ระหว่างนั่งเตรียมเรื่องการเขียน Automated Tests สำหรับการทดสอบระบบงาน
มีเรื่องหนึ่งที่น่าสนใจมาก ๆ คือ
ในการเขียน Unit test นั้นมีแนวทางที่ดีอะไรบ้าง
ที่จะทำให้เราเขียนได้ดีขึ้น
จึงทำการสรุปไว้ 3 เรื่องง่าย ๆ ดังนี้

เรื่องที่ 1 ในแต่ละ test case ให้ทดสอบเรื่องเดียว

ตามแนวคิดของ Single Responsibility Principle (SRP) มันสำคัญมาก ๆ
นั่นคือแต่ละ test case ควรตรวจสอบเรื่องเดียว เป้าหมายเดียว
แต่ไม่ใช่บอกว่ามีการ assert เพียงบรรทัดเดียวนะ !!

เพราะว่า ถ้ามีการทดสอบในหลาย ๆ เรื่องพร้อมกันใน test case เดียวแล้ว
ปัญหาที่ตามมาคือ ความงง ความซับซ้อน ดูแลรักษายากมาก ๆ
ดังนั้นในแต่ละ test case ต้องเฉพาะเจาะจงไปเลย
ว่าต้องการจะทดสอบอะไร
ถ้ามีหลายเรื่องก็ให้แยกเป็นเรื่องย่อย ๆ 
จากนั้นจึงแยกออกเป็น test case ไปซะ

อย่าลืมว่า คิดก่อนทำนะ
เราคิดอย่างไร ก็จะทำเช่นนั้น

เรื่องที่ 2 ตั้งชื่อ test case ให้ดี เข้าใจและอ่านได้ง่าย

ชื่อนั้นสำคัญไฉน ?
ชื่อของ test case มันเป็นสิ่งที่บอกว่า
เราต้องการจะทำอะไร
ทดสอบอะไร
คาดหวังอะไร

เป็นการบอกว่า เรานั้นเข้าใจปัญหาที่ต้องการทดสอบ
หรือเราเข้าใจปัญหาที่ต้องการแก้ไขหรือไม่นั่นเอง !!

ยกตัวอย่างของชื่อ test case ที่ไม่ดี
testcaseTBD00001
testcaseTBD00002
testcaseTBD00003 …

คำถามคือ test case เหล่านี้ทำอะไร
ทดสอบอะไร คาดหวังอะไร
เมื่อมีปัญหาเช่น ทดสอบไม่ผ่าน
เราจะรู้ได้อย่างไรว่าเกิดจากปัญหาอะไรได้บ้าง ​?

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

  • ตั้งชื่อตาม business case ไปเลย ดังนั้นก่อนพัฒนาหรือทดสอบต้องมี test case รอไว้แล้ว
  • ตั้งชื่อตามรูปแบบ ชื่อ function + action + ผลที่คาดหวัง
  • ตั้งชื่อตามรูปแบบ ชื่อระบบ + action + ผลที่คาดหวัง

อย่าลืมว่า ชื่อ test case ต้องสัมพันธ์กับสิ่งที่อยู่ใน test case ด้วยนะ
ไม่ใช่ชื่อไปทาง การทดสอบจริง ๆ ไปอีกทาง แบบนี้ก็ไม่ไหว

เรื่องที่ 3 โครงสร้างของ test case ก็สำคัญเช่นกัน

มีเป้าหมายที่ชัดเจนแล้ว มีชื่อที่ดีแล้ว
ต่อมาก็เป็นเรื่องของโครงสร้างภายใน test case ซึ่งมีหลายรูปแบบ
หนึ่งในนั้นที่ผมชอบใช้คือ AAA (Arrange, Act, Assert)

  • Arrange สำหรับการกำหนดค่าหรือสถานะเริ่มต้น เช่นการ mock/fake/stub สิ่งต่าง ๆ ที่ต้องใช้งาน
  • Act สำหรับการเรียก function หรือพฤติกรรมต่าง ๆ ที่ต้องการทดสอบ
  • Assert สำหรับการตรวจสอบผลการทำงานจริง ๆ กับสิ่งที่คาดหวัง ว่าตรงตามที่หวังหรือไม่

ผลที่ได้จากการมีโครงสร้างที่ดีคือ
ทุกคนในทีมจะมีแนวทางเดียวกัน
ทำให้คุยกันได้ง่าย
ทำให้ดูแลรักษาได้ง่ายขึ้น

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

สุดท้ายลงมือทำครับ

Make it Work => เรียนรู้ ลงมือทำให้มากที่สุด 
Make it Right => เรียนรู้ ในสิ่งที่ถูกและผิด แนะนำให้เรียนจากสิ่งที่ผิดแล้วทำการปรับปรุง Make it Fast => เรียนรู้ ปรับปรุงการเขียนและการทดสอบให้เร็ว เพื่อทำให้ได้รับ feedback ที่เร็วและดี

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