第12章 ビジネスプロセスのテスト
ビジネスプロセスは動的に更新でき、エラーを発生させる可能性があるため、プロセスビジネスのテストは、他の開発アーティファクトと同様のビジネスプロセスライフサイクルの一部でもあります。
ビジネスプロセスのユニットテストにより、特定のユースケースでプロセスが想定通りに動作するようになります。たとえば、特定の入力に基づいて出力をテストできます。単体テストを簡素化するために、Red Hat Process Automation Manager には org.jbpm.test.JbpmJUnitBaseTestCase
クラスが含まれています。
JbpmJUnitBaseTestCase
は、Red Hat Process Automation Manager 関連のテストに使用するベーステストケースクラスとして実行されます。JbpmJUnitBaseTestCase
は、以下の使用領域を提供します。
JUnit ライフサイクルメソッド
表12.1 JUnit ライフサイクルメソッド メソッド 説明 setUp
このメソッドは
@Before
のアノテーションが付けられます。データソースおよびEntityManagerFactory
を設定し、シングルトンのセッション ID を削除します。tearDown
このメソッドは
@After
としてアノテーションが付けられます。履歴を削除し、EntityManagerFactory
およびデータソースを閉じ、RuntimeManager
およびRuntimeEngines
を破棄します。ナレッジベースおよびナレッジセッション管理メソッド: セッションを作成するには、
RuntimeManager
およびRuntimeEngine
を作成します。以下のメソッドを使用してRuntimeManager
を作成および破棄します。表12.2 RuntimeManager および RuntimeEngine の管理方法 メソッド 説明 createRuntimeManager
特定のアセットセットと選択したストラテジーに対して
RuntimeManager
を作成します。disposeRuntimeManager
テストの範囲でアクティブな
RuntimeManager
を破棄します。getRuntimeEngine
指定されたコンテキスト用に新しい
RuntimeEngine
を作成します。アサーション: アセットの状態をテストするには、以下のメソッドを使用します。
表12.3 管理メソッド RuntimeManager および RuntimeEngine アサーション 説明 assertProcessInstanceActive(long processInstanceId, KieSession ksession)
指定した
processInstanceId
を持つプロセスインスタンスがアクティブかどうかを確認します。assertProcessInstanceCompleted(long processInstanceId)
指定した
processInstanceId
を持つプロセスインスタンスが完了しているかどうかを確認します。セッション永続性が有効な場合にこのメソッドを使用できます。それ以外の場合は、assertProcessInstanceNotActive(long processInstanceId, KieSession ksession)
を使用します。assertProcessInstanceAborted(long processInstanceId)
指定された
processInstanceId
を持つプロセスインスタンスが中断されているかどうかを確認します。セッション永続性が有効な場合にこのメソッドを使用できます。それ以外の場合は、assertProcessInstanceNotActive(long processInstanceId, KieSession ksession)
を使用します。assertNodeExists(ProcessInstance process, String… nodeNames)
指定したプロセスに指定されたノードが含まれているかどうかを検証します。
assertNodeActive(long processInstanceId, KieSession ksession, String… name)
指定した
processInstanceId
を持つプロセスインスタンスに、指定されたノード名を持つアクティブなノードが 1 つ以上含まれるかどうかを確認します。assertNodeTriggered(long processInstanceId, String… nodeNames)
指定したプロセスインスタンスの実行中に、指定した各ノードに対してノードインスタンスがトリガーされているかどうかを確認します。
assertProcessVarExists(ProcessInstance process, String… processVarNames)
指定したプロセスに指定されたプロセス変数が含まれているかどうかを検証します。
assertProcessNameEquals(ProcessInstance process, String name)
指定した名前が指定されたプロセス名と一致するかどうかを確認します。
assertVersionEquals(ProcessInstance process, String version)
指定したプロセスバージョンが指定されたプロセスバージョンと一致するかどうかを確認します。
ヘルパーメソッド: 以下のメソッドを使用して、永続性を使用または使用しない特定のプロセスセットに対して新しい
RuntimeManager
およびRuntimeEngine
を作成します。永続性の詳細は、Red Hat Process Automation Manager のプロセスエンジン を参照してください。表12.4 管理メソッド RuntimeManager および RuntimeEngine メソッド 説明 setupPoolingDataSource
データソースを設定します。
getDs
設定したデータソースを返します。
getEmf
設定済みの
EntityManagerFactory
を返します。getTestWorkItemHandler
デフォルトのワークアイテムハンドラーに加えて登録できるテストワークアイテムハンドラーを返します。
clearHistory
履歴ログを消去します。
以下の例は、開始イベント、スクリプトタスク、および終了イベントが含まれます。JUnit テスト例では、新規セッションを作成し、hello.bpmn
プロセスを開始し、プロセスインスタンスが完了し、StartProcess
ノード、Hello
ノード、および EndProcess
ノードが実行されているかどうかを確認します。
図12.1 hello.bpmn
プロセスの JUnit テストの例

