หลังจากยุ่งกับงานประจำนานเลย ตอนนี้เริ่มกลับมาทำงาน Thesis แล้วครับ ถ้าใครสร้าง BPMN ด้วย Camunda ไปแล้วนั่น หาจะทดสอบมีได้หลายวิธีครับ เช่น
- Deploy Process เข้าไปที่ตัว BPMN Engine แล้วกด Test เลย
- Deploy Process แล้วใช้ REST API ของ BPMN Engine เพื่อส่งค่าเข้าไป
แต่ถ้ามาดูที่ตัว Camunda มีตัวช่วยสำหรับ Test เหมือนกันครับ โดยมีตัวช่วย ดังนี้
สร้าง 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.