สารบัญคู่มือ · บทที่ 8 จาก 11
เทสต์: ให้เครื่องช่วยตรวจ
บทที่ 8 จาก 11 · อ่านราว 10 นาที · อัปเดต 9 ตุลาคม 2569 · ระดับเริ่มต้น
สรุปใน 3 บรรทัด
- เทสต์คือโค้ดที่ตรวจโค้ด บอกว่า "ถ้าทำแบบนี้ ต้องได้ผลแบบนี้"
- เขียนครั้งเดียว รันซ้ำได้ทุกครั้งในไม่กี่วินาที จึงจับได้เมื่อการแก้ครั้งใหม่ทำให้ของเดิมพัง
- ให้ agent เขียนเทสต์ได้ แต่เราต้องตรวจว่าเทสต์นั้นตรวจจริง วิธีที่ได้ผลที่สุดคือลองทำให้โค้ดพังแล้วดูว่าเทสต์ล้ม
ควรอ่านก่อน
บทที่ 7: ตรวจงานที่ agent ทำอ่านจบแล้วคุณจะ
- อธิบายได้ว่าเทสต์คืออะไร และทำไมสำคัญเมื่อทำงานกับ agent
- อ่านเทสต์ง่าย ๆ แล้วบอกได้ว่าตรวจอะไร
- สั่ง agent ให้เขียนเทสต์จากเกณฑ์รับงาน และตรวจว่าเทสต์ตรวจได้จริง
เทสต์คือการตรวจที่เครื่องทำแทนเรา
ใน บทที่ 7: ตรวจงานที่ agent ทำ เราตรวจงานด้วยการลองใช้จริงทีละข้อ วิธีนี้ได้ผล แต่เหนื่อย และเราไม่มีทางตรวจทุกอย่างซ้ำทุกครั้งที่ agent แก้งาน
ปัญหาคือ การแก้เรื่องใหม่มักทำให้เรื่องเก่าพังโดยไม่มีใครสังเกต เช่น แก้ปุ่มลบให้สวยขึ้น แต่ปุ่มเพิ่มกลับใช้ไม่ได้ เทสต์แก้ปัญหานี้ เพราะมันคือ checklist ที่เครื่องรันให้เองทุกครั้ง ในเวลาไม่กี่วินาที
หน้าตาของเทสต์
สมมติว่าโปรเจคจดสิ่งที่ต้องทำมีคำสั่งชื่อ addItem ที่รับรายการเดิมกับข้อความใหม่ แล้วคืนรายการใหม่ออกมา เทสต์ของมันอาจหน้าตาแบบนี้
test("เพิ่มรายการใหม่ต่อท้าย", () => {
expect(addItem(["ซื้อนม"], "ซื้อไข่")).toEqual(["ซื้อนม", "ซื้อไข่"]);
});
test("ไม่เพิ่มรายการที่มีแต่ช่องว่าง", () => {
expect(addItem(["ซื้อนม"], " ")).toEqual(["ซื้อนม"]);
});
อ่านได้แบบนี้
test("...")คือชื่อเทสต์ เขียนเป็นภาษาคนว่าตรวจอะไรexpect(...)คือสิ่งที่เกิดขึ้นจริงเมื่อเรียกใช้addItem.toEqual(...)คือผลที่ต้องได้ ถ้าไม่ตรง เทสต์จะล้มและบอกว่าต่างกันตรงไหน
เวลารันเทสต์ จะเห็นผลประมาณนี้
✓ เพิ่มรายการใหม่ต่อท้าย
✓ ไม่เพิ่มรายการที่มีแต่ช่องว่าง
Tests 2 passed
จากเกณฑ์รับงานเป็นเทสต์
ถ้าเขียนเกณฑ์รับงานดีตามบทที่ 6 แต่ละข้อแทบจะกลายเป็นเทสต์ได้ทันที
| เกณฑ์รับงาน | เทสต์ |
|---|---|
| พิมพ์แล้วกด Enter รายการใหม่ขึ้นด้านล่าง | เพิ่มรายการใหม่ต่อท้าย |
| ช่องว่างไม่สร้างรายการ | ไม่เพิ่มรายการที่มีแต่ช่องว่าง |
| ลบรายการหนึ่งแล้ว รายการอื่นยังอยู่ครบ | ลบรายการที่ 2 แล้วเหลือรายการที่ 1 และ 3 |
เกณฑ์ที่ตรวจไม่ได้ เช่น "ใช้งานง่าย" ก็เขียนเป็นเทสต์ไม่ได้เช่นกัน นี่เป็นอีกเหตุผลที่ต้องเขียนเกณฑ์ให้ตรวจได้
เทสต์ที่ตรวจไม่ได้จริง
เทสต์ที่ผ่านทุกตัวไม่ได้แปลว่าโค้ดถูกเสมอ บางครั้งเทสต์เองที่ไม่ได้ตรวจอะไร สัญญาณที่พบบ่อย
- เทสต์ที่ไม่มี
expectเลย รันผ่านเสมอไม่ว่าโค้ดจะเป็นอย่างไร - เทสต์ที่ถูกปิดไว้ด้วย
test.skipจะไม่ถูกรันเลย - เทสต์ที่ agent แก้ผลที่ต้องได้ให้ตรงกับผลที่ผิด เพื่อให้ผ่าน
วิธีตรวจที่ได้ผลที่สุดคือ ลองทำให้โค้ดพังชั่วคราว แล้วดูว่าเทสต์ล้ม เช่น ลบเงื่อนไขที่กันรายการว่างออก ถ้าเทสต์ "ไม่เพิ่มรายการที่มีแต่ช่องว่าง" ยังผ่านอยู่ แปลว่าเทสต์นั้นไม่ได้ตรวจจริง จากนั้นอย่าลืมคืนโค้ดเดิม
ให้ agent เขียนเทสต์
agent เขียนเทสต์ได้เร็วมาก แต่ให้แยกงานเขียนเทสต์ออกจากงานแก้โค้ด และขอหลักฐานว่าเทสต์ตรวจได้จริง
เขียนเทสต์สำหรับคำสั่ง addItem ตามเกณฑ์รับงานนี้ ข้อละหนึ่งเทสต์: - เพิ่มรายการใหม่ต่อท้าย - ไม่เพิ่มรายการที่มีแต่ช่องว่าง ขอบเขต: - ตั้งชื่อเทสต์เป็นภาษาไทยตามเกณฑ์แต่ละข้อ - ห้ามแก้โค้ดของ addItem ในงานนี้ - ห้ามใช้ test.skip หลังเขียนเสร็จ: 1. รันเทสต์และแสดงผล 2. ลองทำให้ addItem พังชั่วคราวทีละเงื่อนไข แสดงว่าเทสต์ที่เกี่ยวข้องล้ม 3. คืนโค้ดเดิม แล้วรันเทสต์อีกครั้งให้เห็นว่าผ่าน
ตรวจผลยังไง
เทสต์มีหลายระดับ
| ระดับ | ตรวจอะไร | ความเร็ว |
|---|---|---|
| Unit test | คำสั่งเดียว หรือส่วนเล็ก ๆ ส่วนเดียว | เร็วมาก |
| Integration test | หลายส่วนทำงานร่วมกัน เช่น กับฐานข้อมูลจริง | ปานกลาง |
| End-to-end test | เปิดเบราว์เซอร์แล้วกดเหมือนคนใช้จริง | ช้าที่สุด แต่ใกล้ความจริงที่สุด |
โปรเจคจริงมักมี unit test จำนวนมาก และ end-to-end test เฉพาะเส้นทางสำคัญ เช่น การสมัครและการซื้อ เทสต์ทั้งหมดถูกรันอัตโนมัติทุกครั้งที่มีคนส่งงาน เรื่องนี้อยู่ใน บทที่ 11: เอางานขึ้นเว็บจริง
ข้อผิดพลาดที่พบบ่อย
- ให้ agent แก้โค้ดและแก้เทสต์ในงานเดียวกัน ถ้าโค้ดผิด agent อาจแก้เทสต์ให้ผิดตามจนผ่าน
- เชื่อว่าเทสต์ผ่านแปลว่าถูก ต้องตรวจด้วยว่าเทสต์ตรวจสิ่งที่ถูก
- ยอมให้ลบหรือปิดเทสต์ที่ล้ม เทสต์ที่ล้มคือข้อมูล ให้หาสาเหตุก่อนเสมอ
- ไม่รันเทสต์ก่อนส่งงาน เทสต์มีค่าก็ต่อเมื่อถูกรัน
เช็กความเข้าใจ
1. หลัง agent แก้งาน เทสต์ผ่านทุกตัว แต่ agent ลบเทสต์ที่เคยล้มไป 2 ตัว แปลว่าอะไร
2. วิธีไหนบอกได้ดีที่สุดว่าเทสต์ตรวจได้จริง