Unit Test กับ Instrumented Test บน Android Studio ต่างกันอย่างไร
สำหรับนักพัฒนาที่เริ่มต้นเขียนเทสให้กับโปรเจคแอนดรอยด์อาจจะมีคำถามกันว่า Unit Test และ Instrumented Test ที่มีให้เขียนเทสใน Android Studio นั้นต่างกันอย่างไร
โดยที่ Unit test คือ Directory ที่ชื่อว่า test
ส่วน Instrumented Test จะเป็น Directory ที่ชื่อว่า androidTest
ซึ่งทั้งคู่ต่างก็เป็น Directory ที่อยู่ใน src
ของโปรเจคแอนดรอยด์
ซึ่งในความเป็นจริง test
มีไว้สำหรับเขียน Unit Test ส่วน androidTest
สามารถเขียนได้ทั้ง Unit Test, Integration Test และ UI Test ดังนั้นถ้านักพัฒนาต้องการเขียน Unit Test ก็สามารถเขียนได้ทั้งใน test
และ androidTest
ดังนั้นเพื่อไม่ให้สับสนเราจึงเรียกกันแบบนี้แทน
- การเขียน Unit Test ใน
test
เรียกว่า Local Unit Test - การเขียน Unit Test ใน
androidTest
เรียกว่า Instrumented Unit Test
แล้วทั้งคู่ต่างกันอย่างไร?
ความแตกต่างระหว่างทั้งสองนี้ก็คือ Test Execution Environment หรือ Environment ที่ใช้ในตอนรันเทสไม่เหมือนกัน โดยที่
- Local Unit Test คือการรันเทสบน JVM และทำงานด้วยเครื่องคอมที่ใช้รันเทส (Local Machine) ได้เลย
- Instrumented Unit Test คือการรันเทสบน Android Runtime และต้องเชื่อมต่อกับอุปกรณ์แอนดรอยด์ (Physical Device หรือ Android Emulator) เพื่อใช้ในการรันเทส
ทั้งนี้ก็เพราะว่า Framework API ของแอนดรอยด์จะมีบางคำสั่งที่จำเป็นต้องทำงานบน Android Runtime เช่น คำสั่งที่มีการเรียกใช้งาน Context จึงทำให้คำสั่งเหล่านี้ทำงานอยู่บน JVM ไม่ได้ และเป็นที่มาของ Instrumented Test นั่นเอง
และเมื่อทั้งคู่ใช้ Test Execution Environment ที่ต่างกัน ทำให้ระยะเวลาที่ใช้ในการรันเทสแตกต่างกันด้วย โดยที่ Local Unit Test จะใช้เวลาน้อยกว่า Instrumented Unit Test
ดังนั้นในการเขียน Unit Test จึงนิยมเขียนเป็น Local Unit Test แทน เพื่อลดระยะเวลาในการรันเทส เนื่องจากการทำงานจริงจะต้องมีการเขียน Unit Test เป็นจำนวนมาก
Robolectric ตัวช่วยสำคัญเพื่อให้รันเทสบน JVM ได้
เพื่อให้ Unit Test ไปทำงานอยู่บน JVM ได้ทั้งหมด จึงมีตัวช่วยอย่าง Robolectric ที่เป็น Library ที่ทำให้ JVM สามารถทำลองการทำงานของ Android Runtime เพื่อช่วยให้ Unit Test หลาย ๆ ตัวย้ายมาทำงานบน JVM แทนได้
ซึ่งข้อดีของ Robolectric ก็คือทำให้โค้ดต่าง ๆ สำหรับ Unit Test ที่เดิมทีต้องทำงานบน Android Runtime ก็เปลี่ยนมาทำงานบน JVM ได้ เพื่อให้ใช้เวลาในการรันเทสน้อยลงกว่าเดิม และไม่ต้องเชื่อมต่อกับอุปกรณ์แอนดรอยด์ให้ยุ่งยาก
แต่การเขียนเทสบางอย่างก็ยังคงต้องใช้ Android Runtime อยู่ดี
เนื่องจาก Robolectric เป็นแค่ตัวช่วยจำลองการทำงานของ Android Runtime บางส่วนให้อยู่บน JVM นั่นหมายความว่าในการเขียนเทสจริง ๆ ก็จะมีเทสบางส่วนที่จำเป็นต้องอยู่บน Android Runtime จริง ๆ เช่น UI Test หรือ Integration Test ที่เกี่ยวกับ UI เป็นต้น
สรุป
ความแตกต่างระหว่าง Unit Test และ Instrumented Test จะเป็นเรื่อง Test Execution Environment ที่เป็น JVM และ Android Runtime ซึ่งจะส่งผลต่อเงื่อนไขการทำงานและระยะเวลาที่ใช้ในการรันเทสนั่นเอง