การเขียน Unit Test เป็นเรื่องสำคัญมากถ้าเราอยากพัฒนาซอฟต์แวร์ที่ไว้ใจได้ และบำรุงรักษาได้ในระยะยาว แต่ว่า...จะเขียนยังไงให้ดีล่ะ? วันนี้เรามีแนวทางที่เข้าใจง่ายและจำง่ายมาฝาก นั่นก็คือหลักการ FIRST ครับผม 🎯
FIRST คืออะไร?
FIRST เป็นคำย่อที่ช่วยเตือนใจว่า Unit Test ที่ดีควรมีลักษณะแบบไหนบ้าง มาดูแต่ละตัวกันเลย:
F – Fast (เร็ว)
การทดสอบควรรันได้เร็วมาก ถ้าใช้เวลาเยอะ นักพัฒนาจะไม่อยากรันบ่อยๆ พอไม่รันบ่อย ก็พลาดจับบั๊กเล็กๆ ไปได้ง่ายๆ
💡 Tip: อย่าไปโหลดไฟล์ใหญ่ๆ หรือเชื่อมต่อฐานข้อมูลจริงๆ ใน Unit Test — มันช้า!
I – Isolated (แยกจากกัน)
แต่ละเทสต์ควรทำงานได้ด้วยตัวมันเอง ไม่ควรพึ่งพาอะไรจากภายนอก เช่น ไฟล์, เครือข่าย, หรือแม้แต่เทสต์อื่นๆ
💡 Tip: ใช้ Mock หรือ Stub แทนการเรียก service จริงๆ
R – Repeatable (รันซ้ำแล้วได้ผลเหมือนเดิม)
เทสต์ควรให้ผลลัพธ์เหมือนเดิมทุกครั้ง ไม่ว่าจะรันตอนไหนหรือเครื่องไหนก็ตาม
💡 Tip: หลีกเลี่ยงการใช้เวลาแบบ real-time หรือข้อมูลจาก API ภายนอกที่เปลี่ยนแปลงได้
S – Self-Verifying (ตรวจสอบตัวเองได้)
เทสต์ควรจะ "บอกเราได้ทันที" ว่าผ่านหรือไม่ผ่าน โดยไม่ต้องมานั่งเปิดไฟล์ log หรือดูคอนโซลเอง
💡 Tip: ใช้ assertion ให้ชัดเจน ว่าคาดหวังผลลัพธ์แบบไหน
T – Timely (เขียนให้ทันเวลา)
อันนี้หลายคนมักพลาด! Test ควรถูกเขียน “ก่อน” ที่เราจะเขียนโค้ดจริง นี่คือหลักของ Test-Driven Development (TDD) ที่เน้นการเขียนเทสต์ก่อน แล้วค่อยเขียนโค้ดให้ผ่านเทสต์นั้น
💡 Tip: อย่ารอให้โค้ดเสร็จก่อนแล้วค่อยมาเขียนเทสต์ — แบบนั้นเรียกว่า TAD (Test-After Development) ซึ่งมักจะทำให้โค้ด test ยากขึ้นเยอะ
ทำไม FIRST ถึงสำคัญ?
เพราะ Unit Test ที่ดีจะช่วยให้เรา:
- จับบั๊กได้เร็ว
- กล้า refactor โค้ด
- มีเอกสารพฤติกรรมของระบบที่เป็นรูปธรรม
- ทำงานเป็นทีมได้ราบรื่นขึ้น
แถมยังช่วยลดเวลาที่เสียไปกับการ debug ที่ไม่รู้ว่าต้นตอมาจากไหนด้วยนะ 😉
แล้วถ้าเจอปัญหาล่ะ?
หลายครั้งเราก็เจอกับปัญหาเช่น:
- เทสต์ช้าเกินไป
- เทสต์ไม่เสถียร (บางทีก็ผ่าน บางทีก็ fail)
- เทสต์ต้องพึ่งพา service ภายนอก
สิ่งที่ช่วยได้คือ:
- แยก Unit Test ออกจาก Integration Test ให้ชัดเจน
- ใช้ Mock อย่างมีประสิทธิภาพ
- หมั่น refactor เทสต์ให้อ่านง่ายและดูแลง่าย
สุดท้ายนี้...ลองกลับไปดูเทสต์ของโปรเจกต์เราสิครับ ว่ามัน "เป็นไปตามหลัก FIRST" แค่ไหน ถ้ายังไม่ครบ ก็อาจถึงเวลาต้องมารีเฟรชแนวทางกันแล้วล่ะ!
ถ้าอยากให้ผมลงลึกในข้อไหนเพิ่มเติม บอกได้เลยนะครับ 🙂
ต้องการให้เพิ่มรูปประกอบหรือโค้ดตัวอย่างด้วยไหมครับ?