ปัญหาที่เจอบ่อยมาก ๆ สำหรับการทดสอบแบบ End-to-End
ยิ่งทดสอบผ่าน User Interface หรือ ระบบที่ต้องทำงานผ่านระบบ network
คือ ทดสอบผ่านบ้าง ไม่ผ่านบ้าง โดยที่ code ไม่เปลี่ยนแปลงใด ๆ เลย !!
ปัญหานี้จะถูกเรียกว่า Flakiness testing
ปัญหานี้จะรบกวนจิตใจของทีมทดสอบและพัฒนาอย่างมาก
บ่อยครั้งการแก้ไขปัญหาจะเป็นการแก้ที่ปลายเหตุทั้งนั้น
โดยไม่แก้ไขที่ต้นเหตุเลย
ยกตัวอย่างเช่น
ให้การทดสอบรอนาน ๆ ด้วย keyword พวก Waiting, Timeout หรือ Delay
ผลที่ตามมาคือ การทดสอบช้ามาก ๆ
ส่งผลให้กระบวนการทำงานช้าเพิ่มเข้าไปอีก
ถึงแม้ว่าจะมีชุดการทดสอบอัตโนมัติ และมีระบบ Continuous Integration ก็ตาม
ยิ่งปัญหานี้เกิดขึ้นบ่อย ๆ
สิ่งที่อาจจะทำต่อไปคือ Ignore test เหล่านั้น
หรือหนักสุดคือ ลบชุดการทดสอบทิ้งไปเลย !!
ทำให้ความน่าเชื่อและความไว้เนื้อเชื่อใจลดลงไปอย่างมาก
แสดงดังรูป
ค่าใช้จ่ายของ Flakiness test เยอะมาก ๆ
เนื่องจากประกอบไปด้วย
- Creation cost
- Execution cost
- Fixing cost
- Business cost
- Psychological cost
ต้นเหตุของ Flakiness test มาจากอะไรบ้าง
- ระบบที่ทดสอบไม่ stable บ่อยครั้งต้องรอข้อมูลจากระบบอื่น ๆ ที่เกี่ยวข้อง ช้าบ้าง เร็วบ้าง ค้างบ้าง
- ลำดับการทดสอบผิด ส่งผลต่อการทำงาน ซึ่งเกิดจากการเขียนชุดการทดสอบที่ผิด คือแต่ละชุดการทดสอบไม่เป็นอิสระต่อกัน ไม่สามารถสลับลำดับการทดสอบ หรือ ทดสอบแบบขนานได้
- มีจำนวนการทดสอบ End-to-End เยอะมาก ๆ แน่นอนว่า ถ้าเจอแบบ 2 ข้อแรกไปยิ่งปัญหาเยอะมากมาย
ดังนั้นสิ่งที่เราควรต้องทำคือ
ลดจำนวนของ Flakiness test ลง
แน่นอนว่า ต้องมีการ monitoring การทดสอบด้วยเสมอ
ว่ามีปัญหาตรงไหนบ้าง ตรงนี้สำคัญมาก ๆ
ถ้าปลายทางมีปัญหา ก็ต้องแก้ไขที่ปลายทาง มิใช่แก้ไขที่ต้นทาง !!
จากนั้นต้องทำการแก้ไขอย่างรวดเร็ว
ส่วนระบบต่าง ๆ จำเป็นต้องทำให้มันเสถียรและน่าเชื่อถือ
หนึ่งในการแก้ไขคือ ลดการใช้งาน Waiting หรือ ให้รอนาน ๆ
พบว่า ถ้าเราใส่เวลาให้รอไป 5 วินาทีแล้วยังไม่พอ
สิ่งที่แก้ไขคือ เพิ่มเวลาไปให้นานกว่าเดิมอีก ไม่น่ามีใครทำ ใช่ไหม ?
ยกตัวอย่างการทดสอบระบบงานด้วย Cypress
ผมจะเจอ code การทดสอบแบบนี้บ่อยมาก ๆ
[gist id="653262fd4b8932eb2d667a1faba6b19e" file="1.js"]คำอธิบาย
ในขั้นตอนการค้นหานั้น ต้องไปดึงข้อมูลจาก RESTful API มา
ซึ่งปัญหาอยู่ตรงนี้ เดี๋ยวช้าเดี๋ยวเร็ว
ส่งผลให้ผลการทดสอบผ่านบ้าง ไม่ผ่านบ้าง
ดังนั้นเราจึงแก้ไขด้วยการใส่ wait(5000)
คือให้รอไป 5 วินาที ไม่ว่าจะทำงานเร็วก็ไม่สนใจ
ใน Cypress จะมีการจัดการ Assertion ของ Network request ให้เลย
ซึ่งจะรอไปจนกว่า จะเรียก RESTFul API และได้ response เรียบร้อย ดังนี้
[gist id="653262fd4b8932eb2d667a1faba6b19e" file="2.js"]เป็นอีกแนวทางหนึ่งที่น่าสนใจ สำหรับการแก้ไข Flakiness testing