[BPMN] มา Test BPMN ที่สร้างจาก Camunda กันครับ

หลังจากยุ่งกับงานประจำนานเลย ตอนนี้เริ่มกลับมาทำงาน Thesis แล้วครับ ถ้าใครสร้าง BPMN ด้วย Camunda ไปแล้วนั่น หาจะทดสอบมีได้หลายวิธีครับ เช่น

  • Deploy Process เข้าไปที่ตัว BPMN Engine แล้วกด Test เลย
  • Deploy Process แล้วใช้ REST API ของ BPMN Engine เพื่อส่งค่าเข้าไป

แต่ถ้ามาดูที่ตัว Camunda มีตัวช่วยสำหรับ Test เหมือนกันครับ โดยมีตัวช่วย ดังนี้

สำหรับใน Blog ตอนนี้ผมใช้ Camundate BPM Assert ที่มันถูก Include เข้ามาใน Project Template ครับ มาลุยกันเลย

สร้าง BPMN ก่อนครับ

  • มาดูที่ BPMN ที่ต้องการทดสอบก่อนครับ เป็น Flow การกู้เงินอย่างง่าย simpleLoan.bpmn
  • ผมตั้ง Id และ Name ว่า "simpleLoan" ครับ
  • ส่วน Task นั้นผมได้กำหนด id และ Name ให้ชื่อเหมือนกันครับ แต่ Id มีข้อจำกัด เรื่องของ space ผมเลยใช้ underscore (_) แทนครับ โดยที่ต้องการตั้งชื่อให้มันสื่อ เพราะจะได้เอาไปใช้ใน Unit Test ครับ
  • จาก BPMN ที่ได้มา ผมสามารถกำหนด Test Path ได้ 3 เส้นทางครับ ดังนี้

มาลุย Code กันดีกว่าครับ

สำหรับ Tools ที่ผมใช้ IntelliJ กับ Camunda Test Project Template ครับ

เมื่อ Generate Project มาแล้วจะพบตัว InmemoryH2Test กับ process.bpmn ไม่ต้องสนใจครับ เราสร้างใหม่อยู่แล้ว

  • นำไฟล์ simpleLoan.bpmn ไปวางไว้ในโพลเดอร์ Resource ของ Project ครับ
  • จากนั้น สร้าง UnitTest Class ขึ้นมาใหม่ โดยใช้ชื่อว่า simpleLoanTest ครับ

เมื่อได้ Unit Test เปล่าๆขึ้นมาแล้วให้ใส่คำสั่งลงไปใน Class simpleLoanTest  ครับ

  • สร้าง Instance ของ ProcessEngine
@ClassRule
@Rule
public static ProcessEngineRule rule = TestCoverageProcessEngineRuleBuilder.create().build();
  • กำหนดชื่อ Process ที่จะ Test ครับ
private static final String PROCESS_DEFINITION_KEY = "simpleLoan";

สร้าง Test initial @Before เพื่อบอกว่าก่อน Test ต้องมีการดึง BPMN Engine ออกมา เพื่อใช้งานก่อนครับ

@Before
public void setup() {
   init(rule.getProcessEngine());
}

จากนั้นลุยสร้าง Test ตามเส้นทางที่กำหนดเลยครับ โดย @Test  เพื่อบอกว่าเป็น Test Case ครับ และ @Deployment  สำหรับบอกว่าเราจะทดสอบ BPM์N อันไหนครับ ในที่นี้เป็นไฟล์ simpleLoan.bpmn  ครับ

  • เส้นทางที่ 1 - รายละเอียดไล้ตามใน Comment เลยครับ
@Test
@Deployment(resources = "simpleLoan.bpmn")
public void testWhenLoanAmountNotNeedToMakeCollateral() {
    //Start Process
    ProcessInstance processInstance = processEngine().getRuntimeService().startProcessInstanceByKey(PROCESS_DEFINITION_KEY);

    //ตรวจสอบว่า Task ตอนนี้อยู่ที่ไหนแล้ว ใช่ Enter_Loan_Amount ?
    assertThat(processInstance).task("Enter_Loan_Amount");

    //ใส่ค่าให้ Task Enter_Loan_Amount
    complete(task(processInstance), withVariables("name", "PingkungA"
                                    , "loanAmt", 40000));

    //ตรวจสอบว่า Task ตอนนี้อยู่ที่ไหนแล้ว ใช่ Loan_Request_Complete ?
    assertThat(processInstance).task("Loan_Request_Complete");
    //ไปต่อ
    complete(task());

    //ตรวจสอบลำดับของ Task โดยเริ่มจาก Enter_Loan_Amount >> Loan_Request_Complete
    assertThat(processInstance).hasPassedInOrder("Enter_Loan_Amount", "Loan_Request_Complete");
    assertThat(processInstance).isEnded();
}
  • เส้นทางที่ 2 - รายละเอียดไล้ตามใน Comment เลยครับ
