เห็นใน facebook มีคำถามว่า
เขียน Unit testing แบบไหนถึงดี ?

เป็นคำถามที่ตอบยากมาก ๆ
เพราะว่าคำว่า “ดี” นั้นแตกต่างกันเหลือเกิน
แต่คิดว่ามันเป็นสิ่งที่ดีนะ
จึงเริ่มด้วยคำถามก่อนว่า

ทำไมการทดสอบ code ของเราจึงมีความสำคัญ ?

การทดสอบ code ที่เราเขียนนั้น

น่าจะเป็นสิ่งที่ดีมาก ๆ
เพื่อเป็นการพิสูจน์และแสดงให้เห็นว่า
สิ่งที่เรากำลังพัฒนา สิ่งที่กำลังจะส่งมอบไปยังลูกค้าเป็นอย่างไร
เป็นสิ่งที่จะช่วยบอกให้เรารู้สิ่งที่ผิดพลาดได้เร็ว
เพื่อทำการแก้ไขและปรับปรุงต่อไป

แต่หลาย ๆ คนบอกว่า
เราไม่ทำการตรวจสอบ code แบบนี้หรอกนะ มันเสียเวลา
เราจะเขียน code ให้เสร็จก่อน
จากนั้นจึงทำการตรวจสอบทีเดียวเลย
มันจะได้ไม่เปลืองเวลา
ระหว่างนั้นก็นั่งจินตนาการในหัวไปว่ามันทำงานได้นะ
เมื่อเขียนเสร็จก็ run สิครับ
พบว่า code ที่เขียนมากมายนั้น มันทำงานผิด
สิ่งที่เกิดขึ้นคือ แก้ไข code สิ แต่ยังก่อน !!
ตรงไหนละที่ผิด ?
เดี๋ยวของ debug code ก่อนนะ !!
งงไหมละ คนอะไร debug code ที่ตัวเองเขียน !!
คำถามคือ ใช้เวลานานไหม ?
ส่วนใหญ่ก็บอกว่า ไม่นานนะ !!
ถ้าเป็นแบบนี้ก็เอาที่สบายใจนะ คิดว่าดีก็ทำต่อไป !!

กลับมาเรื่องของ Unit testing กันต่อดีกว่า

ถ้าต้องการเขียน Unit testing แล้วมีคำแนะนำดี ๆ มาฝาก

ก่อนจะเขียนกรุณาทำความเข้าใจกับ requirement/feature และ business goal ก่อนนะ
มาดูกันว่ามีอะไรบ้าง ?

1. โครงสร้างของ test ที่ดี ถือว่าเป็นการเริ่มต้นที่ดี

ช่วยทำให้ test อ่านง่ายขึ้น
ใช้ได้กับทุก ๆ ภาษา และ ทุก ๆ รูปแบบการทดสอบ
ปกติจะใช้ AAA (Arrange Act Assert) เป็นหลัก
Arrange สำหรับกำหนดค่าเริ่มต้นของการทดสอบ
Act สำหรับ execute ส่วนที่ต้องการทดสอบหรือ business logic
Assert สำหรับการตรวจสอบว่า ผลการทำงานตรงตามที่คาดหวังหรือไม่ ต้องมีทุก test นะขาดไม่ได้

ที่สำคัญแต่ละ test ต้องมีเป้าหมายเพียงอย่างเดียวด้วย

2. การทดสอบต้องเร็ว ถึง เร็วมาก

เป็นหัวใจหลักของการทดสอบเลย
ยิ่งเร็วมากเท่าไร
นั่นคือ เราได้ feedback เร็วมากเท่านั้น
ดังนั้นมันจะสะท้อนว่า
แต่ละ test ต้องสั้นกระชับ ไม่ซับซ้อน และเน้นที่ business logic ของระบบ

ถ้า test คุณช้า นั่นแหละคือปัญหาแรก ๆ ที่ต้องแก้ไข

3. การทดสอบที่ถูกต้อง

คำถามที่น่าสนใจคือ
เราจะรู้ได้อย่างไรว่า test มันถูกต้อง ?
ตอบได้ยากมาก ๆ
แต่มีแนวทางหนึ่งคือ
เขียน test ก่อนสิ เพื่อให้ test มัน fail หรือไม่ผ่าน
จากนั้นถึงเขียน code เพื่อให้ test ผ่าน
คุ้น ๆ กับวิธีการไหม ?

4. เพิ่มการทดสอบไปใน build pipeline ด้วยเสมอ

แนวคิดง่าย ๆ คือ เมื่อ code มีการเปลี่ยนแปลงแล้ว
จะทำการ build และ test อยู่เสมอ
บางทีมก็มีระบบ Continuous Integration
แนะนำให้เพิ่มการทดสอบเข้าไปด้วย

บางทีม ถ้าการเปลี่ยนแปลงเกิดผิดพลาด
ก็จะทำการ rollback code ใน repository กลางทันที

5. อย่าลืมจัดการ dependency ต่าง ๆ ให้ดี

ก่อนที่จะทำการทดสอบควรจัดการ dependency ต่าง ๆ ให้ดี
ทั้ง state และ data
เพื่อทำให้ test ทำงานได้อย่างถูกต้อง

ลองคิดดูสิว่า
ถ้าบางครั้งทดสอบผ่าน
ถ้าบางครั้งทดสอบไม่ผ่าน
ผลที่ตามมาคือ ไม่มีใครเชื่อถือ test แน่นอน

สุดท้ายแล้วอย่างลืมว่า การทดสอบมีหลายระดับนะ
เพียง Unit testing อย่างเดียวไม่พอนะครับ
ทั้ง Integration test , Regression test และ Performance test เป็นต้น

ก่อนอื่นวันนี้คุณเขียนหรือยัง ?
เข้าใจคุณค่าหรือยัง ?
ยิ่ง code มีขนาดใหญ่มากเท่าไร test ยิ่งสำคัญมาก ๆ

ขอให้สนุกกับการ coding ครับ