robo-00
พอดีมีคำถามมาจากน้อง ๆ ที่เขียน Android app ว่า
ถ้าต้องการทดสอบพวก Custom View โดยไม่ต้องเปิดหรือทดสอบผ่าน Activity ได้ไหม ?

ตอบไปแบบไม่คิดว่า ทดสอบยังไงหว่า ไม่ผ่าน Activity !!
แต่เมื่อคิดให้ดี ๆ ก็นึกออกว่า สามารถทดสอบด้วยการใช้ Robolectric

เมื่อไปค้นหาเจอบทความเก่าหน่อยแต่อธิบายได้ดี
เรื่อง Android: Unit testing custom views

เลยเอามาลองใช้งานดูนิดหน่อย

ในการทดสอบใด ๆ ก็ตามผ่าน Activity จะพบปัญหามากมาย

ทั้งการทดสอบที่ช้า
ทั้งการ setup ข้อมูลต่าง ๆ มากมายก่อนการเปิด Activity

ดังนั้นสิ่งที่ควรทำคือ ลดความซ้ำซ้อนของแต่ละ Activity ลงไปก่อน
หมายถึงต้องนำ logic ต่าง ๆ ออกไปจาก Activity
หนึ่งในนั้นคือ การใช้งาน Custom View นั่นเอง
และแน่นอนว่า การทดสอบก็ต้องทดสอบทำได้เช่นเดียวกัน
ซึ่งน่าจะทำให้การทดสอบง่ายและรวดเร็วขึ้น
ที่สำคัญไม่ต้องทดสอบผ่าน Activity หลักอีกด้วย

ลองมาดูตัวอย่างของ Custom View กันหน่อย

ทำหน้าที่ง่าย ๆ คือ แสดง progress bar
เพื่อแสดง progress ของการทำงานของระบบ
เมื่อทำงานเสร็จจะหยุดการแสดง progress bar
ผ่าน method ที่ชื่อว่า stopLoadingAndSetText()
และจะแสดงข้อความตามที่ต้องการออกมาด้วย

Code ของ Custom view ซึ่ง extend มาจาก RelativeLayout

ส่วนของไฟล์ layout เป็นดังนี้

จากนั้นเราลองมาดูสิว่า จะทดสอบการทำงานอย่างไร ?
สิ่งที่เราต้องการคือ ไม่เปิด Activity จริง ๆ ขึ้นมา
ดังนั้นเราไม่ต้องการ UI Testing นั่นเอง
เพราะว่า มันช้าน่าดู !!

แต่เราต้องการทดสอบเฉพาะ custom view หรือจากตัวอย่างคือ LoadingView
สามารถทำการทดสอบด้วย Robolectric ได้
เนื่องจากมันไม่ต้องการ emulator หรือ device จริง ๆ เลย
รวมถึงไม่ต้องใช้ mocking framework ใด ๆ อีกด้วย
ซึ่งคิดว่าน่าจะตรงกับความต้องการ
ดังนั้นมาดูขั้นตอนการใช้งานกันดีกว่า

เริ่มจากการเพิ่ม library เข้าไปในไฟล์ build.gradle ดังนี้

ต่อมาเริ่มเขียน test แรกกันเลย
เป็นการตรวจสอบการทำงานของ Loading View
เริ่มด้วยการแสดงเฉพาะ Progress bar ส่วนข้อความไม่แสดง
แต่หลังจากเรียกใช้ method stopLoadingAndSetText() แล้ว
Progress bar จะหายไป และ แสดงข้อความแทน

แต่ก่อนอื่นต้อง setup  เพื่อใช้งาน Robolectric ก่อน

ซึ่งเป็นจุดที่น่าจะยากสุด ๆ สำหรับการใช้งานแล้ว
จุดที่น่าสนใจคือ การ setUp() นั่นเอง ซึ่งทำงานดังนี้

  • ทำการสร้าง Activity Controller ขึ้นมา เพื่อใช้สำหรับการสร้าง custom view
  • สร้าง custom view ผ่าน LayoutInflate จากไฟล์ layout ที่สร้างไว้จากข้างต้น
  • ทำการสร้าง view object ที่ต้องการ

แสดงดัง code

จากนั้นจึงเริ่มเขียน test แรกดังนี้

ลองทำการ run ชุดการทดสอบว่า ทำงานตามที่คาดหวังหรือไม่ !!

แต่การทดสอบนั้นยังไม่จบ เนื่องจากเรายังขาด ?
test เพื่อตรวจสอบว่า ข้อความที่แสดงตรงตามที่ต้องการหรือไม่
ดังนั้นเขียน test ได้ดังนี้

ให้ทำการ run test ทั้งหมดอีกรอบ จะแสดงผลการทำงานดังนี้

robo-01

หรือทำการ run ผ่าน grade wrapper ด้วยคำสั่ง

$./gradlew  clean testDebugUnitTest

จะแสดงผลการทำงานดังรูป
ซึ่งใช้เวลาในการทดสอบนานใช้ได้เลยนะ

robo-02

ดู code ตัวอย่างเต็ม ๆ ได้ที่ Github::Up1:Demo with Robolectric