มาดูบทความเรื่อง The Cycles of TDD ที่คุณ Robert C. Martin (Uncle Bob)
อธิบายไว้อย่างน่าสนใจ
ซึ่งผมได้นำมาแปล ตามความเข้าใจของตนเองได้ดังนี้
เมื่อคุณเริ่มต้นศึกษา Test-Driven Development(TDD)
คุณจะพบว่ามันเรียบง่าย และ ทำง่ายเหลือเกิน
ซึ่งแนวคิดนี้มันเกิดมาตั้งแต่ปี 1999
โดยเริ่มง่ายๆ ด้วยการเขียน unit test ก่อน
ก่อนที่จะทำการเขียน code โดยแนวคิดนี้ถูกเรียกว่า Test-First Design
ทางผู้เขียนได้เล่าว่า
ในปี 1999 ได้ทำการ pair programming กับคุณ Kent Beck (ผู้สร้าง Extreme Programming)
ผลก็คือ ได้เรียนรู้สิ่งต่างๆ มากมาย หนึ่งในนั้นก็คือ
การเริ่มต้นเขียน test ก่อนจะเขียน code
โดย test นั้นมันคือ การย่อยของปัญหาออกมาเล็กๆ มีขั้นตอนดังนี้
- เขียน test ที่มันทำงานยังไงก็ fail
- เขียน code เพื่อให้ test นั้นมันผ่าน
- โดยการเขียน code นั้นจะมีจำนวนบรรทัดน้อยมาก เช่น 1 บรรทัด
- ทำแบบนี้ไปทุกๆ รอบ
ทางผู้เขียนได้สรุปออกมาว่า
รอบ หรือ cycle การทำงานด้วยแนวคิด TDD มาดังนี้
- Nano-cycle หรือ Second-by-Second
- Micro-cycle หรือ Minute-by-Minute
- Milli-cycle หรือ Decaminute-by-Decaminute
- Primary-cycle หรือ Hour-by-Hour
1. Nano-cycle หรือ Second-by-Second
เรียกได้ว่า cycle นี้มันก็คือ Three Law of TDD ประกอบไปด้วย
- คุณต้องเขียน fail test ขึ้นมาก่อนที่จะเขียน production code เสมอ
- คุณจะไม่เขียน test code มากเกินไป นั่นคือเขียน test ให้มัน fail ก็พอ หรือ compile ไม่ผ่าน
- คุณจะไม่เขียน production code มากเกินไป นั่นคือเขียน code เพียงให้ test มันผ่าน
โดยรูปแบบการพัฒนาแบบนี้ มันมีหลากหลายรูปแบบ และ แนวทางมากๆ
แต่เป้าหมายคือการการเขียน code แบบ line-by-line หรือ บรรทัดต่อบรรทัด
ซึ่งเป็นสิ่งที่ผู้เขียนได้เรียนรู้มาจาก Kent Beck
ตามกฎนี้ คุณจะเขียน code แบบวินาทีต่อวินาที หรือ แบบ Nano-cycle ไปเลย
นั่นหมายถึง คุณต้องทำแบบนี้ไปหลายๆ รอบ ต่อหนึ่ง unit test กันเลย
2. Micro-cycle หรือ Minute-by-Minute
เมื่อเราทำการเขียน code แบบนาทีต่อนาที
เราจะเห็นว่าคนที่ใช้ TDD หรือ TDDer นั้นจะทำตามรูปแบบนี้
นั่นก็คือ Red-Green-Refactor cycle นั่นเอง
โดนแต่ละรอบการทำงานแบบนี้ คือ 1 unit test นั่นเอง
ซึ่งกฏของ Red-Green-Refactor มันเรียบง่ายมากๆ ดังนี้
- เขียน unit test ที่มัน fail ขึ้นมา
- เขียน production code ที่ทำให้ unit test มันผ่าน
- ทำการ refactor ทั้ง unit test และ production code
แนวคิดหลักของ cycle นี้ก็คือ ไม่ให้คุณทำ 2 อย่างพร้อมกัน หรือ ทำงาน หรือ คิด ทีละอย่าง
เนื่องจากเป้าหมายในการพัฒนา software ก็คือ
ระบบต้องมีพฤติกรรมการทำงานที่ถูกต้อง
ระบบต้องมีโครงสร้างที่ดี และ ถูกต้อง
ดังนั้น Red-Green-Refactor (RGR) นั้น
ช่วยให้เรา focus ไปในการสร้าง software ให้มันทำงานได้ถูกต้องก่อน
และจากนั้นให้ทำการ focus ในเรื่องของโครงสร้าง
เพื่อทำให้โครงสร้าง software มันดี สำหรับการ maintain ต่อไปในอนาคต
ทางคุณ Kent Beck ได้อธิบายไว้ดังนี้ สำหรับการพัฒนา Software คือ
- Make it work
- Make it right
- Make it fast
หรือมีอีกแนวคิด ที่บอกว่า
Getting software to work is only half of the job.
มันหมายความว่า softwareท ที่คุณสร้างขึ้นมานั้น
มันต้องส่งมอบคุณค่าไปให้ลูกค้าด้วยนะ
สิ่งที่นักพัฒนามักจะลืมไปว่าใน Red-Green-Refactor มันมี Refactor ด้วย
ต้องทำการ refactor ไปแบบนาทีต่อนาที
ไม่ใช่ไปทำครั้งเดียวหลังจากที่จบการพัฒนา
ไม่มันไม่ใช่งานใน project plan ด้วยนะ
Refactoring มันคือ กิจกรรมที่เกิดขึ้นอยู่ตลอดเวลา
3. Milli-cycle หรือ Decaminute-by-Decaminute
คือรอบการทำงานละ 10 นาที โดยสิ่งที่เห็นการทำงานก็คือ The Specific/Generic cycle
อธิบายไว้ว่า
As the tests get more specific, The code get more generic.
นั่นคือชุดของ test นั้นจะโตขึ้นเรื่อยๆ
แต่ว่าในแต่ละ test จะเฉพาะเจาะจง มีเป้าหมายชัดเจนของตัวมัน (Specific)
มันจะกลายมาเป็นสิ่งที่ใช้อธิบายการทำงานของระบบ หรือ specification ต่อไป
โดยที่ production code ที่ได้จะต้อง generic หรือ อยู่ในรูปแบบทั่วไป ไม่ผูกติด
ซึ่งมันเป็นแนวทางการพัฒนา software ที่ดี
ปัญหาจาก Red-Green-Refactor ที่มักพบเจอก็คือ
มักจะแก้ปัญหาเฉพาะส่วนมากเกินไป
โดยที่ไม่สนใจภาพรวมของระบบเลย ว่ามันมีโครงสร้างที่ถูกต้องหรือไม่
ส่งผลให้เกิดปัญหาในการเขียน code เพื่อให้ test มันผ่าน
ซึ่งมันจะยากขึ้นเรื่อยๆ หรือใช้เวลามากว่ารอบการทำงาน
ส่งผลให้คุณเลิกพัฒนาตามแนวคิด TDD ไปเลย
โดยใน cycle นี้สามารถนำแนวคิด Transformation Priority Premise มาใช้
เพื่อไม่ให้ code ที่เขียนขึ้นมานั้นมันเฉพาะเจาะจงมากเกินไป
4. Primary-cycle หรือ Hour-by-Hour
เป็น cycle ที่ทำให้แน่ใจว่า cycle ต่างๆ นั้น
มันทำให้ software ที่เราสร้างมีโครงสร้างตามแนวคิด Clean Architecture
นั่นคือในทุกๆ ชั่วโมง เราจะต้องหยุด
และทำการตรวจสอบสิ่งที่พัฒนาขึ้นมาว่าเป็นอย่างไร
มีส่วนงานไหนที่มันผูกติดกันมากไป
มีส่วนงานไหนที่ควรต้องแยกออกจากกัน
ซึ่งสิ่งเหล่านี้ เรียกว่า Smell หรือ กลิ่นที่ไม่ดี
โดย Smell ต่างๆ มักจะพบเจอตั้งแต่ Milli-cycle แล้ว
เพื่อให้เห็นภาพรวมของระบบที่เราพัฒนา
ทั้งหมดนี้คือ cycle ต่างๆ ของ Test-Driven Development ที่เราต้องเข้าใจ