พอดีมีคำถามมาจากน้อง ๆ ที่เขียน 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 [gist id="20725a7e236465b4509f21f025a4054a" file="LoadingView.java"] ส่วนของไฟล์ layout เป็นดังนี้ [gist id="20725a7e236465b4509f21f025a4054a" file="loading_view.xml"] จากนั้นเราลองมาดูสิว่า จะทดสอบการทำงานอย่างไร ? สิ่งที่เราต้องการคือ ไม่เปิด Activity จริง ๆ ขึ้นมา ดังนั้นเราไม่ต้องการ UI Testing นั่นเอง เพราะว่า มันช้าน่าดู !! แต่เราต้องการทดสอบเฉพาะ custom view หรือจากตัวอย่างคือ LoadingView สามารถทำการทดสอบด้วย Robolectric ได้ เนื่องจากมันไม่ต้องการ emulator หรือ device จริง ๆ เลย รวมถึงไม่ต้องใช้ mocking framework ใด ๆ อีกด้วย ซึ่งคิดว่าน่าจะตรงกับความต้องการ ดังนั้นมาดูขั้นตอนการใช้งานกันดีกว่า เริ่มจากการเพิ่ม library เข้าไปในไฟล์ build.gradle ดังนี้ [gist id="20725a7e236465b4509f21f025a4054a" file="build.gradle"] ต่อมาเริ่มเขียน test แรกกันเลย เป็นการตรวจสอบการทำงานของ Loading View เริ่มด้วยการแสดงเฉพาะ Progress bar ส่วนข้อความไม่แสดง แต่หลังจากเรียกใช้ method stopLoadingAndSetText() แล้ว Progress bar จะหายไป และ แสดงข้อความแทนแต่ก่อนอื่นต้อง setup เพื่อใช้งาน Robolectric ก่อน
ซึ่งเป็นจุดที่น่าจะยากสุด ๆ สำหรับการใช้งานแล้ว จุดที่น่าสนใจคือ การ setUp() นั่นเอง ซึ่งทำงานดังนี้- ทำการสร้าง Activity Controller ขึ้นมา เพื่อใช้สำหรับการสร้าง custom view
- สร้าง custom view ผ่าน LayoutInflate จากไฟล์ layout ที่สร้างไว้จากข้างต้น
- ทำการสร้าง view object ที่ต้องการ