เช้านี้นั่งอ่านบทความเก่า ๆ ที่เก็บเอาไว้คือ 5 Common Misconceptions About TDD & Unit Tests
อธิบายเกี่ยวกับความเข้าใจผิดเกี่ยวกับ TDD และ Unit Test
จึงทำการแปลและสรุปเนื้อหาบางส่วนไว้นิดหน่อย

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

ปัญหาเหล่านี้อาจจะเกิดมาจาก
ความไม่รู้
ความมีประสบการณ์เยอะไป จนไม่เปลี่ยนวิธีการรวมไปถึงความเชื่อ
ความเข้าใจผิด
หรือเหตุผลใด ๆ ก็ตาม
ดังนั้นมาปรับทัศนคติกันหน่อย
ซึ่งในบทความอธิบายไว้ 5 ข้อดังต่อไปนี้

1. การเขียน unit test หรือทำตามแนวทางของ TDD นั้นมันใช้เวลานาน

ดังนั้นทางทีม business ไม่เห็นดีเห็นงามอย่างแน่นอน
ที่สำคัญมันคือเหตุผลหลักของการไม่ทดสอบระบบ
ผลที่ตามมาก็กระทบทั้งสองฝ่ายคือ development และ business !!

เนื่องจากฝ่าย business ไม่สนใจหรอกว่า
ฝ่าย development จะทำอะไร อย่างไร แบบไหน
ขอให้ได้งานตามที่ต้องการก็พอ

ดังนั้นสิ่งที่ต้องมาคุยและทำความเข้าใจกันใหม่คือ
ฝ่าย business สนใจตัวชี้วัดอะไรบ้าง ?
ในการเขียน unit test และ TDD นั้นส่งผลอะไรต่อตัวชี้วัดของทาง bussiness บ้าง ?

  • ช่วยปรับปรุง productivity ของทีมพัฒนาในระยะยาว
  • ลดค่าใช้จ่ายของฝั่ง customer service และ operation
  • ช่วยทำให้มีผู้ใช้งานมากขึ้น
  • ลูกค้ามีความพึงพอใจมากขึ้น ลดการเลิกใช้งานไป

จากงาน research ของระบบงานที่เขียน unit test และ TDD มาใช้งาน
พบว่าสามารถลด bug บน production ได้ถึง 40-80%
นั่นหมายความว่า
ถ้านักพัฒนาเขียน code โดยไม่มีการทดสอบเช่นเขียน unit test แล้ว
จะเป็นการเพิ่ม bug หรือความผิดพลาดเข้าไปในระบบ
นั่นคือ เราเสียเวลาไปโดยเปล่าประโยชน์หรือไม่ ?
นั่นคือ เสียค่าใช้จ่ายแล้วได้ bug กลับมา มันใช่หรือไม่ ?

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

ในบทความอธิบายว่า
ช่วงเริ่มต้นของการนำ unit test และ TDD มาใช้งาน
จะเพิ่มเวลาในช่วงแรกประมาณ 10-30%
แต่เมื่อเวลาผ่านไปจะช่วยลดงานต่าง ๆ ลงไป

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

2. นักพัฒนาไม่สามารถเขียน test ได้ถ้ายังไม่เขียน code

เป็นสิ่งที่เกิดขึ้นกับนักพัฒนาที่ยังไม่เคยฝึกหรือทำ unit test และ TDD
แต่สิ่งที่ต้องเข้าใจคือ แนวทางนี้คือการเรียนรู้
ต้องมีวินัยในการเรียนรู้
ต้องมีวินัยในการศึกษาเพื่อพัฒนาความสามารถของตนเอง
เพราะว่า มันคือแนวทางที่ต่างจากเดิมอย่างมาก

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

3. ต้องเขียน test ให้ครบก่อนเริ่มเขียน code !!

สิ่งที่ต้องเข้าใจก่อนคือ ปัญหา และ ภาพรวมของสิ่งที่กำลังจะพัฒนา
จากนั้นให้เริ่มทำตามขั้นตอนดังนี้

  1. เขียน test เพียง test case เดียวเท่านั้น
  2. Run test case นั้น แน่นอนว่าต้อง fail
  3. ทำการเขียน code เพื่อให้ test case ผ่าน (Code เท่าที่ทำให้ test case ผ่าน)
  4. Run test case นั้น แน่นอนว่าต้อง ผ่าน
  5. กลับไปทำข้อ 1 ใหม่อีกรอบ

4. ต้องทำการ refactor code อยู่ตลอดเวลา !!

ถามว่าดีไหม ตอบว่าดี
แต่ต้องตอบให้ได้ก่อนว่า เหตุใดจึงทำการ refactor ?
นั่นคือ คุณต้องเรียนรู้ Code Smell ก่อนนะ
เป้าหมายของการ refactoring คือ
ปรับปรุง code ให้ดีขึ้น
ปรับปรุง code ให้เหมาะสมกับทีม
ปรับปรุง code เพื่อให้ทีมเร็วและเข้าใจมากขึ้น
นั่นคือการลดเวลาที่ไร้ประโยชน์ออกไป

5. ต้องเขียน unit test ทั้งหมด !!

ระบบงานที่พัฒนานั้นมักจะต้องติดต่อสื่อสารกับส่วนอื่น ๆ มากมาย
ทั้งระบบ I/O, database, network, User interface
แน่นอนว่า
การเขียน unit test สำหรับสิ่งเหล่านี้มันยากมาก ๆ
บ่อยครั้งจะต้องใช้ Test double ร่วมด้วยเช่น Mocking
บ่อยครั้ง Mocking เต็มไปหมด
นั่นคือ Code smell อย่างหนึ่ง !!
หมายความว่า unit test เหล่านั้นมันไม่ค่อยมีประโยชน์ต่อเราสักเท่าไร !!

หรือว่า ต้องไปเขียน integration/functional/e2e test น่าจะมีประโยชน์หว่าหรือไม่ ?
แต่จะถ้าจะไปเขียน integration/functional/e2e test ทั้งหมดก็ไม่ดี
เพราะว่า ใช้เวลาในการทดสอบสูง
เพราะว่า ใช้เวลาในการเตรียม environment สูง
รวมทั้งเรื่องของ test converage ก็จะต่ำ
และ code ก็ไม่ถูกปรับปรุงให้ดีขึ้น
หรือให้สามารถเขียน unit test ได้ง่าย (Isolation)

เรื่องของ ROI (Return On Investment) จึงมีความสำคัญอย่างมาก

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