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

  • Unit test จะครอบคลุมไปที่ส่วนต่างๆ ของ code ทั้ง class และ method ต่างๆ รวมทั้งยังสามารถทำการ mock ส่วนต่างๆ ได้ด้วย
  • Integration test จะครอบคลุมการทำงานของ component ต่างๆ ว่าทำงานร่วมกันแล้วเป็นอย่างไร และสามารถนำ mock มาใช้สำหรับ component อื่นๆ ที่อยู่นอกเหนือการควบคุมได้
  • System test และ End-to-End test จะครอบคุลมส่วนที่ใหญ่กว่าขึ้นไปอีก

ถ้าถามว่า แต่ละการทดสอบต้องมีจำนวนมากเท่าไรล่ะ ?
คำถามนี้ Testing Pyramid ตอบได้ดีที่สุด ดังรูป

Test-pyramid

จากรูป Testing Pyramid อธิบายได้ง่ายๆ ก็คือ
จำนวนของ unit test > integration test > system test > end-to-end test
มีเหตุผลที่ฟังเข้าใจง่ายๆ ดังนี้

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

บางคนอาจจะมีคำถามว่า
ถ้า Unit test มันดีขนาดนี้แล้ว จะมีการทดสอบแบบอื่นๆ ไปทำไมล่ะ ?

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

รวมทั้ง การทดสอบในระดับที่สูงขึ้นไปนั้น
มักจะใช้เวลาในการทดสอบที่นานขึ้น
ดังนั้น ถ้ามีจำนวนการทดสอบมาก ก็ใช้เวลานาน
ส่งผลให้ได้ feedback ช้าเช่นกัน ซึ่งมันไม่ดีอย่างแน่นอน
ตัวอย่างแสดงดังรูป
testing-pyramid-fabio-pereira

แล้วการทดสอบมันมีคุณค่าอะไรบ้างล่ะ ?

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

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

คิดเล่นๆ ลองเปรียบเทียบระดับความเชื่อมั่นระหว่าง
การเห็น End-to-End test มันผ่านทั้งหมด กับ Unit test มันผ่านทั้งหมด
คุณจะมีความเชื่อมั่นต่อการทดสอบแบบใดมากกว่ากัน ?
เชื่อได้เลยว่าต้อง End-to-End test สิ เพราะว่า ระบบมันทำงานได้จริงๆ นะ

แต่เมื่อมีการเปลี่ยนแปลงที่ code แล้ว System test และ End-to-End test มันไม่ผ่านล่ะ ?
เมื่อเราไปดูที่ System test และ End-to-End test มันไม่ได้บอกอะไรเราเลย เช่น
Function การทำงานตรงไหนที่ผิด ?
มีปัญหาเรื่อง Environment หรือเปล่านะ ?
จุดไหนของการทำงานที่มันผิดนะ ?

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

มาถึงตรงนี้ อาจจะถามอีกว่า แล้วเราควรเขียนการทดสอบอะไรบ้างล่ะ ?

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

สุดท้ายขอให้จำไว้ว่า

System test ที่ผ่าน ทำให้เรามีความมั่นใจสูงขึ้น
แต่คุณค่าที่ได้จาก Unit test ที่ไม่ผ่าน มันมีมากกว่า System test ที่ไม่ผ่านมากมายครับ

วันนี้คุณทดสอบระบบงานอย่างไรกันบ้าง ?
อย่าบอกนะว่ายังทำ Manual test เป็นหลักกันอยู่ !!!