Test Strategy & Design Techniques
Test Levels ในวงจรซอฟต์แวร์
Test level คือ "ชั้น" ของการทดสอบที่สอดคล้องกับ scope ของสิ่งที่ถูกทดสอบ — แต่ละชั้นตอบคำถาม ต่างกัน และควรทำโดยคนละช่วงเวลาในวงจรพัฒนา
| Level | ตอบคำถามอะไร | ใครทำส่วนใหญ่ |
|---|---|---|
| Unit | ฟังก์ชัน/class เดียวทำงานถูกไหม | Developer (ดู Unit Testing) |
| Integration | หลาย component/service ต่อกันแล้วทำงานถูกไหม | Developer + QA |
| System | ทั้งแอปทำงานตาม requirement ครบไหม (end-to-end) | QA |
| Acceptance (UAT) | ระบบตอบโจทย์ธุรกิจจริง พร้อม release ไหม | QA + Business/PO |
"ยิ่งขึ้น level สูง ยิ่งใกล้ตาผู้ใช้จริง แต่ยิ่งพังแล้วหาสาเหตุยาก" — Unit test บอกจุดพังตรงๆ ทันที ส่วน UAT บอกแค่ว่า "flow นี้พัง" แต่ไม่รู้ว่าพังเพราะโค้ดส่วนไหน ต้องไล่ลงมาเช็คทีละ level
หลายทีมเข้าใจผิดว่า "QA ทำแค่ System test กับ UAT" แต่ QA/SDET ที่ดีควรมีส่วนร่วมตั้งแต่ การรีวิว requirement ก่อนโค้ดถูกเขียนเลยด้วยซ้ำ — เทคนิคที่เรียกว่า Three Amigos (Dev + QA + Business/PO ประชุมร่วมกันก่อนเริ่ม sprint) ช่วยจับความกำกวมของ requirement ได้ตั้งแต่ต้น ทาง ก่อนที่มันจะกลายเป็นบั๊กที่เจอช้าสุดและแก้แพงสุดตอน UAT — แนวคิดนี้คือรากของ shift-left testing (ขยับการทดสอบ/คุณภาพให้เร็วขึ้นในวงจร ไม่ใช่รอให้โค้ดเสร็จก่อนค่อยคิดเรื่องเทสต์)
Risk-Based Testing
เวลาและทรัพยากรทดสอบมีจำกัดเสมอ Risk-based testing คือการจัดลำดับความสำคัญของสิ่งที่ต้อง ทดสอบตาม ความเสี่ยง = ความรุนแรงถ้าพัง (impact) × โอกาสที่จะพัง (likelihood)
ความเสี่ยงสูง → ทดสอบละเอียดสุด (เช่น flow เงิน, flow login)
ความเสี่ยงกลาง → ทดสอบตาม happy path + edge case สำคัญ
ความเสี่ยงต่ำ → smoke test พอ หรือข้ามได้ถ้าเวลาจำกัดจริงๆ
"ทดสอบเหมือนประกันภัย ไม่ใช่เหมือนตรวจทุกอย่างเท่ากัน" — ไม่มีใครทำประกันของมีค่าน้อยแพงเท่าของ มีค่ามาก การทดสอบก็ควรลงทุนเวลาตามความเสี่ยงที่แท้จริง ไม่ใช่ไล่ทดสอบทุก field เท่าๆ กันหมด
ความเสี่ยงไม่ได้วัดจาก "ความซับซ้อนของโค้ด" อย่างเดียว แต่ต้องรวม ความถี่ในการใช้งานจริงของ user และ ผลกระทบทางธุรกิจ/กฎหมาย ด้วย เช่น ฟีเจอร์ "เปลี่ยนภาษา UI" อาจโค้ดซับซ้อนน้อยมาก แต่ถ้าพังในตลาดที่กฎหมายบังคับให้แสดงภาษาท้องถิ่น (เช่น ข้อมูลผลิตภัณฑ์ทางการแพทย์) ความเสี่ยง ทางธุรกิจ/กฎหมายอาจสูงกว่าฟีเจอร์ที่โค้ดซับซ้อนกว่ามากแต่ไม่มีข้อผูกพันทางกฎหมาย ทีม QA ระดับ senior จะคุยกับฝั่ง business/legal ก่อนตัดสินใจจัดลำดับความเสี่ยง ไม่ใช่ประเมินจากมุมมองเทคนิค อย่างเดียว
Test Design Techniques (Black-Box)
เทคนิคออกแบบเทสต์เคสที่เป็นระบบ ลด "เทสต์ซ้ำที่ไม่เพิ่มความมั่นใจ" และ "ช่องโหว่ที่ไม่มีใครคิด ถึง"
Equivalence Partitioning (EP) — แบ่ง input เป็นกลุ่มที่ "ควรให้ผลลัพธ์แบบเดียวกัน" แล้วเลือก ทดสอบตัวแทนแค่ 1 ค่าต่อกลุ่มพอ ไม่ต้องทดสอบทุกค่าในกลุ่มเดียวกัน
Boundary Value Analysis (BVA) — บั๊กมักซ่อนอยู่ที่ "ขอบ" ของช่วงค่า ให้ทดสอบค่าที่ขอบพอดี, ค่าเหนือขอบ 1 หน่วย, ค่าใต้ขอบ 1 หน่วย
กฎ: อายุ 18-60 ปีถึงสมัครได้
EP: กลุ่ม <18 (invalid), กลุ่ม 18-60 (valid), กลุ่ม >60 (invalid) → เลือก 1 ตัวแทนต่อกลุ่ม
BVA: 17 (invalid), 18 (valid-ขอบล่าง), 60 (valid-ขอบบน), 61 (invalid) → เทสต์ตรงขอบ
Decision Table — ใช้เมื่อผลลัพธ์ขึ้นกับ การรวมกันของหลาย condition พร้อมกัน ช่วยไม่ให้ ลืม combination ที่เป็นไปได้
| สมาชิก VIP | ยอดซื้อ ≥ 1000 | ผลลัพธ์ |
|---|---|---|
| ใช่ | ใช่ | ส่วนลด 20% |
| ใช่ | ไม่ | ส่วนลด 10% |
| ไม่ | ใช่ | ส่วนลด 5% |
| ไม่ | ไม่ | ไม่มีส่วนลด |
"EP หาตัวแทนกลุ่ม, BVA เจาะที่ขอบ, Decision Table ไล่ครบ combination" — สามเทคนิคตอบคำถามต่าง กัน: EP ลดจำนวนเทสต์ที่ซ้ำซ้อน, BVA เพิ่มเทสต์ตรงจุดเสี่ยงบั๊กสูงสุด, Decision Table ป้องกันการ ลืม combination ของเงื่อนไขหลายตัว
มือใหม่มักทำ BVA ผิดโดยทดสอบแค่ "ค่าขอบ" (18, 60) แต่ลืมทดสอบ "ค่าติดขอบ" (17, 61) ทั้งที่
ค่าติดขอบคือจุดที่บั๊ก off-by-one (< vs <=) จะโผล่ออกมาจริง — ถ้าโค้ดเขียนผิดเป็น age < 18 แทนที่จะเป็น age <= 18 การทดสอบแค่ 18 และ 60 จะไม่จับบั๊กนี้ได้เลย เพราะทั้งสองค่ายัง
ผ่านเหมือนเดิม ต้องทดสอบคู่ 17/18 และ 60/61 เทียบกันจึงจะเห็นรอยต่อที่ผิดจริง — นี่คือเหตุผลที่
BVA ที่ถูกต้องควรมีอย่างน้อย 2 ค่าต่อขอบ (ค่าขอบเอง + ค่าติดขอบ) ไม่ใช่ 1 ค่า
Test levels (unit/integration/system/acceptance) each answer a different question and ideally
involve QA earlier than "system test only" — the Three Amigos practice (dev + QA + business)
reviews requirements before code is written, the root of shift-left testing. Risk-based testing
prioritizes test effort by impact × likelihood, factoring in real usage frequency and business/
legal exposure, not just code complexity. Equivalence Partitioning picks one representative value
per input group; Boundary Value Analysis targets range edges where off-by-one bugs hide — testing
both the boundary value and the value just past it is necessary to actually catch < vs <=
mistakes; Decision Tables enumerate condition combinations to avoid missed cases.