จดบันทึกไว้นิดหน่อยสำหรับการเขียน Unit test
สำหรับทดสอบ Android app ที่พัฒนาด้วย Reactive for Java 2.x (RxJava)
ซึ่งมีโครงสร้างง่าย ๆ คือ
- Presenter สำหรับควบคุมการทำงานหลักของระบบ
- Repository สำหรับจัดการการดึงข้อมูลจาก REST APIs
ปล. ถ้าไม่ทดสอบใน Layer นี้ ก็ต้องไปทดสอบ Layer ที่สูงกว่านี้ ไม่ว่าจะเป็น UI testing และ Manual testing ต่อไป แต่จะใช้เวลาในการทดสอบสูง !!
มาดู code ในส่วนของ Presenter ก่อนดีกว่า
[gist id="f86f43eaf629ef7e29df05686fb3ad9a" file="LoginPresenter.kt"] คำอธิบาย การทำงานง่ายมาก ๆ คือ เรียกใช้งานการ authenication ผ่าน Repository จากนั้นก็รอผลลัพธกลับมา ซึ่งมีทั้งสำเร็จและไม่สำเร็จ ดังนั้นเราต้องทดสอบทั้ง 2 กรณีด้วยนะ การทดสอบมีความยุ่งยากนิดหน่อย เนื่องจากมีหลายสิ่งอย่างต้องควบคุม สิ่งที่เลือกใช้คือ- Mockito สำหรับการทำ Stub และ Mock ทั้ง class และ interface ที่ Presenter ต้องใช้งาน
- class RxAndroidPlugin มาจาก Rx Android ใช้สำหรับการกำหนดค่าเริ่มต้นของการทำงาน
เรื่องของเครื่องมือนั้น จำเป็นต้องลงไปอ่านเอกสารของ library ที่นำมาใช้งานด้วย ทั้ง RxJava และ Rx Android มันสำคัญมาก ๆ นะได้เวลาการเขียน Unit test แล้ว
ขั้นตอนที่ 1 ทำการกำหนดค่าต่าง ๆ ที่ต้องใช้งานในการทดสอบ
ทั้งการสร้าง stub และ mock ของ class และ interface ที่ Presenter ใช้งาน โดยสร้าง stub ของ class Repository สำหรับการกำหนดการทำงานตามชุดการทดสอบ และสร้าง mock ของ interface View เพื่อใช้ตรวจสอบพฤติกรรมการทำงาน รวมทั้งการกำหนดค่าต่าง ๆ สำหรับจัดการทดสอบทั้ง Rx Android และ Mockito แสดงดัง code [gist id="f86f43eaf629ef7e29df05686fb3ad9a" file="LoginPresenterTest.kt"]ขั้นตอนที่ 2 เขียนชุดการทดสอบแรกคือ กรณีทำงานสำเร็จ
สิ่งที่คาดหวังคือ function หรือ method ใน interface View จะต้องถูกเรียกใช้งาน 1 ครั้ง เป็นการตรวจสอบพฤติกรรมการทำงานของ Presenter ว่าทำงานตามที่ต้องการหรือไม่ ? โดยสิ่งที่ต้องทำคือ การสร้าง stub ของ Repository ขึ้นมา และกำหนดผลจากการทำงานของ Repository ให้ทำงานได้อย่างถูกต้อง เขียนได้ดังนี้ [gist id="f86f43eaf629ef7e29df05686fb3ad9a" file="test_success.kt"]ขั้นตอนที่ 3 เขียนชุดการทดสอบที่สองคือ กรณีทำงานไม่สำเร็จ
ในกรณีนี้มีเหตุการณ์มากมาย ที่ทำให้การทำงานไม่ถูกต้อง โดยสิ่งที่เลือกคือ กำหนดให้เกิด error เรื่องของ Network กลับมา ผลที่คาดหวังคือ function หรือ method ใน interface View จะต้องไม่ถูกเรียก เขียนได้ดังนี้ [gist id="f86f43eaf629ef7e29df05686fb3ad9a" file="test_error.kt"] เพียงเท่านี้เราก็สามารถเขียนชุดการทดสอบแบบง่าย ๆ ได้แล้ว ซึ่งน่าจะทำให้เรามั่นใจใน code ได้มากขึ้นมาบ้าง เมื่อไปดูค่า code coverage ก็ได้ออกมาดังนี้อย่าลืมว่า เมื่อเลือกอะไรมาใช้แล้ว ใช้เป็นอย่างเดียวไม่พอ จำเป็นต้องทดสอบมันได้ด้วยขอให้สนุกกับการเขียน code ครับ