Screen Shot 2558-05-30 at 2.34.48 PM
จากงาน Agile Transformation Summit 2015 นั้น
มีหัวข้อที่น่าสนใจเกี่ยวกับ TDD คือ TDD – Making sure everything works
ทำการอธิบายเกี่ยวกับ 20 ความเข้าใจผิดเกี่ยวกับ TDD
ดังนั้นมาดูกันว่า 20 ข้อนั้นมีอะไรบ้าง …

ในปัจจุบันแนวปฏิบัติ TDD (Test-Driven Development) นั้น

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

แต่ developer ส่วนมาก
มักจะพบเจอปัญหามากมายเมื่อเริ่มนำ TDD มาใช้งาน
โดยทางผู้พูดทำการสรุป 20 สิ่งเข้าใจผิด
และปัญหาที่พบเจอมากมาให้เราเพื่อเตรียมตัวรับมือกับมัน

แต่ผมเลือกเฉพาะเรื่องที่โดนใจมาสรุปให้ฟัง ดังนี้

1. Thinking that your code is flawless

คิดไปเองว่า code มันดี ทำงานได้อย่างถูกต้อง
แต่โดยธรรมชาติของ code มันมักจะถูกเปลี่ยนแปลงตาม business อยู่เสมอ
และนั่นคือจุดเริ่มต้นของความผิดพลาดต่างๆ

คุณสามารถพิสูจน์ได้ไหมว่า
code ที่คุณสร้าง หรือ แก้ไขมันถูกต้อง
และ ไม่กระทบส่วนการทำงานอื่นๆ
ตอบตรงนี้ได้เลย ว่าไม่ได้หรอกนะ !!

2. Thinking that is all about the tests

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

3. Asking for permission

มันเป็นสิ่งที่ไม่ควรทำเลย
จะขออนุญาตไปทำไม ในเมื่อมันคือสิ่งที่คุณต้องทำ !!

เมื่อคุณมีคำถาม หรือ ต้องขออนุญาตแสดงว่ามันมีแนวคิดอื่นๆ อีกใช่ไหม ?
… น่าจะไม่แล้วนะ …
ดังนั้นลงมือทำเถอะครับ

4. Not having your entire team onboard

ไม่มีทีมมาทำ ..
หรือ ทำ tdd แค่บางคน ไม่ได้ทำทั้งทีม ..

ในการพัฒนา software นั้นคือการทำงานเป็นทีม
ซึ่งทีมก็ควรที่จะต้องทำเองนะ
จะแยกไปให้อีกทีมทำ มันเป็นเรื่องที่ยากมาก
ลองคิดดูสิว่า ถ้าโลกนี้ไม่มี Stack overflow และ Google
ชีวิตคุณจะเป็นอย่างไร ?
TDD ก็เช่นกัน ไม่ต้องการ team มา support หรอกนะ

5. Pursuing a specific code coverage

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

เนื่องจาก code coverage มันใช้วัดในเชิงปริมาณมากกว่าเชิงคุณภาพ
ดังนั้นค่า code coverage มันไม่ได้บอกว่า test ที่เขียนขึ้นมาดีหรือไม่ ?
เราจะรู้ได้อย่างไรว่า สิ่งที่ทดสอบมันถูกต้อง ?
เราจะรู้ได้อย่างไรว่า test และ code มันอ่านง่าย และดูแลรักษาได้ง่าย ?

ดังนั้นค่า code coverage ใช้เพื่อการปรับปรุงนะ
อย่านำมาใช้เพื่อบังคับให้ทำตาม
ไม่เช่นนั้นจะได้เพียงปริมาณ แต่ไร้ซึ่งคุณภาพ

6. Failing to be consistent

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

ซึ่งเหตุมาจากคำพูดที่คุณบอกว่า เดี๋ยวค่อยทำทีหลัง (Do it later)

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

ดังนั้น ทีมควรที่จะหาวิธีการของทีม
เพื่อไม่ให้สมาชิกในทีมออกนอกลู่นอกทางกันนะ !!

7. Not running your tests frequently enough

คุณทำการ run test ทั้งหมดบ่อยเพียงใด ?
ถ้าคุณไม่ทำการ run test เลย หรือ นานๆ ครั้ง
มันบ่งบอกว่า คุณกำลังมีปัญหาแล้วนะ

แสดงว่าคุณไม่ได้เขียน test ให้ fail ก่อนที่จะเขียน code ใช่ไหม ?
แสดงว่าชุด test ทั้งหมดของคุณ มันใช้เวลาทดสอบนานมากใช่ไหม ?
แสดงว่า feedback ที่คุณได้จาก test มันช้ามากๆ ใช่ไหม ?
แสดงว่า คุณแก้ไขสิ่งต่างๆ ได้ช้าลงใช่ไหม ?
และสุดท้ายขั้นตอนการพัฒนา software ของคุณมีปัญหาแล้วนะ

ดังนั้น ทำการ run test ให้บ่อยที่สุดเท่าที่จะเป็นไปได้
ปกติผมจะ run test ทุกๆ ครั้งที่ code มีการเปลี่ยนแปลง

