ซีรีส์ QA ใช้ AI ทำงาน · ตอนที่ 6 จาก 7
Test ผ่านทุกข้อ แต่ร้านยังคิดเงินผิด: ตรวจ Test ที่ AI เขียนอย่างไร
17 ต.ค. 2569 · อ่าน 8 นาที
เราให้ AI เขียน Unit Test ให้ส่วนคิดเงินของร้านค้าจำลองที่มีบั๊ก ได้มา 35 ข้อ ไม่มีข้อไหนไม่ผ่านเลย เพราะบางข้อถูกพักไว้ และบางข้อเขียนตามสิ่งที่โค้ดทำ ไม่ใช่สิ่งที่ควรเป็น ตอนที่ 6 ของซีรีส์ QA ใช้ AI ทำงาน เทียบ Test 3 ชุด และลองทำให้โค้ดผิดทีละบรรทัดเพื่อดูว่า Test จับได้หรือไม่ พร้อมเช็กลิสต์ 5 ข้อและคำสั่งสำเร็จรูป

ตอนที่ 6 ของซีรีส์ "QA ใช้ AI ทำงาน" ตอนนี้ว่าด้วยเรื่องที่ QA และ Dev ที่ใช้ AI เขียน Test น่าจะได้เจอ คือ Test ที่ AI เขียนให้
Test ที่ผ่าน (เขียว) เต็มจอดูน่าอุ่นใจ แต่ Test ผ่านแปลว่าโค้ดทำตามที่ Test ตรวจ ถ้า Test ตรวจผิดเรื่อง หรือไม่ได้ตรวจอะไรเลย สีเขียวก็ไม่ได้บอกอะไร
ข้อมูล ณ ตุลาคม 2569 เราลองกับ Claude ครั้งละ 1 รอบ แล้วรัน Test จริงด้วย Node.js 23 กับส่วนคิดเงินของร้านกาแฟตัวอย่าง (ร้านสมมติ) ที่เราสร้างไว้ทดสอบ
ส่วนคิดเงินของร้านมีบั๊กเรื่องเงิน 3 ตัว
ส่วนคิดเงินของร้านมีบั๊กที่เราตั้งใจใส่ไว้ 3 ตัว
- ยอดเท่าขั้นต่ำพอดีใช้โค้ดไม่ได้ ยอด 500 บาทพอดีใส่ SAVE10 แล้วร้านบอกว่ายอดไม่ถึงขั้นต่ำ
- ส่งฟรีคิดจากยอดก่อนหักส่วนลด Requirement บอกให้ดูยอดหลังหักส่วนลด ยอด 1,050 บาทใช้ SAVE10 แล้วเหลือ 950 บาท ต้องเสียค่าส่ง แต่ร้านให้ส่งฟรี
- แก้ตะกร้าหลังใส่โค้ดแล้ว ส่วนลดยังอยู่ ข้อนี้ Requirement ไม่ได้บอกตรงๆ ว่าต้องตรวจเงื่อนไขใหม่
Test ที่ดีควรไม่ผ่าน (แดง) อย่างน้อยใน 2 ข้อแรก
Test 3 ชุดที่ได้ผลต่างกันมาก
เราให้ Claude เขียน Test 3 แบบ แล้วรันกับโค้ดเดียวกัน ผลเป็นดังนี้
| ชุด | สั่งว่าอะไร | ผลรัน |
|---|---|---|
| A | ให้แค่โค้ด "ช่วยเขียน unit test ให้หน่อย" | 35 ข้อ ผ่าน 30 พักไว้ 5 ไม่มีข้อไหนแดง |
| B | ให้โค้ดกับ Requirement คำสั่งเดิม | 26 ข้อ แดง 4 (บั๊ก 2 ตัวแรก) พักไว้ 2 |
| C | ให้โค้ดกับ Requirement พร้อมกติกา 5 ข้อ (คำสั่งท้ายบทความ) | 51 ข้อ แดง 5 (บั๊ก 2 ตัวแรก) ไม่มีข้อที่พักไว้ |
ชุด A น่าสนใจที่สุด เพราะ Claude เห็นบั๊ก ระหว่างอ่านโค้ด และเขียนไว้เองว่า "เจอพฤติกรรมที่น่าจะเป็นบั๊ก 3 จุด" แต่เลือกติดป้าย todo ไว้ Test ที่ติดป้ายนี้ยังรันอยู่ แต่ไม่ทำให้ทั้งชุดไม่ผ่าน คนที่ดูแค่ว่าผ่านหรือไม่จะเห็นแต่สีเขียว
ชุด A ยังมีอีกข้อหนึ่งชื่อว่า "เกณฑ์ส่งฟรีใช้ยอดก่อนหักส่วนลด" ข้อนี้ เขียนบั๊กให้กลายเป็นสิ่งที่ถูก เพราะผลลัพธ์ที่คาดหวัง (Expected Result) มาจากการอ่านโค้ด ไม่ได้มาจาก Requirement Claude ไม่ได้ซ่อนเรื่องนี้ โดยเขียนไว้ท้ายคำตอบว่าควรถามเจ้าของร้าน แต่ตัว Test ผ่านไปแล้ว
ระหว่างอ่านโค้ด ชุด A ยังเจอบั๊กที่เราไม่ได้ตั้งใจใส่ด้วย คือเมื่อพิมพ์โค้ดว่า constructor ร้านตอบว่า "ยอดสินค้าขั้นต่ำ undefined บาท" เราลองแล้วเกิดจริง แต่ข้อนี้ก็ถูกพักไว้เหมือนกัน
ลองทำให้โค้ดผิด เพื่อดูว่า Test จับได้หรือไม่
จะรู้ได้อย่างไรว่า Test ตรวจจริง วิธีที่ง่ายที่สุดคือลองทำให้โค้ดผิดทีละจุด แล้วดูว่า Test ไม่ผ่านหรือไม่ แนวคิดนี้เรียกว่า Mutation Testing ซึ่งมีเครื่องมือที่ทำให้อัตโนมัติ แต่ทำด้วยมือแบบนี้ก็เห็นภาพแล้ว
เราเริ่มจากโค้ดที่แก้บั๊ก 2 ตัวแรกแล้ว (ถูกตาม Requirement) จากนั้นเปลี่ยนทีละบรรทัด ผลเป็นดังนี้
| เปลี่ยนอะไรในโค้ด | ชุด A | ชุด C |
|---|---|---|
| ตัดเพดานส่วนลด 100 บาท | จับได้ | จับได้ |
| ลบบรรทัดที่ทำให้ FREESHIP ส่งฟรี | จับได้ | จับได้ |
| ลบการเช็กวันหมดอายุ | จับได้ | จับได้ |
| เปลี่ยนส่วนลดเป็น 5% | จับได้ | จับได้ |
| ใส่บั๊กส่งฟรีกลับเข้าไป | กลับเป็นสีเขียว | จับได้ |
| ใส่บั๊กขั้นต่ำกลับเข้าไป | ไม่รู้ตัว | จับได้ |
ชุด A ไม่ได้ไร้ประโยชน์ เพราะจับได้เมื่อโค้ดเปลี่ยนไปจากเดิม แต่จับไม่ได้ว่าโค้ดผิดมาตั้งแต่แรก ที่แย่กว่านั้นคือ เมื่อเราแก้บั๊กส่งฟรีให้ถูก ชุด A กลับไม่ผ่าน 2 ข้อ ถ้าคนแก้ไม่รู้ว่า Test ผิด อาจแก้ Test ให้ผ่าน ซึ่งเท่ากับใส่บั๊กกลับเข้าไป
Test ที่ไม่ได้ตรวจอะไรมีหลายหน้าตา
Martin Fowler เล่าเรื่องโปรเจกต์ที่บังคับให้ทุกเมธอดต้องมี Test แล้วโชว์ลูกค้าว่าเขียวทั้งแถบ แต่ Test ทั้งหมด ไม่มี Assertion เลย และชี้ว่าแบบนี้ก็ทำ Code Coverage ได้ 100% ในการทดลองของเรา Claude ใส่ Assertion ทุกข้อ แต่เราเจอแบบที่ใกล้เคียงกัน ดังนี้
- พักไว้ ติด
todoหรือskipแล้วชุด Test ยังเขียว - ตรวจตามโค้ด Expected Result มาจากสิ่งที่โค้ดทำ บั๊กจึงกลายเป็นสิ่งที่ถูก
- ตรวจแค่ว่ามีค่า เช่น ชุด B ตรวจว่ามีข้อความเหตุผล "ยาวกว่า 0 ตัวอักษร" ข้อความผิดเรื่องก็ยังผ่าน
- แก้ Test ให้ผ่าน เมื่อโค้ดถูกแต่ Test ผิด หรือเมื่อโค้ดผิดแต่อยากให้เขียว
เช็กลิสต์ 5 ข้อก่อนเชื่อ Test ที่ AI เขียน
- Expected Result มาจาก Requirement ชื่อ Test ควรบอกได้ว่ามาจากข้อไหน ถ้าตอบไม่ได้ อาจมาจากการอ่านโค้ด
- นับข้อที่พักไว้ ค้นคำว่า
todoและskipทุกครั้ง แต่ละข้อคือบั๊กหรือคำถามที่ยังไม่มีคนตอบ - ทุก Test ตรวจค่าที่ควรได้จริง ไม่ใช่ตรวจแค่ว่ามีค่า ไม่ error หรือยาวกว่า 0
- ค่าขอบครบ ทั้งค่าที่เท่ากับขอบพอดีและค่าข้างๆ ชุด A ไม่มี Test ยอด 500 พอดีที่ไม่ถูกพักไว้
- ลองทำให้โค้ดผิด 1 จุด แก้บรรทัดสำคัญให้ผิด รัน Test แล้วเปลี่ยนกลับ ถ้ายังเขียว แปลว่า Test ไม่ได้ตรวจจุดนั้น
อีกเรื่องที่ไม่ใช่ข้อตรวจ แต่ต้องเป็นนิสัยของทีม คือ ห้ามแก้ ปิด หรือข้าม Test เพื่อให้ผ่าน เรื่องนี้เราเล่าไว้ใน เมื่อ AI เขียนโค้ดแทนเป็นส่วนใหญ่: 3 ทีมจริงเจออะไร
คำสั่งสำเร็จรูป: ให้ AI เขียน Test จาก Requirement
คำสั่งนี้มาจากคำสั่งที่ใช้กับชุด C โดยเราเปลี่ยนส่วนที่เป็นข้อมูลร้านเป็นช่องว่างให้เติม และตัดบรรทัดที่กำหนดรูปแบบไฟล์ที่ตอบออก 1 บรรทัด
นี่คือ requirement ของ [ระบบ / ฟีเจอร์] และโค้ดที่ต้องทดสอบ ช่วยเขียน unit test ด้วย [เครื่องมือ เช่น node:test / Jest / pytest] กติกา - ผลที่คาดหวังทุกข้อต้องมาจาก requirement ไม่ใช่จากสิ่งที่โค้ดทำอยู่ ใส่หมายเลขข้อ requirement ไว้ในชื่อ test - ถ้าโค้ดทำต่างจาก requirement ให้เขียน test ตาม requirement แล้วปล่อยให้ fail ห้ามใช้ todo หรือ skip ซ่อนไว้ แล้วสรุปท้ายคำตอบว่าข้อไหนน่าจะ fail เพราะอะไร - ถ้า requirement ไม่ได้บอกว่าต้องเป็นยังไง ไม่ต้องเขียน test เดาเอง ให้แยกเป็นรายการคำถามท้ายคำตอบ - ทุกเงื่อนไขที่มีตัวเลขขั้นต่ำหรือเพดาน ให้ทดสอบทั้งค่าที่เท่ากับขอบพอดี และค่าที่อยู่ข้างๆ ขอบ - ทุก test ต้องตรวจค่าที่ควรได้จริง ไม่ใช่แค่ตรวจว่ามีค่า หรือไม่ error ## requirement """ [วาง requirement] """ ## โค้ด """ [วางโค้ด] """
ทำไมได้ผล: บรรทัดแรกของกติกาตัดปัญหา "ตรวจตามโค้ด" การห้าม todo และ skip ทำให้บั๊กปรากฏเป็นสีแดง และการแยกคำถามออกมาทำให้เรื่องที่ Requirement ไม่ได้บอกไปถึง PO แทนที่จะกลายเป็น Test ที่เดาเอา ในการทดลอง คำถามข้อ 2 ที่ Claude ตั้งมาคือเรื่องแก้ตะกร้าหลังใส่โค้ด ซึ่งก็คือบั๊กตัวที่ 3
สรุป
Test ที่ผ่าน (เขียว) บอกแค่ว่าโค้ดทำตามที่ Test ตรวจ งานของ QA คือดูว่า Test ตรวจถูกเรื่องหรือไม่ โดยใช้ Requirement เป็นต้นทาง นับข้อที่พักไว้ และลองทำให้โค้ดผิดดูสักจุด
ตอนสุดท้ายของซีรีส์ เราจะให้ AI เขียน Automated Test ที่กดหน้าเว็บจริง แล้วดูว่า Test ไม่ผ่านเพราะบั๊ก หรือเพราะหาปุ่มไม่เจอ
อาทิตย์ละสกิล เดี๋ยวก็เก่ง