public class ProcessPersistenceTest extends JbpmJUnitBaseTestCase { public ProcessPersistenceTest() { super(true, true); } @Test public void testProcess() { createRuntimeManager("hello.bpmn"); RuntimeEngine runtimeEngine = getRuntimeEngine(); KieSession ksession = runtimeEngine.getKieSession(); ProcessInstance processInstance = ksession.startProcess("com.sample.bpmn.hello"); assertProcessInstanceNotActive(processInstance.getId(), ksession); assertNodeTriggered(processInstance.getId(), "StartProcess", "Hello", "EndProcess"); } }
JbpmJUnitBaseTestCase
は、ユニットテストの一環として事前定義された RuntimeManager
ストラテジーをすべてサポートします。そのため、1 つのテストの一部として RuntimeManager
を作成するときに使用されるストラテジーを指定するだけで十分です。以下の例は、ユーザータスクを管理するタスクサービスでの PerProcessInstance ストラテジーの使用を示しています。
public class ProcessHumanTaskTest extends JbpmJUnitBaseTestCase { private static final Logger logger = LoggerFactory.getLogger(ProcessHumanTaskTest.class); public ProcessHumanTaskTest() { super(true, false); } @Test public void testProcessProcessInstanceStrategy() { RuntimeManager manager = createRuntimeManager(Strategy.PROCESS_INSTANCE, "manager", "humantask.bpmn"); RuntimeEngine runtimeEngine = getRuntimeEngine(ProcessInstanceIdContext.get()); KieSession ksession = runtimeEngine.getKieSession(); TaskService taskService = runtimeEngine.getTaskService(); int ksessionID = ksession.getId(); ProcessInstance processInstance = ksession.startProcess("com.sample.bpmn.hello"); assertProcessInstanceActive(processInstance.getId(), ksession); assertNodeTriggered(processInstance.getId(), "Start", "Task 1"); manager.disposeRuntimeEngine(runtimeEngine); runtimeEngine = getRuntimeEngine(ProcessInstanceIdContext.get(processInstance.getId())); ksession = runtimeEngine.getKieSession(); taskService = runtimeEngine.getTaskService(); assertEquals(ksessionID, ksession.getId()); // let John execute Task 1 List<TaskSummary> list = taskService.getTasksAssignedAsPotentialOwner("john", "en-UK"); TaskSummary task = list.get(0); logger.info("John is executing task {}", task.getName()); taskService.start(task.getId(), "john"); taskService.complete(task.getId(), "john", null); assertNodeTriggered(processInstance.getId(), "Task 2"); // let Mary execute Task 2 list = taskService.getTasksAssignedAsPotentialOwner("mary", "en-UK"); task = list.get(0); logger.info("Mary is executing task {}", task.getName()); taskService.start(task.getId(), "mary"); taskService.complete(task.getId(), "mary", null); assertNodeTriggered(processInstance.getId(), "End"); assertProcessInstanceNotActive(processInstance.getId(), ksession); } }
12.1. 外部サービスとの統合テスト
ビジネスプロセスには、多くの場合は、外部サービスの呼び出しが含まれます。ビジネスプロセスのユニットテストでは、特定のサービスが正しく要求されているかどうかを検証するテストハンドラーを登録し、要求されたサービスのテスト応答を提供できます。
外部サービスとの対話をテストするには、デフォルトの TestWorkItemHandler
ハンドラーを使用します。TestWorkItemHandler
を登録して、特定タイプのワークアイテムをすべて収集できます。また、TestWorkItemHandler
にはタスクに関連するデータも含まれます。ワークアイテムは、特定の電子メールを送信したり特定のサービスを呼び出すなど、作業単位 1 つを表します。TestWorkItemHandler
は、プロセスの実行中に特定のワークアイテムが要求されているかどうかを確認し、関連付けられたデータが正しいことを確認します。
以下の例は、メールタスクを検証する方法と、電子メールが送信されていない場合に例外が発生するかどうかを示しています。ユニットテストは、メールの要求時に実行されるテストハンドラーを使用し、送信者や受信者などの電子メールに関連するデータをテストできます。abortWorkItem()
メソッドがメール配信の失敗についてエンジンに通知すると、ユニットテストではエラーを生成してアクションをログに記録することにより、プロセスがこのようなケースを処理することを検証します。この場合、プロセスインスタンスは最終的に中止されます。
図12.2 メールプロセスの例

public void testProcess2() { createRuntimeManager("sample-process.bpmn"); RuntimeEngine runtimeEngine = getRuntimeEngine(); KieSession ksession = runtimeEngine.getKieSession(); TestWorkItemHandler testHandler = getTestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Email", testHandler); ProcessInstance processInstance = ksession.startProcess("com.sample.bpmn.hello2"); assertProcessInstanceActive(processInstance.getId(), ksession); assertNodeTriggered(processInstance.getId(), "StartProcess", "Email"); WorkItem workItem = testHandler.getWorkItem(); assertNotNull(workItem); assertEquals("Email", workItem.getName()); assertEquals("me@mail.com", workItem.getParameter("From")); assertEquals("you@mail.com", workItem.getParameter("To")); ksession.getWorkItemManager().abortWorkItem(workItem.getId()); assertProcessInstanceNotActive(processInstance.getId(), ksession); assertNodeTriggered(processInstance.getId(), "Gateway", "Failed", "Error"); }