8. Failing to define proper conventions

ในการทำงานเป็นทีมควรที่จะกำหนดแนวทางการทำงานต่างๆ ด้วยกันซะ
ทั้งแนวทางการตั้งชื่อ เพื่อให้เป็นภาษาเดียวกัน
ทั้งโครงสร้างของ test ที่เขียน
ทั้งสถาปัตยกรรมของระบบ โดยให้ยึด unit test เป็นหลักในการออกแบบระบบ

9. Testing other people’s code

การไปทดสอบ code ของคนอื่นมันแปลกๆ ไหมนะ
คุณจะไปทดสอบ code ของคนอื่นได้อย่างไร
ถ้าคุณยังต้องเขียน test ก่อนที่จะเขียน code นั้นขึ้นมา

คุณจะไปขัดจังหวะการทำงานคนอื่นๆ และ ตัวเองทำไมนะ ?
ให้แต่ละคนคิดสิ ว่าจะทำอะไร
และทำให้มันเกิดขึ้นมาซะ
มันเป็นแนวปฏิบัติปกติของมนุษย์เลยนะ

10. Writing code without having a failing test

มันคือปัญหาที่หลายๆ ที่อาจจะกำลังประสบปัญหาอยู่
คือการไม่เขียน test หรือเขียน test หลังจากที่เขียน code

ซึ่งถ้ายังทำกันอยู่ แนะนำให้หยุดเดี๋ยวนี้ !!
และให้เริ่มต้นใหม่ ด้วยแนวทางใหม่ คือ

  • ลบ code ทิ้ง
  • เขียน test ให้ fail
  • เขียน code เพื่อให้ test ผ่าน

ดังนั้นให้จำไว้ว่า
เราจะไม่เขียน code ใดๆ ทั้งสิ้น ถ้าไม่เขียน test ที่มัน fail

11. Writing a test before all other tests are passing

เหตุใจคุณถึงเขียน test ใหม่ก่อนที่จะ run test ทั้งหมดให้ผ่านล่ะ ?
คุณต้องมั่นใจก่อนว่า ทุกๆ test มันผ่านนะ

ลองคิดดูสิว่า
ถ้าคุณเขียน test ที่มัน fail
จากนั้นทำการ run test ทั้งหมดแล้วเกิดปัญหาจาก test อื่นๆ
แล้วเราจะทำอย่างไร ?

เราจะมีสมาธิกับการแก้ไขหลายๆ ปัญหาพร้อมกันหรือ ?
ตอบได้เลยว่าเป็นไปไม่ได้หรอกนะ

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

เป้าหมายของ TDD คือทำให้ test มันผ่านทั้งหมดให้เร็วที่สุดเท่าที่จะเป็นไปได้

12. Refactoring before all tests are passing

เป็นแนวทางที่น่ากลัวมากๆ เลยนะ
ดังนั้นคุณห้ามแก้ไข code เด็ดขาด ถ้า test ยังไม่ผ่านทั้งหมด

การ refactoring คือ การปรับปรุง code ให้ดีขึ้น
ดังนั้น จะทำให้ code ดีขึ้นได้อย่างไร ถ้า test มันยัง fail !!

13. Writing code unrelated to the failing test

คุณควรหยุดเขียน code ที่ไม่เกี่ยวกับ test นั้นๆ เลย

นั่นหมายความว่า
ควรเขียน code เท่าที่จะทำให้ test มันทำงานผ่านเท่านั้นนะ
ดังนั้น code ที่เขียนจะไม่เยอะ หรือ ให้ง่ายที่สุดเท่าที่จะทำได้
หรือเขียน code เท่าที่ test มันบอกเรานะ

14. Testing more than one thing at the time

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

ดังนั้น แต่ละ test ควรทำงานเพียงอย่างเดียวเท่านั้นนะ
แต่ถ้ามี test ที่ซับซ้อน หรือ มีการทดสอบมากกว่าหนึ่งอย่าง
ก็ให้ test ออกมานะ

15. Writing slow tests

ลองคิดดูสิว่า ถ้า test มันที่เขียนขึ้นมามันทำงานช้า
คุณจะได้รับ feedback กลับมาช้าเพียงใด ?
คุณสามารถ run test บ่อยๆ ได้หรือไม่ ?

ดังนั้นควรทำให้ test มันทำงานให้เร็วที่สุดเท่าที่จะเป็นไปได้
และต้อง run test อย่างสม่ำเสมอ

แต่ถ้ามี test ที่มันทำงานช้าๆ ก็ให้แยกกลุ่มของ test ซะ
เช่น fast test และ slow test

และสิ่งที่ขาดไม่ได้เลยในการเขียน test
คือแนวคิด Test double
เพื่อทำให้สามารถทดสอบพวก dependency ต่างๆ ที่มันทำงานช้า
ให้สามารถทดสอบได้รวดเร็วขึ้น

16. Creating dependencies between tests

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

ลองดูสิว่า มีอะไรที่เราเข้าใจผิดเกี่ยวกับ TDD กันอีกบ้าง ?

Tags: