搜索

第 12 章 测试业务流程

download PDF

业务流程可以动态更新,这可能会导致错误,因此测试过程业务也是与任何其他开发工件类似的业务流程生命周期的一部分。

业务流程的单元测试可确保具体用例中过程的行为如预期。例如,您可以基于特定输入测试输出。为了简化单元测试,Red Hat Process Automation Manager 包括 org.jbpm.test.JbpmJUnitBaseTestCase 类。

JbpmJUnitBaseTestCase 作为基础测试案例执行,它用于红帽流程自动化管理器相关测试。JbpmJUnitBaseTestCase 提供以下使用区域:

  • JUnit 生命周期方法

    表 12.1. JUnit 生命周期方法
    方法描述

    setUp

    此方法标注为 @Before。它配置数据源和 EntityManageronnectionFactoryy,并删除单例的会话 ID。

    tearDown

    此方法标注为 @After。它移除了历史、关闭 实体管理器 和数据源,并处理 RuntimeManagerRuntimeEngines

  • 知识库和知识会话管理方法:要创建一个会话,创建 RuntimeManagerRuntimeEngine。使用以下方法创建和关闭 RuntimeManager

    表 12.2. RuntimeManager 和 RuntimeEngine 管理方法
    方法描述

    createRuntimeManager

    为给定的资产和选定策略创建 RuntimeManager

    disposeRuntimeManager

    在测试范围内激活的 RuntimeManager

    getRuntimeEngine

    为给定的上下文创建新的 RuntimeEngine

  • 断言:要测试资产的状态,请使用以下方法之一:

    表 12.3. RuntimeManager 和 RuntimeEngine 管理方法
    断言描述

    assertProcessInstanceActive(long processInstanceId, KieSession ksession)

    验证具有给定 processInstanceId 的进程实例是否活跃。

    assertProcessInstanceCompleted(长 processInstanceId)

    验证具有给定 processInstanceId 的进程实例是否已完成。如果启用了会话持久性,您可以使用此方法,否则使用 assertProcessInstanceNotActive(long processInstanceId, KieSession ksession)

    assertProcessInstanceAborted(长 processInstanceId)

    验证具有给定 processInstanceId 的进程实例是否已中止。如果启用了会话持久性,您可以使用此方法,否则使用 assertProcessInstanceNotActive(long processInstanceId, KieSession ksession)

    assertNodeExists(ProcessInstance process, String…​ nodeNames)

    验证指定进程是否包含给定的节点。

    assertNodeActive(long processInstanceId, KieSession ksession, String…​ name)

    验证具有给定 processInstanceId 的进程实例是否至少包含一个具有指定节点名称的活跃节点。

    assertNodeTriggered(long processInstanceId, String…​ nodeNames)

    验证在执行指定进程实例的过程中是否为每个给定节点触发节点实例。

    assertProcessVarExists(ProcessInstance process, String…​ processVarNames)

    验证给定进程是否包含指定的进程变量。

    assertProcessNameEquals(ProcessInstance process, String name)

    验证给定名称是否与指定进程名称匹配。

    assertVersionEquals(ProcessInstance process, String version)

    验证给定进程版本是否与指定进程版本匹配。

  • 帮助程序方法:使用以下方法为具有或不使用持久性的给定进程集合创建新的 RuntimeManagerRuntimeEngine。有关持久性的更多信息,请参阅 Red Hat Process Automation Manager 中的进程引擎

    表 12.4. RuntimeManager 和 RuntimeEngine 管理方法
    方法描述

    setupPoolingDataSource

    配置数据源。

    getDs

    返回配置的数据源。

    getEmf

    返回配置的 实体管理器onnectionFactoryy

    getTestWorkItemHandler

    返回除了默认的工作项处理程序之外可以注册的测试工作项处理程序。

    clearHistory

    清除历史记录日志。

以下示例包含一个起始事件、脚本任务和结束事件。JUnit 测试示例会创建一个新的会话,并启动 hello.bpmn 进程,并验证进程实例是否已完成,以及 StartProcessHelloEndProcess 节点是否已执行。

图 12.1. hello.bpmn 进程的 JUnit 测试示例

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 策略,作为单元测试的一部分。因此,在创建一个 RuntimeManager 作为单个测试的一部分,它足以指定创建 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. 测试与外部服务集成

业务流程通常包括调用外部服务。业务流程的单元测试允许您注册测试处理程序,以验证是否正确请求特定服务,并为请求的服务提供测试响应。

要测试与外部服务的交互,请使用 default TestWorkItemHandler 处理程序。您可以注册 TestWorkItemHandler,以收集特定类型的所有工作项目。另外 ,testWorkItemHandler 包含与任务相关的数据。工作项目代表一个工作单元,如发送特定电子邮件或调用特定服务。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");

}
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.