Chapter 14. Testing and debugging
- 14.1. Unit testing
-
- 14.1.1. Helper methods to create your session
- 14.1.2. Assertions
- 14.1.3. Testing integration with external services
- 14.1.4. Configuring persistence
- 14.2. Debugging
-
- 14.2.1. The Process Instances View
- 14.2.2. The Human Task View
- 14.2.3. The Audit View
14.1. Unit testing
- helper methods to create a new knowledge base and session for a given (set of)
process(es)
- you can select whether you want to use persistence or not
- assert statements to check
- the state of a process instance (active, completed, aborted)
- which node instances are currently active
- which nodes have been triggered (to check the path that has been followed)
- get the value of variables
- etc.
public class MyProcessTest extends JbpmJUnitTestCase { public void testProcess() { // create your session and load the given process(es) StatefulKnowledgeSession ksession = createKnowledgeSession("sample.bpmn"); // start the process ProcessInstance processInstance =
ksession.startProcess("com.sample.bpmn.hello"); // check whether the process instance has completed successfully assertProcessInstanceCompleted(processInstance.getId(), ksession); // check whether the given nodes were executed during the process execution assertNodeTriggered(processInstance.getId(),
"StartProcess", "Hello", "EndProcess"); } }
14.1.1. Helper methods to create your session
- createKnowledgeBase(String... process): Returns a new knowledge base containing all the processes in the given filenames (loaded from classpath)
- createKnowledgeBase(Map<String, ResourceType> resources) :Returns a new knowledge base containing all the resources (not limited to processes but possibly also including other resource types like rules, decision tables, etc.) from the given filenames (loaded from classpath)
- createKnowledgeBaseGuvnor(String... packages): Returns a new knowledge base containing all the processes loaded from Guvnor (the process repository) from the given packages
- createKnowledgeSession(KnowledgeBase kbase): Creates a new statefull knowledge session from the given knowledge base
- restoreSession(StatefulKnowledgeSession ksession, boolean noCache) : completely restores this session from database, can be used to recreate a session to simulate a critical failure and to test recovery, if noCache is true, the existing persistence cache will not be used to restore the data
14.1.2. Assertions
- assertProcessInstanceActive(long processInstanceId, StatefulKnowledgeSession ksession): check whether the process instance with the given id is still active
- assertProcessInstanceCompleted(long processInstanceId, StatefulKnowledgeSession ksession): check whether the process instance with the given id has completed successfully
- assertProcessInstanceAborted(long processInstanceId, StatefulKnowledgeSession ksession): check whether the process instance with the given id was aborted
- assertNodeActive(long processInstanceId, StatefulKnowledgeSession ksession, String... name): check whether the process instance with the given id contains at least one active node with the given node name (for each of the given names)
- assertNodeTriggered(long processInstanceId, String... nodeNames) : check for each given node name whether a node instance was triggered (but not necessarily active anymore) during the execution of the process instance with the given
- getVariableValue(String name, long processInstanceId, StatefulKnowledgeSession ksession): retrieves the value of the variable with the given name from the given process instance, can then be used to check the value of process variables
14.1.3. Testing integration with external services
A TestWorkItemHandler is provided by default that can be registered to collect all work items (a work item represents one unit of work, like for example sending one specific email or invoking one specific service and contains all the data related to that task) for a given type. This test handler can then be queried during unit testing to check whether specific work was actually requested during the execution of the process and that the data associcated with the work was correct.
The following example describes how a process that sends out an email could be tested. This test case in particular will test whether an exception is raised when the email could not be sent (which is simulated by notifying the engine that the sending the email could not be completed). The test case uses a test handler that simply registers when an email was requested (and allows you to test the data related to the email like from, to, etc.). Once the engine has been notified the email could not be sent (using abortWorkItem(..)), the unit test verifies that the process handles this case successfully by logging this and generating an error, which aborts the process instance in this case.
public void testProcess2() { // create your session and load the given process(es) StatefulKnowledgeSession ksession = createKnowledgeSession("sample2.bpmn"); // register a test handler for "Email" TestWorkItemHandler testHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Email", testHandler); // start the process ProcessInstance processInstance =
ksession.startProcess("com.sample.bpmn.hello2"); assertProcessInstanceActive(processInstance.getId(), ksession); assertNodeTriggered(processInstance.getId(), "StartProcess", "Email"); // check whether the email has been requested WorkItem workItem = testHandler.getWorkItem(); assertNotNull(workItem); assertEquals("Email", workItem.getName()); assertEquals("me@mail.com", workItem.getParameter("From")); assertEquals("you@mail.com", workItem.getParameter("To")); // notify the engine the email has been sent ksession.getWorkItemManager().abortWorkItem(workItem.getId()); assertProcessInstanceAborted(processInstance.getId(), ksession); assertNodeTriggered(processInstance.getId(), "Gateway", "Failed", "Error"); }
14.1.4. Configuring persistence
By default, persistence is turned on. To turn off persistence, simply pass a boolean to the super constructor when creating your test case, as shown below:
public class MyProcessTest extends JbpmJUnitTestCase { public MyProcessTest() { // configure this tests to not use persistence in this case super(false); } ...
14.2. Debugging
When debugging the application, you can use the following debug views to track the execution of the process:
- The process instances view, showing all running process instances (and their state). When double-clicking a process instance, the process instance view visually shows the current state of that process instance at that point in time.
- The human task view, showing the task list of the given user (fill in the user id of the actor and click refresh to view all the tasks for the given actor), where you can then control the life cycle of the task, for example start and complete it.
- The audit view, showing the audit log (note that you should probably use a threaded file logger if you want to session to save the audit event to the file system on regular intervals, so the audit view can be update to show the latest state).
- The global data view, showing the globals.
- Other views related to rule execution like the working memory view (showing the contents (data) in the working memory related to rule execution), the agenda view (showing all activated rules), etc.
14.2.1. The Process Instances View
When you double-click a process instance in the process instances view and the process instance view complains that it cannot find the process, this means that the plugin wasn't able to find the process definition of the selected process instance in the cache of parsed process definitions. To solve this, simply change the process definition in question and save again (so it will be parsed) or rebuild the project that contains the process definition in question.
14.2.2. The Human Task View
14.2.3. The Audit View
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory .newThreadedFileLogger(ksession, "logdir/mylogfile", 1000); // do something with the session here logger.close();To open up an audit tree in the audit view, open the selected log file in the audit view or simply drag the file into the audit view. A tree-based view is generated based on the audit log. An event is shown as a subnode of another event if the child event is caused by (a direct consequence of) the parent event. An example is shown below.
No comments:
Post a Comment