Screen Shot 2557-07-09 at 1.28.50 PM

ปัจจุบันกระบวนการพัฒนา software นั้นนำ unit test มาใช้กันมากขึ้น
หรืออาจจะนำแนวคิด Test Driven Developement ( TDD ) มาใช้
แต่มันก็มักมาพร้อมกับความเข้าใจผิดต่างๆ นานา
จนทำให้ unit test ที่สร้างขึ้นมานั้นก่อให้เกิดปัญหาเสียเอง
ดังนั้น มาดูกันว่าความเข้าใจผิดเหล่านั้น ประกอบไปด้วยอะไรบ้าง

การพัฒนา software นั้นไม่ใช่เรื่องที่ง่ายเลย

มีหลายสิ่งหลายอย่างให้เราต้องศึกษา ทั้งจากการอ่าน
การฝึกฝนจนชำนาญ ด้วยแนวปฏิบัติต่างๆ ที่เขาว่าดี
ตัวอย่างเช่นการเขียน unit test

โดยที่ unit test นั้นมันเรียบง่ายมาก
สร้างมาเพื่อทำการพิสูจน์ให้เห็นว่า การทำงานของ code ที่เราเขียนขึ้นมานั้น
ทำงานเป็นไปตามดังที่เราคาดหวังไว้หรือไม่

บางคนก็อาจจะบอกว่า การเขียน unit test เพื่อเป็นการบอกว่า
เราเข้าใจในปัญหาที่กำหลังแก้ไขหรือไม่

แต่ก็มีหลายคนที่ยังต่อต้าน หรือไม่เห็นด้วยกันการเขียน unit test
ซึ่งเรื่องนี้มันขึ้นอยู่กับบริบทของแต่ละคน
ส่วนผมเขียน unit test ก็พอล่ะ

แต่เมื่อกลับไปดู unit test ที่เขียนขึ้นมาแล้ว

ก็พบว่า ผู้นำไปใช้งานส่วนใหญ่จะเข้าใจผิดอยู่เสมอ ทำให้ได้ผลลัพธ์ที่ไม่ดี เช่น
เมื่อมีการเปลี่ยนแปลงความต้องการต่างๆ แล้ว
จำเป็นต้องมาแก้ไข unit test เป็นจำนวนมาก ( Test Fragile )
ทำให้หลายๆ คน มองว่า unit test มันคือภาระเข้าไปอีก

ดังนั้นเรามาดูกันว่า มีความเข้าใจผิดอะไรกันบ้าง

1. เข้าใจว่า unit test มันคือวิธีการค้นหา bug

หลายคนมักจะบอกว่า unit test นั้นมันช่วยทำให้หา bug ได้มากขึ้น
ซึ่งนั่นคือเหตุผลหลักว่า ทำไมคนถึงเลิกเขียน unit test ภายในเวลาที่รวดเร็ว
และซ้ำร้ายไปกว่านั้น อาจจะทำให้ management นั้นไม่เชื่อใน unit test อีกเลย

ดังนั้น สิ่งที่ต้องคิดใหม่ก็คือ unit test ไม่ใช่สิ่งที่ช่วยหา bug
แต่เข้ามาช่วยป้องกันไม่ให้เกิด bug นะ

2. เข้าใจว่า unit test นั้นมีไว้สำหรับระบบขนาดใหญ่ และระบบที่ความซับซ้อน เท่านั้น

unit test มันคือ การให้ความสำคัญ เรื่องคุณภาพจากภายใน
ดังนั้น ไม่ว่าระบบจะใหญ่ขนาดไหน จำเป็นต้องมีคุณภาพ
ยิ่งมีขนาดใหญ่มากเท่าไร คุณภาพยิ่งมากขึ้นเป็นเงาตามตัว
ดังนั้น ลองคิดดูเองว่าควรเขียน unit test ไหม

3. Unit test กระทำโดย Tester

เป็นเรื่องที่เข้าใจผิดอย่างแรง  ถ้ายังทำงานอยู่ใน traditional software development
แน่นอนว่าการทดสอบมักจะโยนไปให้ทีม tester, QA เป็นผู้รับไว้
แต่นั่นเป็นเรื่องที่เข้าใจผิดอย่างแรง เนื่องจากเป็นการแก้ไขปัญหาที่ปลายเหตุ

ลองคิดดูว่า
developer  เขียน unit test เพื่อทำให้มั่นใจว่าการทำงานของส่วนงานต่าง ทำงานร่วมกันได้อย่างถูกต้อง แล้ว
ทาง QA มาดูภาพรวมในเรื่อง integration test ของระบบ ว่าทั้งระบบทำงานได้อย่างถูกต้อง
เมื่อต่างฝ่ายต่างช่วยเหลือกัน ก็น่าจะเป็นเส้นทางที่ดีสำหรับการทำงานนะ คุณว่าไหม ??
แต่ส่วนใหญ่หลายๆ ที่มักจะไม่ ?

มาถึงตรงนี้ unit test จึงไม่น่าจะเป็น task หรือ
งานที่ถูกแยกออกไปทำเป็น phase นะ
งานที่ถูกแยกออกไปทำโดยทีมอื่นๆ นะ
แต่มันคือสิ่งที่ควรอยู่ในการ coding นั่นเอง อย่างเป็นธรรมชาติ

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

ผมขอเน้นว่า unit test กระทำโดยทีม น่าจะเหมาะสมที่สุด

4. เข้าใจว่าต้องเขียน unit test สำหรับทุกๆ class และ ทุกๆ method

