Mutation Testing สำหรับโค้ดที่เขียนโดย Agent

ชุดการทดสอบที่สร้างโดย LLM อาจมีค่า line และ branch coverage สูงถึง 100% แต่ผลการศึกษาล่าสุดพบว่าพวกมันทำคะแนนได้เพียง 4% ในการทำ Mutation Testing ซึ่งเผยให้เห็นถึงช่องว่างด้านความน่าเชื่อถือที่นักพัฒนาอาจมองข้ามไปในช่วงการรีวิวสปรินต์ (sprint reviews)

นักวิจัยได้ประเมินชุดการทดสอบที่สร้างโดย coding agents ของโมเดลภาษาขนาดใหญ่ (large-language-model) บนเกณฑ์มาตรฐาน HumanEval-Java โดยพบว่าชุดการทดสอบหนึ่งสามารถครอบคลุมโค้ดทุกบรรทัดและทดสอบทุกเงื่อนไข (conditional branch) ได้ครบถ้วน แต่เมื่อชุดการทดสอบเดียวกันนี้ต้องเผชิญกับการทำ Mutation Testing ซึ่งเป็นเทคนิคการฉีดข้อผิดพลาดเล็กๆ น้อยๆ เข้าไปเพื่อดูว่าการทดสอบจะตรวจพบหรือไม่ กลับพบว่ามันตรวจจับบั๊กที่ถูกฉีดเข้าไปได้เพียงส่วนน้อยเท่านั้น

Coverage ดูดี แต่ความหมายที่แท้จริงคืออะไร?

ตัวชี้วัด coverage แบบดั้งเดิมจะนับว่าการทดสอบนั้นรันคำสั่ง (statements) หรือเงื่อนไข (branches) ไปมากน้อยเพียงใด ทีมพัฒนาต่างๆ มักจะชอบตัวเลขที่ดูดีเหล่านี้ในการสาธิตสปรินต์ (sprint demos) อย่างไรก็ตาม ตัวชี้วัดนี้ไม่ได้บอกอะไรเลยว่าการทดสอบจะล้มเหลวหรือไม่หากโค้ดนั้นผิดพลาด Mutation Testing จึงเข้ามาเติมเต็มช่องว่างนี้ด้วยการจงใจสร้างข้อผิดพลาด (mutants) ขึ้นมา และวัดเปอร์เซ็นต์ของ mutants เหล่านั้นที่ทำให้การทดสอบล้มเหลว ซึ่งก็คือ "mutation score" นั่นเอง

ในการศึกษานี้ ชุดการทดสอบที่มี coverage 100% กลับพลาดการตรวจจับ mutants เกือบทั้งหมด รวมถึงข้อผิดพลาดทางตรรกะที่เรียบง่าย เช่น การจัดการวันที่ในปีอธิกสุรทิน (leap-year) ที่ผิดพลาด คะแนน mutation score ที่ 4% หมายความว่าชุดการทดสอบนี้จะตรวจพบเพียงบั๊กจริงๆ เพียงไม่กี่รายการเท่านั้น

ทำไมเรื่องนี้จึงสำคัญต่อการพัฒนาโดยใช้ AI ช่วยเหลือ

  • ความมั่นใจที่ผิดพลาด (False confidence): นักพัฒนาอาจเชื่อมั่นในชุดการทดสอบที่ดูสมบูรณ์แบบบนหน้ากระดาษ
  • ข้อบกพร่องที่ซ่อนอยู่ (Hidden defects): บั๊กจำนวนมากอาจหลุดรอดไปโดยไม่ถูกสังเกตเห็น
  • ต้นทุนในการแก้ไข (Remediation cost): การแก้ไขบั๊กในภายหลังมีต้นทุนสูงกว่าการตรวจพบตั้งแต่เนิ่นๆ มาก

มุมมองต่าง: Coverage ไม่ได้ไร้ประโยชน์

Coverage ยังคงบอกคุณได้ว่าเส้นทางการทำงานของโค้ด (code paths) ถูกรันหรือไม่ แต่มันไม่ได้การันตีว่าจะตรวจพบข้อผิดพลาดได้เสมอไป

สิ่งที่ควรจับตามองต่อไป

  • การรวมเข้ากับเครื่องมือ (Tooling integration): ฝัง Mutation Testing เข้าไปใน CI pipelines
  • การปรับปรุง LLM: ฝึกฝน agents ให้สร้างการทดสอบที่สามารถ "ฆ่า" mutants ได้
  • แนวทางปฏิบัติในอุตสาหกรรม: นำมาตรฐานที่ใช้คู่กันระหว่าง coverage และ mutation scores มาปรับใช้

บทสรุป: ตัวเลข coverage ที่สูงจากการทดสอบที่สร้างโดย AI ไม่ใช่ข้อพิสูจน์ของคุณภาพที่เพียงพออีกต่อไป คะแนน mutation score ที่ต่ำเป็นสัญญาณบ่งบอกว่าการทดสอบอาจไม่สามารถตรวจพบบั๊กที่เกิดขึ้นจริง ซึ่งเป็นการกระตุ้นให้นักพัฒนาควรนำ Mutation Testing มาใช้เป็นตาข่ายรองรับความปลอดภัย (safety net)