SE บทที่ 6 — ทดสอบก่อนเชื่อโค้ดที่ AI เขียน · ชิมก่อนเสิร์ฟทุกจาน
ใช้ปุ่ม ← → เปลี่ยนสไลด์ได้SE TRACK — MODULE 6 · TESTING
ทดสอบก่อนเชื่อโค้ดที่ AI เขียน
AI ทำงานเสร็จแล้วมักรายงานว่า "All tests pass ✓ — the feature is complete" — ฟังดูน่าวางใจมาก แต่ถ้าเราไม่รู้ว่า "tests" ที่ว่าคืออะไร ตรวจอะไรไปบ้าง เราก็กำลังรับงานเพียงเพราะคนทำบอกว่าเสร็จ บทนี้สอนให้อ่านรายงานผลทดสอบของ AI ออก และรู้ว่าต้องถามอะไรกลับก่อนกดรับงาน
กับดักที่เจ็บที่สุดของคนคุม AI: "โค้ดดูเหมือนถูก" ไม่เท่ากับ "โค้ดถูก" — โค้ดที่อ่านแล้วสวยงามและ AI ยืนยันว่าเสร็จ ยังพังต่อหน้าลูกค้าได้ ถ้าไม่มีการชิมก่อนเสิร์ฟ
ทำไมต้องรู้
ร้านอาหารไม่เสิร์ฟโดยไม่ชิม — ซอฟต์แวร์ก็เหมือนกัน
01AI มั่นใจเสมอ แม้ตอนผิด
- AI รายงานว่า "เสร็จแล้ว" ด้วยน้ำเสียงเดียวกัน ทั้งตอนงานดีและตอนงานมีจุดพัง
- คำว่า "done" ของ AI = "ผมเขียนเสร็จแล้ว" ไม่ใช่ "พิสูจน์แล้วว่าถูก"
02ลูกค้าคือคนเจอ bug ถ้าเราไม่เจอก่อน
- ระบบสั่งซื้อหน้าร้านออนไลน์ที่คิดส่วนลดผิด — กว่าจะรู้ก็ตอนลูกค้าทักมาโวย
- ค่าเสียหายของ bug ที่หลุดถึงลูกค้า แพงกว่าเวลาที่ใช้ทดสอบเสมอ
03เราไม่ต้องชิมเอง แต่ต้องสั่งให้ชิม
- AI เขียนชุดทดสอบให้ได้ และรันให้ดูได้ — หน้าที่เราคือสั่งให้มันชิม และอ่านผลชิมออก
- ศัพท์ในบทนี้คือภาษาที่ใช้สั่งและอ่านผลนั้น
MENTAL MODEL ประจำบท
"โค้ดดูเหมือนถูก" ≠ "โค้ดถูก" — เชื่อผลชิม อย่าเชื่อคำพูดคนทำ
Analogy หลักของบท · Test Pyramid
ชิมก่อนเสิร์ฟ 3 ระดับ — จากวัตถุดิบ ถึงนั่งกินจริง
ทดสอบชิ้นเล็กสุดแยกส่วน เช่น "ฟังก์ชันคิดส่วนลดคิดถูกไหม" — เร็ว ราคาถูก รันได้ทีละร้อยข้อ
ทดสอบหลายส่วนทำงานร่วมกัน เช่น "กดสั่งซื้อแล้ว ยอดในระบบสต๊อกลดจริงไหม"
ไล่ทั้ง workflow ตั้งแต่เข้าร้านยันจ่ายเงิน — เข้าเว็บ เลือกสินค้า ใส่ตะกร้า จ่ายเงิน ได้ใบยืนยัน
หลักการ Test Pyramid: ชิมวัตถุดิบ (unit) ให้เยอะที่สุดเพราะเร็วและชี้จุดผิดแม่น · นั่งกินทั้งมื้อ (E2E) ให้น้อยแต่ครอบคลุมเส้นทางสำคัญเพราะช้าและแพง — AI รู้หลักนี้อยู่แล้ว เราแค่ต้องอ่านออกว่ามันชิมระดับไหนไปบ้าง
ศัพท์ชุดที่ 1 · 6 คำ
ศัพท์ฝั่ง "ผลการชิม" — อ่านรายงานเทสให้ออก
BUG · DEFECTรสชาติผิดจากที่สั่ง
- ระบบทำงานไม่ตรงกับที่ตกลงกันไว้ (requirement — บท SE1)
- AI: "I found a bug in the discount logic"
TEST CASEโจทย์ชิม 1 ข้อ
- กำหนดชัด: ป้อนอะไรเข้าไป (input) → ต้องได้อะไรออกมา (expected result)
- เช่น "ซื้อครบ 500 ต้องได้ส่วนลด 10%"
REGRESSION TESTเมนูใหม่ต้องไม่ทำเมนูเก่าเสียรส
- รันเทสเก่าทั้งชุดซ้ำ เพื่อยืนยันว่าของใหม่ไม่พังของเดิม
- AI: "running the full suite to check for regressions"
SMOKE TESTชิมเร็ว ๆ ว่าครัวยังเปิดอยู่
- เช็คฟังก์ชันสำคัญแบบกว้างและไว หลังติดตั้งของใหม่ — เปิดเว็บติดไหม กดสั่งซื้อได้ไหม
- ผ่าน smoke ≠ ผ่านทุกอย่าง แค่ "ไม่พังโครม ๆ"
FLAKY TESTลิ้นเพี้ยน เดี๋ยวผ่านเดี๋ยวไม่ผ่าน
- เทสที่ผลไม่นิ่งทั้งที่โค้ดไม่ได้เปลี่ยน — เชื่อผลไม่ได้ ต้องแก้ ไม่ใช่ลบ
- AI: "this test is flaky"
TEST COVERAGEชิมครบกี่ % ของเมนู
- สัดส่วนโค้ดที่เทสวิ่งผ่าน — วัดว่าชิมครบ ไม่ได้วัดว่าชิมเป็น
- Coverage สูง ≠ อร่อย — เทสห่วย 100 ข้อก็ดันตัวเลขขึ้นได้
ตัวอย่างจริง: AI แก้สูตรค่าส่งใน LINE OA shop แล้วรัน regression — เจอว่าเทสเก่าเรื่อง "ส่งฟรีเมื่อครบ 1,000" พัง แปลว่าของใหม่ไปทับสูตรเดิม ดีที่รู้ก่อนลูกค้ารู้
ศัพท์ชุดที่ 2 · 6 คำ
ศัพท์ฝั่ง "ด่านตรวจคุณภาพ" — ก่อนงานผ่านเข้าเส้นหลัก
LINTตรวจความสะอาดครัว
- เครื่องมือตรวจรูปแบบโค้ดและจุดเสี่ยงที่มองเห็นได้จากตัวโค้ด — ยังไม่ต้องรันโปรแกรม
- AI: "lint passes with no warnings"
TYPE CHECKตรวจว่าใส่ของถูกช่อง
- ตรวจว่าข้อมูลแต่ละชนิดถูกใช้ถูกที่ เช่น ไม่เอาข้อความไปคำนวณเป็นตัวเลข
- จับความผิดพลาดได้ก่อนโปรแกรมรันจริง
CODE REVIEWหัวหน้าเชฟตรวจจาน
- คน (หรือ AI อีกตัว) อ่านโค้ดตรวจความถูกต้อง อ่านง่าย และความปลอดภัย — เกิดในหน้า Pull Request (บท SE5)
- เทสตรวจ "ทำงานไหม" · review ตรวจ "ทำมาดีไหม"
QUALITY GATEด่านที่ต้องผ่านก่อนเสิร์ฟ
- เกณฑ์รวมที่ต้องเขียวครบก่อน merge (บท SE5): เทสผ่าน + lint ผ่าน + review แล้ว
- คือไฟเขียว-แดงที่เราเห็นในหน้า PR นั่นเอง
ACCEPTANCE TEST · UATเจ้าของร้านชิมเอง
- ตรวจว่า feature ตรงกับที่ธุรกิจต้องการจริง — UAT คือรอบที่เรา (ฝั่งธุรกิจ) เป็นคนลองใช้เอง
- ด่านเดียวที่ AI ทำแทนเราไม่ได้ เพราะคนตัดสิน "ตรงใจ" คือเรา
TDDตั้งโจทย์ชิมก่อนเริ่มปรุง
- แนวทางเขียนเทสที่ "ยังไม่ผ่าน" ก่อน แล้วค่อยเขียนโค้ดให้ผ่าน — รู้ไว้พอให้อ่านออกเวลา AI เสนอ
- AI: "I'll write the failing test first"
⭐ หัวใจของบท
ตารางแปลภาษา AI — ได้ยินแบบนี้ ต้องทำยังไง
| AI พูดว่า | กำลังจะเกิดอะไร | เราควรทำอะไร |
|---|---|---|
| "I'll add unit tests for this" | จะเขียนเทสชิมทีละวัตถุดิบให้ส่วนที่เพิ่งแก้ | ✅ ดีมาก — นี่คือพฤติกรรมที่อยากเห็น ปล่อยได้ |
| "All tests pass ✓" | เทสเท่าที่มีอยู่ผ่านหมด — ไม่ได้แปลว่าไม่มี bug | 🟡 ถามต่อ: "test ครอบคลุมอะไรบ้าง? มีเคสสำคัญไหนยังไม่ได้เทส?" |
| "Coverage is 85%" | เทสวิ่งผ่านโค้ด 85% — เป็นตัวเลขปริมาณ ไม่ใช่คุณภาพ | 🟡 อย่าหลงตัวเลข — ถามว่า 15% ที่เหลือคือส่วนไหน สำคัญไหม |
| "Lint passes with no warnings" | ความสะอาด-รูปแบบโค้ดผ่านเกณฑ์ — คนละเรื่องกับความถูกต้อง | ✅ รับทราบ — แต่ยังต้องดูผลเทสจริงแยกต่างหาก |
| "This test is flaky" | เทสข้อนี้เดี๋ยวผ่านเดี๋ยวไม่ผ่าน ผลเชื่อไม่ได้ | ⚠️ สั่งให้หาสาเหตุและแก้ — ห้ามลบหรือปิดเทสทิ้งเพื่อให้เขียว |
| "I'll skip the failing tests for now" · "no tests needed for this small change" | กำลังจะข้ามด่านชิม — งานที่ไม่ผ่านการตรวจกำลังจะไหลต่อ | ⚠️ หยุดก่อน — ให้อธิบายว่าเทสพังเพราะอะไร แก้ให้ผ่านก่อนไปต่อ |
สูตรจำเร็ว: ประโยคที่ AI เพิ่มเทส/แก้เทส = ทิศทางดี · ประโยคที่ skip / remove / disable test = ยกมือถามก่อนเสมอ — ด่านชิมมีไว้ป้องกันเรา ไม่ใช่ไว้ให้ข้าม
กันหลงทาง
6 คู่ที่จำสลับกันบ่อยที่สุด
| คู่ศัพท์ | ต่างกันตรงไหน |
|---|---|
| Unit Test vs E2E Test | Unit = ชิมทีละวัตถุดิบ เร็ว ชี้จุดผิดแม่น · E2E = นั่งกินทั้งมื้อเหมือนลูกค้า ช้าแต่เห็นภาพรวมจริง |
| Bug vs Flaky Test | Bug = โค้ดผิดจริง ต้องแก้โค้ด · Flaky = ผลเทสไม่นิ่งทั้งที่โค้ดไม่เปลี่ยน ต้องหาสาเหตุให้เจอ (มักอยู่ที่ตัวเทสหรือจังหวะเวลา) — อย่าโทษผิดตัว |
| Smoke Test vs Regression Test | Smoke = ชิมเร็ว ๆ ไม่กี่จุดว่าระบบยังเปิดใช้ได้ · Regression = รันเทสเก่าทั้งชุด ยืนยันของใหม่ไม่พังของเดิม |
| Test Coverage vs คุณภาพเทส | Coverage = ชิมครบกี่ % (ปริมาณ) · คุณภาพ = ชิมเป็นไหม ตรวจเคสที่เจ็บจริงหรือเปล่า — ตัวเลขสูงแต่ชิมไม่เป็นก็มี |
| Lint vs Test | Lint = ตรวจความสะอาด-รูปแบบโค้ด โดยไม่รันโปรแกรม · Test = รันจริงเพื่อพิสูจน์ว่าทำงานถูก — ผ่าน lint แต่คำนวณผิดก็ได้ |
| Acceptance Test vs UAT | Acceptance = เช็คตามเกณฑ์ที่เขียนไว้ (ใครรันก็ได้ รวมถึง AI) · UAT = ฝั่งธุรกิจลงมือลองใช้เองก่อนไฟเขียว — รอบนี้คืองานของเรา |
QUICK-CHECK · กดดูเฉลย
จริงหรือไม่? — เช็คก่อนปิดบท
1 · "Tests ผ่านหมด = โค้ดไม่มี bug"
ไม่จริง — เทสพิสูจน์ได้เฉพาะเคสที่มีคนเขียนเทสไว้ เคสที่ไม่ได้เทสยังพังได้เสมอ · คำถามที่ถูกคือ "เทสครอบคลุมเคสสำคัญของธุรกิจเราหรือยัง"
2 · "Coverage 85% ดีกว่า 60% เสมอ"
ไม่จริง — coverage วัดแค่ว่าชิมครบ ไม่ได้วัดว่าชิมเป็น · เทส 60% ที่ตรวจเคสเงิน ๆ ทอง ๆ ครบ อาจคุ้มกว่าเทส 85% ที่ตรวจแต่จุดง่าย ๆ
3 · "Flaky test น่ารำคาญ ลบทิ้งให้ suite เขียวไปเลยดีกว่า"
ไม่จริง — ลบเทสคือถอดกล้องวงจรปิดเพราะรำคาญภาพสั่น · ต้องสั่ง AI หาสาเหตุแล้วแก้ให้ผลนิ่ง เพราะจุดที่เทสนั้นเฝ้าอยู่ยังต้องมีคนเฝ้า
KEY TAKEAWAY
Unit = ชิมวัตถุดิบ · Integration = ชิมทั้งจาน · E2E = นั่งกินเหมือนลูกค้า · Regression = เมนูใหม่ไม่ทำเมนูเก่าเสียรส
กฎเหล็กประจำบท: "อย่ารับงานเพราะ AI บอกว่าเสร็จ — รับงานเพราะเห็นผลชิมแล้วว่าผ่าน"