Author:
Fluent Commerce
Changed on:
30 June 2024
This page describes the best practice testing approaches for rules and plugins.
As per standard industry practices, rules should be tested as part of the development cycle, on the developer's local machine.
Rules should be atomic in size and complexity, they are a great candidate for adopting a TDD approach, whereby you write the test first before you even have one line of rule code. You may have heard the phrase "Red, Green, Refactor", and this is a great approach for writing quality rules, that have high test coverage and quality.
There are 2 ways to test locally:
You should always include both types of testing for your rules.
The first type of tests that should be written is Mocked Unit Tests. These tests are ideal for TDD.
`MyCustomRule`
Below is an example Test Suite for a Rule.
1public class MyCustomRuleTest {
2
3 MyCustomRule rule = new MyCustomRule();
4
5 @Mock
6 Context context;
7
8 @Mock
9 Entity entity;
10
11 @Mock
12 ReadOnlyFluentApiClient apiClient;
13
14 @Mock
15 GetOrderByIdQuery.Data data;
16
17 @Mock
18 GetOrderByIdQuery.OrderById orderById;
19
20 @Mock
21 ActionFactory actionFactory;
22
23 @Before
24 public void setup() {
25
26 MockitoAnnotations.initMocks(this);
27
28 when(context.getProp(anyString())).thenReturn("1000");
29 when(context.getProp(RuleConstants.PARAM_NAME_HIGH_VALUE_THRESHOLD, Integer.class)).thenReturn(1000);
30 when(context.getEntity()).thenReturn(entity);
31 when(entity.getId()).thenReturn("123");
32 when(context.api()).thenReturn(apiClient);
33 when(apiClient.query(any())).thenReturn(data);
34 when(data.orderById()).thenReturn(orderById);
35 }
36
37 @Test(expected = MissingRequiredParamException.class)
38 public void MyCustomRule_withMissingThresholdParam_ThrowsMissingRequiredParamException() {
39
40 //arrange:
41 when(context.getProp(RuleConstants.PARAM_NAME_HIGH_VALUE_THRESHOLD)).thenReturn(null);
42
43 //act:
44 rule.run(context);
45
46 //assert:
47
48 }
49
50 @Test(expected = MissingRequiredParamException.class)
51 public void MyCustomRule_withEmptyThresholdParam_ThrowsMissingRequiredParamException() {
52
53 //arrange:
54 when(context.getProp(RuleConstants.PARAM_NAME_HIGH_VALUE_THRESHOLD)).thenReturn("");
55
56 //act:
57 rule.run(context);
58
59 //assert:
60
61 }
62
63 @Test
64 public void MyCustomRule_withValueGreaterThanThreshold_AddsAttributeHIGH_VALUE() {
65
66 //arrange:
67 when(orderById.totalPrice()).thenReturn(1001.00);
68 when(context.action()).thenReturn(actionFactory);
69
70 //act:
71 rule.run(context);
72
73 //assert:
74 verify(actionFactory, times(1)).mutation(any());
75
76 }
77
78 @Test
79 public void MyCustomRule_withValueLessThanThreshold_DoesNothing() {
80
81 //arrange:
82 when(orderById.totalPrice()).thenReturn(999.00);
83
84 //act:
85 rule.run(context);
86
87 //assert:
88 verify(actionFactory, never()).mutation(any());
89
90 }
91
92 @Test
93 public void MyCustomRule_withValueEqualThanThreshold_DoesNothing() {
94
95 //arrange:
96 when(orderById.totalPrice()).thenReturn(1000.00);
97
98 //act:
99 rule.run(context);
100
101 //assert:
102 verify(actionFactory, never()).mutation(any());
103
104 }
105}
Language: java
Name: Example Test Suite for a Rule
Description:
[Warning: empty required content area]The
`TestExecutor`
It provides the following methods:
`rule(Class.class)`
`ruleset(RuleSet ruleSet)`
`entity(Entity entity)`
`validateWorkflow(Event event)`
`execute(Event event)`
`TestContext`
The
`TestContext`
`action()`
`api()`
`count*()`
`get*()`
`scanAndValidateAllRules()`
The
`scanAndValidateAllRules()`
Once you've got good coverage of your Rules in Unit Tests and using the TestExecutor locally, you can deploy your plugin to your Sandbox account.
Once uploaded, you will want to test your rule in a workflow. In many cases, it may be best to test your rule in an isolated ruleset first, where you can trigger it directly with a specific event, and assess the results via the Audit Events. This should include positive and negative test scenarios. For example, if you rule is expected to fail under certain conditions, make sure to test those conditions, and that the resulting audit log reflects the expected information to help users and support staff understand what happened and why.
Once you've tested your rule in isolation, you should include in within the intended Ruleset as part of the orchestration lifecycle logic, and perform end to end tests for various scenarios, each time using the Audit Events to validate the expected outcomes and behaviour.
Copyright © 2024 Fluent Retail Pty Ltd (trading as Fluent Commerce). All rights reserved. No materials on this docs.fluentcommerce.com site may be used in any way and/or for any purpose without prior written authorisation from Fluent Commerce. Current customers and partners shall use these materials strictly in accordance with the terms and conditions of their written agreements with Fluent Commerce or its affiliates.