Screen Shot 2558-10-03 at 11.06.12 AM
มีโอกาสได้ไปแนะนำแนวทางการเขียนโปรแกรมเบื้องต้น
ให้กับนักศึกษาระดับปริญญาตรีที่มหาวิทยาลัยวลัยลักษณ์มา
โดยหนึ่งในแนวทาง ที่ได้แนะนำ และ พาฝึกหัด คือ TDD (Test-Driven Development)
ซึ่งมันเหมาะมากสำหรับการเรียนรู้ และ การนำไปใช้งาน

เริ่มต้นด้วยการแนะนำให้รู้จัก TDD

  • TDD มันคือวินัยสำหรับการทำงานของทุก ๆ คน (Way of working)
  • Developer ทุก ๆ คนต้องเขียน Automated test สำหรับ code ที่เขียนขึ้นมาด้วยเสมอ ไม่มีข้อยกเว้น
  • TDD มันคือรอบการทำงานสั้น ๆ ในระดับทุก ๆ นาที

ขั้นตอน และ แนวทางของ TDD เป็นดังนี้

ขั้นตอนที่ 1 :: Overview และ Think

เริ่มจาก คิด วิเคราะห์ แยกแยะ ก่อนว่าปัญหาคืออะไร อย่างไร​ ?
มีชุดการทดสอบอะไรบ้าง ?
จะทำการทดสอบอย่างไร ?

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

ขั้นตอนที่ 2 :: Red

เริ่มทำการเขียน test ซึ่งใช้ข้อมูลจากขั้นตอนที่ 1 นำทาง (Guide by tests)
สิ่งที่สำคัญมาก ๆ ในขั้นตอนนี้ คือ

  • การตั้งชื่อของ test
  • สิ่งที่อยู่ใน test จะต้องเป็นไปตามชื่อ test ด้วยนะ
  • โครงสร้างของ test ที่ดี ซึ่งสิ่งที่แนะนำคือ AAA (Arrange-Act-Assert)
  • แน่นอนว่า code จะต้อง compile ผ่านด้วยนะ
  • ส่วนผลการทำงานยังไม่ถูกต้อง เพราะว่า เรายังไม่ implement หรือ สร้าง code อะไรเลย

ขั้นตอนที่ 3 :: Green

ทำการเขียน code ผมมักจะเรียกว่า production code
เป็น code จริง ๆ ที่เราส่งมอบให้ลูกค้านั่นเอง
ซึ่งมี 3 แนวทาง คือ

  1. Fake, Hard code หรือ dummy code ขึ้นมา เพื่อให้ test ผ่าน
  2. แก้ไข Fake code ด้วยการเพิ่ม test ใหม่เข้าไป ซึ่งเรียกวิธีการนี้ว่า Triangulation
  3. Real implementation คือ code ที่แก้ไขปัญหานั้นจริง ๆ

เป็นแนวทางท่ีอธิบายไว้ในหนังสือ Test-Driven Development by Example

โดยสิ่งที่ผมแนะนำไปคือ
เริ่มทำจากข้อ 1 และ 2 และ 3 ตามลำดับ
เพื่อทำให้เราเห็นว่า แนวทางการแก้ไขปัญหาเล็ก ๆ เป็นอย่างไร (Small step)

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

  • แก้ไข code ให้ดีขึ้น
  • ทำการเขียน test ใหม่

ขั้นตอนที่ 4 :: Refactor

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

  • เอา code ที่มัน Fake ออกไป
  • มี code ที่มันไม่ดี หรือ Code smell หรือเปล่า ถ้ามีก็เอาออกไป
  • โครงสร้างของ code ดีหรือไม่ ถ้าไม่ดีก็ปรับปรุง

แต่จำไว้ว่า
ในขั้นตอนนี้ เราจะไม่เพิ่ม feature ใหม่ ๆ เข้าไปนะครับ
เนื่องจากขั้นตอนนี้ คือ การปรับปรุงให้ดีขึ้น

เมื่อทุกอย่างเรียบร้อยให้กลับไปที่ ขั้นตอนที่ 1 หรือ ขั้นตอนที่ 2 ได้เลย

ข้อดีของ TDD ที่เห็นได้ชัดคือ

เรื่องของ feedback loop ที่รวดเร็ว
กล่าวคือ
เมื่อเราเขียน test ขึ้นมา แล้วผลการทำงานคือ ไม่ผ่าน หรือ fail
นั่นคือ feedback ที่บอกคุณว่า
ปัญหาคืออะไร ?
เพื่อทำให้เราแก้ไขปัญหาได้อย่างทันท่วงที
ไม่ต้องไปเสียเวลา debug อีกต่อไป

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

รวมทั้งเรื่องของการออกแบบอีกด้วย
code ส่วนไหนที่ไม่จำเป็นลบออกไป
ขั้นตอนนี้ เรากำลัง LEAN กันอยู่หรือเปล่านะ ?

TDD มันไม่ใช่สิ่งที่ดีที่สุดนะ มันคือแนวทางหนึ่งที่ดีเท่านั้น

ยังมีวิธีการอื่น ๆ ที่ดีอีกมากมาย
แต่ในตอนนี้ผมคิดว่า TDD คือแนวทางที่เหมาะสมมาก ๆ

จากหนังสือ Coder at work เขียนไว้ว่า

You can test all you want
and if you don’t know how to approach the problem,
you’re not going to get a solution

ลองถามตัวเองสิว่า
คุณแก้ไขปัญหากันอย่างไร ?

ปิดท้ายด้วย แนวปฏิบัติที่ทีมพัฒนาต้องมี และ ปฏิบัติอย่างมีวินัย

ประกอบไปด้วย

  • Testing และ Exploratory Testing
  • การตรวจสอบแบบอัตโนมัติ ถ้าระดับ code มันคือ TDD นี่เอง
  • Continuous Integration
  • Automated Build
  • Version Control

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

Screen Shot 2558-10-03 at 10.52.37 AM

 

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

เอกสารต่าง ๆ ของการแบ่งปันอยู่ที่ GitHub:Up1:PHP101

Tags: