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

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

ทั้งเรื่องของ timing หรือเวลาในการเขียน test หรือเวลาในการทดสอบ
ทั้งทำหลังจากที่ระบบงานเสร็จสิ้น (Test-Last)
ทั้งทำก่อนจะเริ่มลงมือพัฒนา (Test-First)

ถ้าไปเจอ Legacy code ละ จะทำอย่างไร ?
เขียนและทดสอบกันอย่างไร ?

ถ้าไปเจอกับทีมที่ไม่เขียน test ละทำอย่างไร ?

ถ้าไปเจอ business ที่เปลี่ยนแปลงเร็วมาก ๆ จะทำอย่างไร ?

เนื่องด้วยบริบทหรือ domain มันหลากหลายมาก ๆ

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

ถ้าเริ่มเขียน test แรก ๆ

ผมก็จะเขียนมันไปให้หมด ไม่เชื่อมั่นอะไรก็เขียนมันไป
เขียนมากจนกลับมาดู
ยังด่าตัวเองว่า Test แบบนี้เขียนไปทำซากอะไร !!

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

แต่ถ้ายังไม่เคยทำ ก็ให้ทำก่อน อย่าเพิ่งไปเชื่อคำพูดของคนอื่น ๆ

โดย test ต่าง ๆ มักจะมาจาก acceptance criteria ของแต่ละ feature/flow ที่คุยกันไว้

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

อีกอย่างถ้าเรามี acceptance criteria แล้ว
เราต้องทำการแบ่งปัญหาใหญ่เป็นปัญหาเล็ก ๆ (Work breakdown)
เพื่อค่อย ๆ แก้ไขไป 
ตรงนี้เป็นความสามารถที่ต้องฝึกอย่างมาก
ถ้าเราไม่สามารถแยกได้แล้ว เราจะแก้ไขปัญหาได้ยากมาก ๆ หรืออาจจะออกทะเลได้ง่าย ๆ

ต่อมาในการเขียน test นั้น

จะมีหลาย level อีก ซึ่งแต่ละ level
นั้นก็เป็นเรื่อง ของความเชื่อมัน ของความไว้เนื้อเชื่อใจ
ทั้ง End-to-End testing สำหรับ UI
ทั้ง End-to-End testing สำหรับ API
ทั้ง Contract, Component test
ทั้ง Integration test
ทั้ง Unit test


จะทดสอบใน level ไหน ตรงนี้ผมคิดว่ามันมี trade-off ทั้งหมด
จะมาวางแนวทางกัน เพราะว่า มันไม่ใช่แค่การ test เพียงอย่างเดียว

หลัก ๆ ที่จะทดสอบมาก ๆ หรือละเอียดสุด ๆ คือ
ส่วนงาน business logic ที่มีความสำคัญและซับซ้อน
ในส่วนนี้จะพยายามตัดควบคุม dependency ให้ได้มากที่สุด
เพื่อทดสอบการทำงานว่า
เป็นไปตามเงื่อนไขที่กำหนดหรือไม่ ทั้งเหตุการณ์ดีและแย่

เพียงแค่การทดสอบอย่างเดียวไม่พอ !!

เรื่องของ environment ของการทดสอบก็สำคัญ
ว่าคล้ายหรือเหมือนจริงหรือไม่ ?
เพราะว่า ผมมักจะเจอว่าเรามี environment ต่าง ๆ เยอะมาก
ทั้ง dev, test, QA, SUT, SAT, UAT, Staging, Pre prod 
แน่นอนว่า ทดสอบผ่านมาทั้งหมด !!
แต่เมื่อขึ้น Production เมื่อใด มีปัญหาเมื่อนั้น ใช่หรือไม่ ?

รวมไปถึงเรื่องของ Monitoring system หรือพวก Observability ของระบบ
ทั้งค่าในเชิงตัวเลข หรือ metric ของระบบงาน
ไม่ใช่ตัวเลขทาง infrastructure เท่านั้น มีหรือไม่

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

เป้าหมายหลัก ๆ ของการทดสอบคือ

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

สุดท้ายต้องเข้าใจสิ่งที่กำลังจะทำก่อนเสมอ

เครื่องไม้เครื่องมือที่ใช้ก็ต้องคล่องมือด้วย
ตลอดจนทีมและ environment ต่าง ๆ ก็ต้องสนับสนุนเช่นกัน