@Test
@Deployment(resources = "simpleLoan.bpmn")
public void testWhenLoanAmountNeedToMakeCollateralAndLoanRequestComplete() {
    //Start Process
    ProcessInstance processInstance = processEngine().getRuntimeService().startProcessInstanceByKey(PROCESS_DEFINITION_KEY);

    //ตรวจสอบว่า Task ตอนนี้อยู่ที่ไหนแล้ว ใช่ Enter_Loan_Amount ?
    assertThat(processInstance).task("Enter_Loan_Amount");

    //ใส่ค่าให้ Task Enter_Loan_Amount
    complete(task(processInstance), withVariables("name", "PingkungA"
                                    , "loanAmt", 100000));

    //ตรวจสอบว่า Task ตอนนี้อยู่ที่ไหนแล้ว ใช่ Update_Collateral ?
    assertThat(processInstance).task("Update_Collateral");
    //ใส่ค่าให้ Task Update_Collateral
    complete(task(processInstance), withVariables("collateralAmt", 71000
                                    , "collaternalInfo", "นาฟิกา"));

    //ตรวจสอบว่า Task ตอนนี้อยู่ที่ไหนแล้ว ใช่ Loan_Request_Complete
    assertThat(processInstance).task("Loan_Request_Complete");
    //ไปต่อ
    complete(task());

    //ตรวจสอบลำดับของ Task โดยเริ่มจาก Enter_Loan_Amount >> Update_Collateral >> Loan_Request_Complete
    assertThat(processInstance).hasPassedInOrder("Enter_Loan_Amount", "Update_Collateral", "Loan_Request_Complete");
    assertThat(processInstance).isEnded();
}
  • เส้นทางที่ 3 - รายละเอียดไล้ตามใน Comment เลยครับ
@Test
@Deployment(resources = "simpleLoan.bpmn")
public void testWhenLoanAmountNeedToMakeCollateralAndLoanRequestReject() {
    //Start Process
    ProcessInstance processInstance = processEngine().getRuntimeService().startProcessInstanceByKey(PROCESS_DEFINITION_KEY);

    //ตรวจสอบว่า Task ตอนนี้อยู่ที่ไหนแล้ว ใช่ Enter_Loan_Amount ?
    assertThat(processInstance).task("Enter_Loan_Amount");
    //ใส่ค่าให้ Task Enter_Loan_Amount
    complete(task(processInstance), withVariables("name", "PingkungA"
            , "loanAmt", 100000));

    //ตรวจสอบว่า Task ตอนนี้อยู่ที่ไหนแล้ว ใช่ Update_Collateral ?
    assertThat(processInstance).task("Update_Collateral");
    //ใส่ค่าให้ Task Update_Collateral
    complete(task(processInstance), withVariables("collateralAmt", 2500
            , "collaternalInfo", "นาฟิกา"));

    //ตรวจสอบว่า Task ตอนนี้อยู่ที่ไหนแล้ว ใช่ Reject_Loan_Request
    assertThat(processInstance).task("Reject_Loan_Request");
    //ไปต่อ
    complete(task());

    //ตรวจสอบลำดับของ Task โดยเริ่มจาก Enter_Loan_Amount >> Update_Collateral >> Reject_Loan_Request
    assertThat(processInstance).hasPassedInOrder("Enter_Loan_Amount", "Update_Collateral", "Reject_Loan_Request");
    assertThat(processInstance).isEnded();
}

ทดสอบ Run Unit Test ดูครับ

หมายเหตุ : ผมยังเล่นกับแต่ User Task นะครับ แต่ส่วนอื่นๆ ยังไม่ได้ทดสอบนะครับ

ERROR ที่พบ

ถ้าพบ Error ENGINE-16004 Exception while closing command context: Can't find scripting engine for 'groovy': scriptEngine is null  ให้ใส่ dependency ลงไปในไฟล์ pom.xml ดังนี้

หมายเหตุ ให้เลือกเวอร์ชันของ Lib ให้เหมาะสมกับตัว Engine ด้วย

<!-- https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-all -->
<dependency>
  <groupId>org.codehaus.groovy</groupId>
  <artifactId>groovy-all</artifactId>
  <version>2.5.2</version>
  <type>pom</type>
</dependency>

Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts sent to your email.