“สถานการณ์ทดสอบ” (Test scenario) และ “กรณีทดสอบ” (Test case) ไม่ใช่สิ่งเดียวกัน แม้มักถูกใช้แทนกันในการวางแผน QA ก็ตาม สถานการณ์ทดสอบบอกว่า “ต้องทดสอบอะไร” ส่วนกรณีทดสอบบอกว่า “ต้องทดสอบอย่างไร” ด้วยข้อมูล ขั้นตอน และผลลัพธ์ที่คาดหวังที่ชัดเจน หากแยกสองเลเยอร์นี้ออกจากกัน แผนทดสอบจะตรวจสอบความครอบคลุมได้ง่ายขึ้น และนำไปทำ automation ได้จริง
คู่มือนี้อธิบายความแตกต่างระหว่างสถานการณ์ทดสอบและกรณีทดสอบ พร้อมวิธีนำไปใช้ในเวิร์กโฟลว์การทดสอบ API ด้วย Apidog
สถานการณ์ทดสอบคืออะไร?
สถานการณ์ทดสอบคือข้อความระดับสูงที่ระบุพฤติกรรม เงื่อนไข หรือความสามารถที่ควรถูกตรวจสอบ โดยไม่ลงรายละเอียดระดับ endpoint, payload, test data หรือ assertion
ให้คิดว่าสถานการณ์คือ “หัวข้อความครอบคลุม” ตัวอย่างเช่น ระบบชำระเงินของอีคอมเมิร์ซอาจมีสถานการณ์ดังนี้:
- ตรวจสอบการชำระเงินสำหรับผู้ใช้ที่ลงทะเบียนและมีบัตรที่บันทึกไว้
- ตรวจสอบการชำระเงินสำหรับผู้ใช้ทั่วไป
- ตรวจสอบการชำระเงินเมื่อสินค้าหมดสต็อกระหว่างการซื้อ
- ตรวจสอบการชำระเงินเมื่อการชำระเงินถูกปฏิเสธ
แต่ละบรรทัดตอบคำถามว่า:
- ต้องตรวจสอบพฤติกรรมใด
- พฤติกรรมนั้นสำคัญต่อธุรกิจอย่างไร
- มีพื้นที่ใดบ้างที่ต้องครอบคลุมก่อน release
สถานการณ์ไม่ควรระบุรายละเอียดเช่น POST /orders, payload หรือ status code เพราะหน้าที่ของมันคือกำหนด “ขอบเขต” ไม่ใช่ “ขั้นตอนการรัน”
ใช้สถานการณ์เพื่อตรวจว่า:
- requirement สำคัญถูกครอบคลุมครบหรือไม่
- happy path และ unhappy path ถูกพิจารณาหรือยัง
- ทีม product, QA และ engineering เข้าใจตรงกันหรือไม่
ถ้าสถานการณ์หายไป ต่อให้มีกรณีทดสอบละเอียดแค่ไหน ก็ยังอาจพลาดพฤติกรรมสำคัญของระบบได้
กรณีทดสอบคืออะไร?
กรณีทดสอบคือการตรวจสอบที่ระบุรายละเอียดครบพอให้คนหรือเครื่องมือ automation สามารถรันซ้ำแล้วได้ผลลัพธ์เดียวกัน โดยทั่วไปควรมี:
- เงื่อนไขเบื้องต้น
- endpoint หรือ action ที่ต้องเรียก
- input หรือ payload ที่ใช้
- expected status code
- expected response body
- assertion หรือเงื่อนไขผ่าน/ไม่ผ่าน
ตัวอย่างจากสถานการณ์ “ตรวจสอบการชำระเงินสำหรับผู้ใช้ทั่วไป” สามารถแตกเป็นกรณีทดสอบได้ดังนี้:
-
POST /ordersพร้อม payload ผู้ใช้ทั่วไปที่ถูกต้อง ต้องได้201และมีorder_id -
POST /ordersโดยไม่มีที่อยู่จัดส่ง ต้องได้400และvalidation_error -
POST /ordersพร้อม SKU ที่หมดสต็อก ต้องได้409และerror: out_of_stock
ตัวอย่างกรณีทดสอบแบบชัดเจน:
ชื่อกรณี: สร้างคำสั่งซื้อสำหรับผู้ใช้ทั่วไปสำเร็จ
Precondition:
- มีสินค้า SKU-001 ในสต็อก
- ผู้ใช้ยังไม่ได้ login
Request:
POST /orders
Payload:
{
"items": [
{
"sku": "SKU-001",
"quantity": 1
}
],
"shipping_address": {
"name": "Guest User",
"city": "Bangkok",
"postal_code": "10110"
},
"payment_method": "card"
}
Expected:
- HTTP status เป็น 201
- response มี order_id
- response.status เป็น created
กรณีทดสอบต้องเฉพาะเจาะจงพอสำหรับ automation หากต้องการโครงสร้างแบบฟิลด์ต่อฟิลด์ อ่านเพิ่มได้ที่ วิธีเขียนกรณีทดสอบ API และถ้าต้องการแยกความต่างระหว่าง test case กับ executable code ดู กรณีทดสอบเทียบกับสคริปต์ทดสอบ
จุดสำคัญคือความแม่นยำ ประโยคอย่าง “การชำระเงินใช้งานได้” ยังเป็นแค่สถานการณ์ แต่ “ส่ง POST /orders ด้วย payload ที่ถูกต้อง แล้วคาดหวัง 201 พร้อม order_id ที่ไม่ว่างเปล่า” คือกรณีทดสอบ
ความแตกต่างที่สำคัญ
| มิติ | สถานการณ์ทดสอบ | กรณีทดสอบ |
|---|---|---|
| ระดับ | ระดับสูง ระบุสิ่งที่ต้องทดสอบ | ระดับต่ำ ระบุวิธีทดสอบ |
| รายละเอียด | สั้น กระชับ มักเป็นหนึ่งบรรทัด | มีขั้นตอน ข้อมูล และ expected result |
| จุดเน้น | เป้าหมายทางธุรกิจหรือฟังก์ชัน | การตรวจสอบทางเทคนิค |
| ข้อมูลนำเข้า | ไม่ระบุรายละเอียด | ระบุ payload, parameter หรือ test data |
| ผลลัพธ์ที่คาดหวัง | มักเป็นนัย | ระบุชัดเจน เช่น status, body, schema, response time |
| ผู้อ่านหลัก | Product, QA, Engineering | QA, Developer, Automation tool |
| จำนวน | ไม่กี่รายการต่อ feature | หลายรายการต่อสถานการณ์ |
| ช่วงเวลาที่สร้าง | ระหว่าง test planning | หลังจากตกลงสถานการณ์แล้ว |
ความสัมพันธ์เป็นแบบลำดับชั้น:
สถานการณ์ทดสอบ
└── กรณีทดสอบ 1
└── กรณีทดสอบ 2
└── กรณีทดสอบ 3
หนึ่งสถานการณ์ควรแตกออกเป็นหลายกรณี สถานการณ์ควบคุม “ความกว้าง” ของ coverage ส่วนกรณีควบคุม “ความลึก” และความเข้มงวดของการตรวจสอบ
ข้อผิดพลาดที่พบบ่อยคือเขียน test case จำนวนมากโดยไม่มี scenario map ทำให้ตอบไม่ได้ว่า feature ถูกครอบคลุมครบหรือแค่ถูกทดสอบหนักเฉพาะบางมุม
อีกวิธีคิดคือ:
- สถานการณ์ตอบว่า “ครอบคลุมแล้วหรือยัง”
- กรณีทดสอบตอบว่า “ผ่านหรือไม่ผ่าน”
คุณต้องมีทั้งสองระดับเพื่อจัดการคุณภาพได้จริง
วิธีใช้สถานการณ์และกรณีร่วมกัน
เวิร์กโฟลว์ที่นำไปใช้ได้จริงควรเริ่มจากกว้างไปหาเฉพาะเจาะจง
1. ระบุสถานการณ์จาก requirement
อ่าน requirement, user story หรือ API documentation แล้วลิสต์พฤติกรรมที่ต้องตรวจสอบ รวมถึง:
- happy path
- validation error
- permission หรือ authentication error
- business rule
- boundary condition
- integration failure
ตัวอย่าง:
Feature: Notes API
สถานการณ์:
- ผู้ใช้สามารถสร้างบันทึกได้
- ผู้ใช้สามารถแก้ไขบันทึกของตัวเองได้
- ผู้ใช้ไม่สามารถแก้ไขบันทึกของผู้อื่นได้
- ผู้ใช้สามารถลบบันทึกได้
2. กำหนด objective ของแต่ละสถานการณ์
เขียนให้ชัดว่า “สำเร็จ” หมายถึงอะไร เช่น:
สถานการณ์: ผู้ใช้สามารถสร้างบันทึกได้
Objective:
- ผู้ใช้ที่ authenticated สามารถสร้างบันทึกใหม่ได้
- ระบบต้อง reject request ที่ข้อมูลไม่ครบ
- ระบบต้อง reject request ที่ไม่มี token
ขั้นตอนนี้ช่วยให้ทีมตกลง scope ก่อนลงรายละเอียด test case
3. แตกสถานการณ์เป็นกรณีทดสอบ
สำหรับแต่ละสถานการณ์ ให้เขียน test case ที่มี input และ expected result ชัดเจน
ตัวอย่าง checklist:
- มี happy path อย่างน้อยหนึ่งกรณีหรือไม่
- มี negative case สำหรับ validation หรือไม่
- มี authentication/authorization case หรือไม่
- มี boundary case หรือไม่
- expected status code ตรงกับเอกสาร API หรือไม่
- response body มี assertion ที่ตรวจ business outcome หรือไม่
4. ตรวจความครบถ้วนของ coverage
ก่อนเริ่ม automation ให้ย้อนกลับมาตรวจ mapping:
Scenario: ผู้ใช้สามารถสร้างบันทึกได้
- TC-001 สร้างบันทึกสำเร็จ
- TC-002 title หายไป
- TC-003 ไม่มี token
- TC-004 payload ใหญ่เกินกำหนด
ถ้าสถานการณ์ใดไม่มี test case แสดงว่ายังไม่มีการตรวจสอบจริง
ถ้า test case ใดไม่ผูกกับสถานการณ์ อาจเป็นการทดสอบที่ไม่มีบริบท coverage
5. รันและสรุปผลทั้งสองระดับ
เมื่อรัน test case ให้บันทึกผลระดับกรณี เช่น:
TC-001: Passed
TC-002: Passed
TC-003: Failed
TC-004: Passed
จากนั้นสรุปกลับไปที่ระดับสถานการณ์:
Scenario: ผู้ใช้สามารถสร้างบันทึกได้
Status: At risk
Reason: TC-003 failed - unauthenticated request ไม่ถูก reject ตามที่คาดหวัง
รายงานแบบนี้มีประโยชน์กว่าแค่จำนวน test ที่ผ่าน เพราะ stakeholder เห็นได้ทันทีว่า feature ใดมีความเสี่ยง
สำหรับทีมที่ใช้ BDD สถานการณ์สามารถ map กับ Given-When-Then ได้โดยตรง อ่านแนวทางเพิ่มเติมได้ที่ คู่มือ Gherkin สำหรับการทดสอบ API แบบ BDD
ตัวอย่างการทำงาน: จากสถานการณ์ไปสู่กรณี
สมมติว่าคุณมี Notes API และต้องการทดสอบพฤติกรรมนี้:
สถานการณ์: ผู้ใช้สามารถสร้างบันทึกได้
สถานการณ์นี้บอก “สิ่งที่ต้องตรวจสอบ” แต่ยังไม่พอสำหรับการรันจริง จึงต้องแตกเป็นกรณีทดสอบ
กรณีที่ 1: สร้างบันทึกสำเร็จ
POST /notes
Authorization: Bearer <valid_token>
Content-Type: application/json
{
"title": "Groceries",
"body": "milk, eggs"
}
Expected:
- status code เป็น
201 - response มี
idที่ไม่ว่าง -
titleเท่ากับGroceries - มี
created_at - response time น้อยกว่า 600 ms
กรณีที่ 2: ขาดฟิลด์ที่จำเป็น
POST /notes
Authorization: Bearer <valid_token>
Content-Type: application/json
{
"body": "milk, eggs"
}
Expected:
- status code เป็น
400 -
errorเท่ากับvalidation_error -
detailsระบุว่า fieldtitleหายไป
กรณีที่ 3: ไม่ได้ยืนยันตัวตน
POST /notes
Content-Type: application/json
{
"title": "Groceries",
"body": "milk, eggs"
}
Expected:
- status code เป็น
401 - response ไม่มี
id - ระบบไม่สร้าง note ใหม่
กรณีที่ 4: payload ใหญ่เกินไป
POST /notes
Authorization: Bearer <valid_token>
Content-Type: application/json
{
"title": "Large note",
"body": "<2MB text>"
}
Expected:
- status code เป็น
413 - response มีข้อความ error ที่ชัดเจน
จากตัวอย่างนี้:
- หนึ่งสถานการณ์อธิบาย “อะไร”
- สี่กรณีอธิบาย “ทดสอบอย่างไร”
- แต่ละกรณีสามารถนำไปสร้าง automated API test ได้
ถ้าในอนาคตเพิ่มฟีเจอร์ “ผู้ใช้สามารถแนบไฟล์ไปยังบันทึกได้” นั่นควรเป็นสถานการณ์ใหม่ และแตกเป็น test case ชุดใหม่ ไม่ควรยัดรวมเข้าไปในสถานการณ์เดิมจน scope ไม่ชัดเจน
การสร้างสถานการณ์และกรณีใน Apidog
Apidog รองรับการจัดโครงสร้างการทดสอบ API ตามลำดับชั้นนี้ เพื่อให้แผนทดสอบในเอกสารและการทดสอบในเครื่องมือสอดคล้องกัน
ใน Apidog คุณสามารถสร้างสถานการณ์ทดสอบเป็นลำดับของ API requests ที่เกี่ยวข้องกัน เช่น:
1. Login
2. Create note
3. Get note detail
4. Assert created note
แต่ละ request สามารถมี assertion ของตัวเอง เช่น:
- status code
- response body field
- schema validation
- response time
- value ที่ส่งต่อจาก request ก่อนหน้า
ตัวอย่าง flow:
POST /login
└── extract token
POST /notes
└── use token
└── assert status = 201
└── extract note_id
GET /notes/{note_id}
└── assert title = Groceries
แต่ละ request พร้อม assertion ทำหน้าที่เหมือนกรณีทดสอบที่รันได้จริง ส่วนชุดของ request ที่ประกอบกันเป็น behavior หนึ่งชุดทำหน้าที่เป็นสถานการณ์
Apidog ยังรองรับ data-driven testing เพื่อรันกรณีเดียวกับข้อมูลหลายชุดจาก CSV หรือ JSON เช่น ใช้ทดสอบ validation error หลายแบบโดยไม่ต้องสร้าง test case ซ้ำจำนวนมาก
จากนั้นสามารถจัดกลุ่มสถานการณ์เป็น ชุดทดสอบ เพื่อรันซ้ำได้ เช่น:
- รันในเครื่องระหว่างพัฒนา
- รันตาม schedule
- รันใน CI pipeline
- สร้างรายงานผลระดับกรณีและระดับสถานการณ์
มุมมองสองระดับนี้ช่วยให้:
- วิศวกรเห็นว่า request หรือ assertion ใดล้มเหลว
- QA เห็นว่า test case ใดต้องแก้
- stakeholder เห็นว่าสถานการณ์หรือ feature ใดมีความเสี่ยง
คุณสามารถ ดาวน์โหลด Apidog เพื่อสร้างสถานการณ์แรกและดูการสรุปผลจาก test case ไปยัง scenario ในเวิร์กโฟลว์จริง
ทำไมต้องมีทั้งสถานการณ์และกรณีทดสอบ
ถ้ามีเฉพาะกรณีทดสอบ คุณจะได้รายการยาว ๆ เช่น:
TC-001
TC-002
TC-003
TC-004
...
แต่ตอบยากว่า feature ใดถูกครอบคลุมครบแล้ว หรือกรณีเหล่านั้นผูกกับ requirement ไหน
ถ้ามีเฉพาะสถานการณ์ คุณจะได้แผนระดับสูง เช่น:
ตรวจสอบการชำระเงิน
ตรวจสอบการสมัครสมาชิก
ตรวจสอบการลืมรหัสผ่าน
แต่ไม่มีรายละเอียดพอให้รันซ้ำอย่างสม่ำเสมอ เพราะแต่ละคนอาจตีความ “ตรวจสอบ” ต่างกัน
แนวทางที่ใช้งานได้จริงคือ:
Scenario → Test cases → Assertions → Test report
สองเลเยอร์นี้ยังตอบโจทย์ผู้อ่านต่างกลุ่ม:
- Product manager อ่านสถานการณ์เพื่อยืนยันว่า test coverage ตรงกับ business requirement
- QA อ่านกรณีเพื่อออกแบบข้อมูลและ expected result
- Developer อ่านกรณีเพื่อ debug และเขียน automation
- Manager อ่านรายงานระดับสถานการณ์เพื่อประเมิน release risk
หลักปฏิบัติที่ดีคือ:
- รักษาสถานการณ์ให้เสถียร เปลี่ยนเมื่อเจตนาของ feature เปลี่ยน
- อัปเดตกรณีทดสอบเมื่อ API contract, schema หรือ business rule เปลี่ยน
- ผูก test case ทุกตัวเข้ากับสถานการณ์เสมอ
- สรุปรายงานจาก test case ขึ้นไปเป็น scenario status
เมื่อแยก lifecycle ของสองสิ่งนี้ แผนทดสอบจะอ่านง่ายขึ้น บำรุงรักษาได้ดีขึ้น และเหมาะกับ automation มากขึ้น
คำถามที่พบบ่อย
สถานการณ์ทดสอบเหมือนกับชุดทดสอบหรือไม่?
ไม่เหมือนกัน สถานการณ์อธิบายพฤติกรรมที่ต้องทดสอบ ส่วนชุดทดสอบคือกลุ่มของการทดสอบที่จัดไว้เพื่อการรัน ชุดทดสอบอาจมีกรณีจากหลายสถานการณ์ได้ อ่านเพิ่มได้ที่ ชุดทดสอบเทียบกับกรณีทดสอบ
สถานการณ์หนึ่งควรมีกี่กรณีทดสอบ?
ควรมีมากพอที่จะครอบคลุม happy path, negative path และ boundary condition ที่เกี่ยวข้อง สถานการณ์ง่ายอาจมี 3-4 กรณี ส่วนสถานการณ์ซับซ้อนอาจต้องมีมากกว่านั้น
ใครควรเขียนสถานการณ์และใครควรเขียนกรณีทดสอบ?
สถานการณ์มักเขียนร่วมกันระหว่าง product และ QA เพราะเกี่ยวกับ intent ของ feature ส่วนกรณีทดสอบมักเขียนโดย QA หรือนักพัฒนา เพราะต้องใช้รายละเอียดทางเทคนิค เช่น endpoint, payload และ assertion ดูแนวทางเพิ่มเติมได้ที่ รูปแบบข้อกำหนดกรณีทดสอบ
ถ้าการทดสอบเป็น automation อยู่แล้ว ยังต้องมีสถานการณ์หรือไม่?
ยังต้องมี Automation รันกรณีทดสอบ แต่สถานการณ์บอกว่ากรณีเหล่านั้นครอบคลุม requirement ที่ถูกต้องหรือไม่ หากไม่มี scenario map ระบบ automation อาจแค่รันเร็วขึ้น แต่ยังไม่รับประกันว่า coverage ครบถ้วนจริง
Top comments (0)