[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 ที่ต้องการทดสอบก่อนครับ เป็น 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 ขึ้นมาใหม่ โดยใช้ชื่อว่า 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 to your email.