CI/CD Pipeline ของผมผ่านฉลุยมา 3 เดือน — จนกระทั่งผมได้อ่าน Log

เครื่องหมายถูกสีเขียวให้ความรู้สึกดี ทุก Pull Request ผ่านฉลุย ทุกการ Deploy ทำงานได้ปกติ

แล้วจู่ๆ ผู้ใช้ก็รายงานว่าฟีเจอร์หนึ่งพัง ซึ่งมันพังมาหลายสัปดาห์แล้ว

ผมเปิดดู Pipeline logs สิ่งที่ Build ผ่านมาตลอดนั้นกำลังหลอกเราอยู่

กระบวนการของเราดูเหมือนจะสมบูรณ์แบบ:

  • Linting
  • Unit tests
  • Integration tests
  • Build
  • Deploy

ทุกขั้นตอนมีอัตราความสำเร็จ 100% ติดต่อกันมาหลายเดือน

ปุ่ม Export ไม่ทำงานเลยเมื่อคลิก และไม่มี Error ใดๆ ปรากฏขึ้น ผมไล่ย้อนกลับไปจนพบว่ามันเกิดจากการเปลี่ยนแปลงเมื่อ 11 สัปดาห์ก่อน Pipeline ก็ผ่าน Code review ก็ได้รับอนุมัติ แต่ฟีเจอร์นี้พังมาตั้งแต่ต้นแล้ว

ปัญหาไม่ใช่ที่ Code ของเรา แต่มันอยู่ที่ Code ของ Test ต่างหาก

Integration tests ของเราใช้ Mock กับทุกอย่าง เรา Mock บริการ Export ทั้งหมด ผลคือ Test ไปตรวจสอบที่ตัว Mock แทนที่จะเป็น Code จริงๆ และตัว Mock ก็ส่งสถานะ Success กลับมาเสมอ

เราตกหลุมพรางของการทำ Over-mocking:

  • Unit tests: Mock ทุกอย่างเพื่อแยก Unit ออกมา ซึ่งแบบนี้ไม่เป็นไร
  • Integration tests: Mock ทุกอย่างเพื่อให้ทำงานเร็ว ซึ่งนี่คือความผิดพลาด
  • E2E tests: ข้าม Flow เฉพาะเจาะจงนี้ไป

Integration tests ของเราเป็นเพียง Unit tests ที่มีต้นทุนสูง พวกมันแค่ยืนยันว่า Mock ของเราทำงานได้ แต่ไม่ได้ยืนยันว่า Code ของเราทำงานได้จริง

ผมได้ทำการเปลี่ยนแปลง 3 อย่างเพื่อแก้ไขเรื่องนี้:

  1. จำกัดการใช้ Mock ไว้แค่ใน Unit tests เท่านั้น ส่วน Integration tests ต้องเชื่อมต่อกับ Database, API และ File system จริงๆ หาก Test ทำงานช้า อย่าพยายามซ่อนมันด้วยการใช้ Mock แต่ให้ใช้ความช้านั้นเป็นสัญญาณในการ Optimize แทน

  2. เพิ่ม Contract tests เพื่อให้แน่ใจว่า Mock ของคุณทำงานตรงกับพฤติกรรมของ Service จริง หาก Mock ส่งข้อมูลที่ Service จริงไม่มีทางส่งมา Contract test จะต้อง Fail

  3. ติดตาม Coverage ที่แท้จริง เราเลิกดูแค่ว่าผ่านกี่เปอร์เซ็นต์ แต่เราดูว่า Test ได้เข้าไปตรวจสอบส่วนไหนของ Code จริงๆ บ้าง ตัวเลข Coverage ของเราลดลงจาก 94% เหลือ 67% แต่นี่คือ Metric ที่ซื่อสัตย์ที่สุดที่เรามี

Pipeline สีเขียวไม่ได้แปลว่า Code ของคุณทำงานได้ แต่มันแปลว่า Test ของคุณผ่าน ซึ่งสองอย่างนี้ไม่เหมือนกัน

Bug ที่อันตรายที่สุดคือ Bug ที่ Pipeline บอกว่าไม่มีปัญหา

ลองถามตัวเองด้วยคำถามเหล่านี้:

  • Test ของผมกำลังดักจับ Bug หรือแค่ยืนยันว่า Mock ทำงานได้?
  • Integration tests ของผมได้ทำการ Integrate จริงๆ หรือเปล่า?
  • ถ้าผมเอา Mock ออกทั้งหมด จะยังมี Test กี่ตัวที่ผ่าน?
  • ผมกำลังวัด Coverage หรือวัดความมั่นใจ (Confidence)?

Pipeline ที่ไม่เคย Fail เลยไม่ใช่สิ่งที่เชื่อถือได้ แต่มันคือ Pipeline ที่ยังไม่ผ่านการทดสอบ

ที่มา: https://dev.to/kollittle/my-cicd-pipeline-passed-for-3-months-then-i-read-the-logs-4mbj