checklist
เมื่อเริ่มต้นเขียน test ขึ้นมานั้น
เราจะสนใจในเรื่อง scenario ที่ต้องการทดสอบ
จากนั้นก็ลงมือเขียน test นั้นขึ้นมา นั่นคือการให้ความสนใจในสิ่งที่เรากำลังทำทีละอย่าง
เนื่องจากเราไม่สามารถทำงานหรือการทดสอบหลายๆ งานพร้อมกันได้
ตัวอย่างเช่น แนวคิด Test Driven Development (TDD)
ทำให้เราค่อยๆ สร้าง test เพิ่มขึ้นมาเรื่อยๆ

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

1. มันสมเหตุสมผลหรือไม่

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

คำถามที่น่าสนใจก็คือ 
เราจะรู้ได้อย่างไรว่า test ที่สร้างมานั้นมันไม่ถูกต้องนะ หรือ ไม่สมเหตุสมผลนะ ?

คำตอบเกี่ยวกับเรื่องนี้มีวิธีการหาที่หลากหลาย เช่น
ทำการ review test โดยทีม
เราสามารถหาข้อผิดพลาดหรือ test ที่ไม่สมเหตุสมผล และทำการแก้ไขได้ง่าย
แต่สิ่งที่ยากก็คือ การไม่ทำให้มันเกิดขึ้นมาอีก
โดยสามารถแก้ไขด้วยการทำ pair programming เพื่อลดและหลีกเลี่ยงข้อผิดพลาด
และการเขียน test ที่ผิดหรือไม่สมเหตุสมผล
แต่ไม่ใช่การทำให้สิ่งที่ผิดพลาดหายไปนะ เพียงแต่ละลง
รวมทั้ง เรายังต้องการ feedback ที่รวดเร็ว ดังนั้นถ้าเรารู้ความผิดพลาดตั้งแต่แรกแล้ว
ก็จะทำให้เรารู้จักปัญหา และ หาทางแก้ไขปัญหาได้เร็วขึ้น

2. มันอ่านง่าย และเข้าใจง่าย หรือไม่

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

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

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

ถ้า test มันสามารถอ่านง่ายและเข้าใจได้ง่าย จะช่วยลดเวลาในการวิเคราะห์ปัญหาลงไปได้
เนื่องจากไม่ต้องไปทำวิธีในการวิเคราะห์ปัญหาที่เยอะหรือสิ้นเปลืองเกินไป เช่น การ debugging เป็นต้น

แต่คนที่นำแนวคิดนี้ไปใช้งาน มักคิดว่าจะทำให้ test มันดี และ ทุกๆ คนต้องเข้าใจมันได้อย่างดี
ทำให้เสียเวลาไปนั่งคิดกันนานมากๆ ซึ่งเป็นแนวคิดที่ผิดอย่างแรง
แต่สิ่งที่ขอแนะนำก็คือ พยายามทำให้ test นั้นทำงานให้ได้ก่อน
โดยก็ใช้ชื่อที่เราคิดว่าดีพอล่ะ แล้วสิ่งที่เราต้องทำต่อไปก็คือ การหา feedback ของ test แบบรวดเร็ว
ว่ามันเข้าใจง่ายหรือไม่ ด้วยวิธีการหาบุคคลที่สามมาช่วย review จะทำให้เราเห็นปัญหามากยิ่งขึ้น
หรือว่าใช้ pair programming มาร่วมด้วยก็จะดีขึ้นไปอีก

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

3. มันควรที่จะทำงานได้อย่างรวดเร็ว

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

แล้วจะทำอย่างไร เพื่อให้ได้ feedback ที่รวดเร็วล่ะ

  • การวิเคราะห์ เวลาการทดสอบในทุกๆ ครั้งว่าใช้เวลาเท่าไร เพื่อดูว่า test ใดที่ใช้เวลาการทดสอบนาน เพื่อทำการแก้ไขและปรับปรุง เช่น เปลี่ยนจากการทดสอบแบบ manual ไปเป็น automated
  • การวางโครงสร้างของ test เช่น ทำการแยก test ที่ทำงานช้าออกจาก test ที่ทำงานเร็ว
  • การปรับปรุง test ให้ดีขึ้น จากการวิเคราะห์และการจัดวางโครงสร้าง

โดยการทำงานที่รวดเร็ว ยังต้องมาพร้อมการทำงานที่ถูกต้อง ซึ่งนั่นคือความเชื่อมั่นนั่นเอง

4.  มันต้องทำงานได้อย่างถูกต้องเสมอ

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

ดังนั้น test ต้องยึดตามแนวคิด Single Responsibility Principle (SRP) คือ
ในแต่ละ test case ควรมีการตรวจสอบเพียงอย่างเดียวเสมอ
ส่งผลให้ test มันสั้น เล็ก ง่ายต่อการอ่าน และทำความเข้าใจ

แล้วจะเขียน test อย่างไรดีล่ะ

  • แต่ละ test มีการตรวจสอบเพียงเรื่องเดียว อย่างเดียว จริงๆ นะ
  • แต่ละ test ควรมีขั้นตอนการทำงานสั้นๆ
  • แต่ละ test ถ้ามีการใช้งานส่วนอื่นๆ ที่เราไม่สามารถควบคุมได้ ให้ทำการ mock ด้วยแนวคิด Test Double ซะ

5.  แบ่งกลุ่มของ test ซะ

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

เมื่อทำการจัดกลุ่มของ test แล้ว แนะนำให้เปลี่ยนชื่อ test ตามกลุ่มไปด้วย
รวมทั้งรายละเอียดของการทดสอบ ด้วยกิจกรรมการ Review และ pair programming

6. มันต้องดูแลรักษาได้ง่าย

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

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

แล้ว test ที่มันดูแลรักษาง่ายๆ เป็นอย่างไรล่ะ

  • เขียน test ใหม่มันง่ายง่าย และ เข้าใจได้ง่าย ทำให้เราดูเพียงผลลัพธ์ที่ออกมาก็เพียงพอ ที่จะไปแก้ไขปัญหาได้
  • แต่ละ test case ต้องทำการตรวจสอบเพียงอย่างเดียว
  • ต้องทำการแบ่งกลุ่มของ test

คุ้นๆ ไหมว่า ถ้าทำตามข้อ 1-5 แล้วมันจะทำให้ test มันดูแลรักษาได้ง่าย

7. ความน่าเชื่อถือ

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

ดังนั้น test ที่สร้างขึ้นมาจะต้องมีความน่าเชื่อถือเสมอ
ไม่เช่นนั้นความน่าเชื่อถือก็จะลดลงไป จนไม่เหลือในที่สุด

ดังนั้น เราจะทำให้ test มีความน่าเชื่อถือได้อย่างไรล่ะ

  • ก่อนที่จะเขียน test ให้ทำการเขียน test case ทั้งหมดขึ้นมาก่อน เพื่อที่จะทำให้รู้ว่ามันมีกี่ test case และเราจะทดสอบอะไรบ้าง หรือไม่ทดสอบอะไร
  • ทำการ review test อยู่เสมอ ทำงานแบบ pair programming ซึ่ง 4 ตาย่อมดีกว่า 2 ตานะเออ

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

สุดท้ายแล้ว

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

Reference Websites
How to test you tests ?