แนวคิดนี้จะถูกต้อง เมื่อคุณต้องการที่จะ refactor code ของ method นั้นๆ
แต่ถ้าไม่ใช่ ก็ไม่จำเป็นต้องเขียน unit test ทั้งหมดหรอกนะ
เริ่มเฉพาะในส่วนที่สำคัญๆ ก่อน จะเป็นเส้นทางที่เหมาะต่อการเริ่มต้น

สิ่งที่ควรรู้ไว้คือ unit test คือ การทำซ้ำ 
เนื่องจากเราต้องการทำตรวจสอบ เรื่องเดิมซ้ำๆ  ด้วยข้อมูลที่หลากหลาย
ดังนั้น unit test อาจจะเรียกได้ว่า เป็น redundancy programming ก็ได้

เราไม่ควรบังคับให้ทีมทำการเขียน unit test บน code ที่แย่ๆ
แต่ควรบอกว่า ทีมเราควรเขียน code ที่สามารถทดสอบได้ง่ายแทน ( Teatable )

การเขียน unit test ควรเริ่มจากง่ายๆ ก่อน
ไม่จำเป็นต้องใช้ framework ที่ซับซ้อน
เนื่องจากเราต้องการสร้าง product ที่ดี ไม่ใช่ unit test ที่ดีนะ

5. ควรเขียน unit test ก่อนหรือหลังจากการเขียน code ?

คำพูดที่น่าสนใจจากคุณ Michael Feather กำหนดความหมายของ legacy code ไว้ คือ code ที่ไม่มี test
ดังนั้น ถ้าคุณเขียน test หลังจาก code แล้วคุณจะได้ legacy code มาอย่างแน่นอน

และในปัจจุบัน หลายๆ คน น่าจะกำลังเผชิญกับ legacy code ดังนั้นคุณยังอยากจะสร้างมันขึ้นมาอีกหรือ ?

ในบางครั้งหลายๆ คนมักจะบอกว่า เดี๋ยวกลับมาเขียนในภายหลัง
แต่ในความเป็นจริง คือไม่มีทางกลับมาเขียนแน่นอน
เพราะว่า ต้องทำงานอื่นๆ ไปตลอดเวลา  ( Test later = Test never )

6. เข้าใจว่าเขียน unit test แล้ว มันจะทำให้ง่ายต่อการแก้ไข code

code ที่สามารถทดสอบได้ง่ายนั้น ไม่จำเป็นต้องแก้ไขง่าย
แต่สิ่งที่ unit test ช่วยก็คือ ทำให้เรามั่นใจในการแก้ไข code
ว่าสิ่งที่เราแก้ไขไปนั้นส่งผลต่อการทำงานอื่นๆ บ้างหรือไม่

ส่วนจะแก้ไขยากหรือไม่ เป็นเรื่องของการออกแบบโครงสร้าง code กันแล้ว
เช่น การมองในระดับ abstraction มากกว่าการ implement เป็นต้น

แต่ถ้า unit test ของคุณผูกมัดกับส่วน implement มาก เมื่อมีการเปลี่ยนแปลง
มันจะกระทบต่อ code และ unit test อย่างมาก
ทำให้คุณต้องเขียนทั้ง code และ unit test ขึ้นมาใหม่อยู่เสมอ
ผลก็คือ มันทำให้คุณลำบาก มีงานเพิ่มเป็น 2 เท่า ….

ดังนั้นต้องศึกษา technical practice อื่นๆ เพิ่มด้วย เช่น แนวคิด SOLID เป็นต้น

7.  Unit test นำไปสู่การออกแบบ code ที่ดี !!!

เป็นความเข้าใจผิดอย่างมาก เนื่องจากมันไม่ใช่จุดประสงค์ของ unit test
แต่สิ่งที่น่าสนใจกว่าก็คือ

  • เริ่มด้วยการเขียน code ที่สามารถทดสอบได้ง่าย แต่โครงสร้างของ code จะแย่ๆ ( Make it work )
  • code ที่มี unit test นั้นมันสามารถที่จะปรับปรุงให้ดีขึ้นได้ ( Make it right )
  • ดังนั้น unit test จะช่วยทำให้คุณสามารถปรับปรุง code ให้ดีขึ้นไปเรื่อยๆ ได้อย่างมั่นใจ

โดยสรุป

ผมไม่ได้บอกว่า unit test มันยาก หรือ ไม่ต้องเขียนมันหรอกนะ
แต่ก่อนจะนำอะไรเข้ามาใช้งาน ควรจะศึกษาให้เข้าใจถึงที่มาที่ไปของมันก่อน

การทดสอบนั้น มันมีคุณค่า มันทำให้เรามีความมั่นใจ
และป้องกันความผิดพลาดต่างๆ ที่อาจจะเกิดขึ้นใน software ของเรา

ดังนั้น ถ้าอยากรู้ว่า unit test มันช่วยเรื่องคุณภาพให้กับ software ที่พัฒนาหรือไม่
เริ่มง่ายๆ ด้วยการลงมือทำครับ แล้วจึงกลับมาดูว่าดีขึ้นไหม !!!!

Reference Website
http://nearsoft.com/blog/five_misconceptions_about_unit_testing/
http://www.infoq.com/articles/testing-misconceptions
http://www.davesquared.net/2007/05/tdd-and-unit-testing-misconceptions.html
http://thomaskowalski.wordpress.com/2013/08/09/top-3-misconceptions-about-unit-testing-and-tdd/
http://www.slideshare.net/TerryYin/misconceptions-of-unit-testing