Android Espresso on CircleCI
ต่อจากที่ได้ลอง setup CircleCI สำหรับ Android project ในครั้งก่อน นอกจากจะให้ CI ช่วยรัน unit tests แล้วคราวนี้ลองทำให้รองรับ Espresso Testing ด้วยจะได้ให้ CI รันให้ทั้ง Unit tests และ UI tests เลย ขั้นตอนก็ไม่ได้ยุ่งยากอะไรมาก เอกสารของ CircleCI ก็บอกไว้ละเอียดครอบคลุมถึงการเปิด emulator ขึ้นมารัน Espresso tests
จากที่ทำตามเอกสารของ CircleCI ทุกอย่างก็เป็นไปได้ด้วยดี แต่ติดตรงที่ว่าเวลาที่ใช้ build มันเยอะขึ้น เพราะต้องรอ Android Emulator เปิดขึ้นมาก่อนถึงจะรัน Espresso tests ได้
ตัวอย่างจากเอกสารของ CircleCI
test:
override:
# start the emulator
- emulator -avd circleci-android22 -no-audio -no-window:
background: true
parallel: true
# wait for it to have booted
- circle-android wait-for-boot
# run tests against the emulator.
- ./gradlew connectedAndroidTest
# copy the build outputs to artifacts
- cp -r my-project/build/outputs $CIRCLE_ARTIFACTS
# copy the test results to the test results directory.
- cp -r my-project/build/outputs/androidTest-results/* $CIRCLE_TEST_REPORTS
จากตัวอย่างจะเห็นว่าแม้เราจะเปิด emulator ขึ้นมาให้เป็น background แล้วรันแบบ parallel แล้ว แต่สุดท้ายก็ต้องมารอให้ emulator เปิดขึ้นมาให้เรียบร้อยก่อนถึงจะใช้งานได้ (คำสั่ง circle-android wait-for-boot
)
ก็เลยไปลองหาในอากู๋ดูว่ามีใครเคยปรับอะไรพวกนี้ไหม แล้วก็มาเจอ gistอันนี้ ซึ่งเขาเอาคำสั่งในการเปิด emulator ไปใส่ไว้ในส่วนของ pre:
แทนที่จะไว้ตรง override:
ผมเลยเอาแนวคิดนี้มาปรับกับโปรเจคที่ทำอยู่โดยไปเปิด emulator ที่ pre:
ระหว่างนั้นก็ไปรัน unit tests ปกติก่อนเพื่อไม่ให้เป็นการเสียเวลา พอรัน unit tests เสร็จแล้วค่อยต่อ emulator เพื่อรัน Espresso tests
วิธีนี้ทำให้ประหยัดเวลาขึ้นมาอีกหน่อย
นอกจากปัญหาเรื่องเวลาในการบิ้วท์แล้ว ยังมีปัญหาว่าพอ emulator เปิดขึ้นมาแล้วเราไม่สามารถรัน Espresso Tests ได้ทันทีเนื่องจากหน้า Activity ไม่ได้ถูก Focus
java.lang.RuntimeException: Waited for the root of the view hierarchy to have window focus and not be requesting layout for over 10 seconds. If you specified a non default root matcher, it may be picking a root that never takes focus. Otherwise, something is seriously wrong.
สำหรับเรื่องนี้แก้ได้โดยการส่งคำสั่งไปทำให้หน้าจอ emulator แอคทีฟขึ้นมา
- sleep 5
- adb shell input keyevent 82
ต้องมี sleep นิดหน่อยไม่งั้นก็จะเจอปัญหาไม่ focus เหมือนเดิม (= =) ส่วนเลข 82 นั้นก็คือ menu key
ผมอัพเดท circle.yml ที่เคยทำไว้ในบล็อกก่อนให้เพิ่มส่วนของ Espresso Test เข้ามา ลองดูได้ที่ gist นี้ครับ