“สถานการณ์ทดสอบ” (Test scenario) และ “กรณีทดสอบ” (test case) มักถูกใช้ราวกับว่ามีความหมายเดียวกัน แต่ความจริงแล้วไม่เหมือนกัน การนำสองคำนี้มาปะปนกันทำให้แผนการทดสอบอาจคลุมเครือเกินกว่าจะนำไปปฏิบัติได้จริง หรือละเอียดเกินกว่าจะอ่านเข้าใจ หนึ่งอธิบายว่าจะทดสอบอะไร อีกหนึ่งอธิบายว่าจะทดสอบอย่างไรให้แม่นยำ หากเข้าใจความสัมพันธ์ที่ถูกต้อง ความครอบคลุมของคุณจะสามารถตรวจสอบได้และทำงานได้จริง
คู่มือนี้จะให้คำจำกัดความของแต่ละคำ ชี้ให้เห็นถึงความแตกต่าง และแสดงให้เห็นว่าทั้งสองทำงานร่วมกันอย่างไรในเวิร์กโฟลว์การทดสอบ API จริงโดยใช้ Apidog
สถานการณ์ทดสอบคืออะไร?
สถานการณ์ทดสอบคือข้อความระดับสูงที่ระบุสิ่งที่ควรค่าแก่การทดสอบ โดยจะระบุพฤติกรรมหรือเงื่อนไขโดยไม่ระบุขั้นตอนที่ชัดเจน ข้อมูลนำเข้า หรือค่าที่คาดหวัง
ลองคิดว่ามันคือหัวข้อ ตัวอย่างเช่น สำหรับการชำระเงินของอีคอมเมิร์ซ สถานการณ์อาจมีดังนี้:
- ตรวจสอบการชำระเงินสำหรับผู้ใช้ที่ลงทะเบียนซึ่งมีบัตรที่บันทึกไว้
- ตรวจสอบการชำระเงินสำหรับผู้ใช้ทั่วไป
- ตรวจสอบการชำระเงินเมื่อสินค้าหมดสต็อกระหว่างการซื้อ
- ตรวจสอบการชำระเงินเมื่อการชำระเงินถูกปฏิเสธ
แต่ละบรรทัดจะบอกคุณว่า ต้องตรวจสอบอะไร และ ทำไม ถึงสำคัญต่อธุรกิจ ไม่มีข้อความใดที่บอกคุณว่าจะต้องเรียกใช้ปลายทาง (endpoint) ใด หรือจะส่งเพย์โหลด (payload) ใด สถานการณ์ถูกเขียนขึ้นจากมุมมองของผู้ใช้หรือข้อกำหนด ดังนั้นจึงอ่านเข้าใจได้ทั้งผู้จัดการผลิตภัณฑ์และวิศวกร
สถานการณ์ตอบคำถามเดียวว่า: เราได้คิดถึงทุกสิ่งที่ควรจะทำงานหรือไม่? มันคือแผนที่ความครอบคลุม หากสถานการณ์ขาดหายไป ไม่ว่าจะมีกรณีทดสอบที่ละเอียดแค่ไหนก็ไม่สามารถครอบคลุมช่องว่างนั้นได้
กรณีทดสอบคืออะไร?
กรณีทดสอบคือการตรวจสอบที่เป็นรูปธรรมและสามารถทำงานได้จริงซึ่งอยู่ภายใต้สถานการณ์ มันระบุข้อมูลนำเข้าที่แน่นอน เงื่อนไขเบื้องต้น การดำเนินการ และผลลัพธ์ที่คาดหวัง ด้วยความแม่นยำเพียงพอที่คนสองคนสามารถดำเนินการแล้วได้ผลลัพธ์เดียวกัน
ยกตัวอย่างสถานการณ์ “ตรวจสอบการชำระเงินสำหรับผู้ใช้ทั่วไป” ซึ่งสามารถแบ่งเป็นกรณีต่างๆ ได้ดังนี้:
POST /ordersพร้อมเพย์โหลดผู้ใช้ทั่วไปที่ถูกต้อง คืนค่า201และorder_idPOST /ordersหากไม่มีที่อยู่จัดส่ง คืนค่า400และvalidation_errorPOST /ordersพร้อม SKU ที่หมดสต็อก คืนค่า409และerror: out_of_stock
แต่ละกรณีจะระบุปลายทาง (endpoint) เนื้อหา สถานะที่คาดหวัง และฟิลด์การตอบกลับที่คาดหวัง มันมีความเฉพาะเจาะจงพอที่จะนำไปทำเป็นระบบอัตโนมัติ หากคุณต้องการโครงสร้างแบบฟิลด์ต่อฟิลด์ของกรณีทั้งหมด วิธีเขียนกรณีทดสอบ API จะครอบคลุมเทมเพลตอย่างละเอียด และ กรณีทดสอบเทียบกับสคริปต์ทดสอบ จะชี้แจงว่าโค้ดที่สามารถทำงานได้อยู่ที่ใด
คุณสมบัติที่สำคัญของกรณีทดสอบคือความแม่นยำ “การชำระเงินใช้งานได้” เป็นเพียงส่วนหนึ่งของสถานการณ์เท่านั้น “POST คำสั่งซื้อของผู้ใช้ทั่วไปที่ถูกต้อง คาดหวัง 201 พร้อม order_id ที่ไม่ว่างเปล่า” นี่คือกรณีทดสอบ
ความแตกต่างที่สำคัญ
แนวคิดทั้งสองแตกต่างกันในหลายมิติ ตารางนี้เป็นฉบับย่อ
| มิติ | สถานการณ์ทดสอบ | กรณีทดสอบ |
|---|---|---|
| ระดับ | ระดับสูง สิ่งที่ต้องทดสอบ | ระดับต่ำ วิธีการทดสอบ |
| รายละเอียด | สั้นๆ บรรทัดเดียว | ทีละขั้นตอนพร้อมข้อมูล |
| จุดเน้น | เป้าหมายทางธุรกิจหรือฟังก์ชัน | การดำเนินการทางเทคนิค |
| ข้อมูลนำเข้า | ไม่ได้ระบุ | เพย์โหลดและพารามิเตอร์ที่แน่นอน |
| ผลลัพธ์ที่คาดหวัง | โดยนัย | ระบุไว้อย่างชัดเจน (สถานะ, เนื้อหา, เวลา) |
| กลุ่มเป้าหมาย | ผลิตภัณฑ์, QA, วิศวกรรม | ผู้ทดสอบและเครื่องมืออัตโนมัติ |
| จำนวน | ไม่กี่รายการต่อคุณสมบัติ | หลายรายการต่อสถานการณ์ |
| สร้างขึ้น | ระหว่างการวางแผนการทดสอบ | หลังจากสถานการณ์ได้รับการตกลง |
ความสัมพันธ์เป็นแบบลำดับชั้น หนึ่งสถานการณ์จะก่อให้เกิดหลายกรณี สถานการณ์ควบคุมความกว้างของความครอบคลุม ส่วนกรณีควบคุมความลึกและความเข้มงวด ข้อผิดพลาดที่พบบ่อยคือการเขียนกรณีที่ละเอียดหลายสิบกรณีโดยไม่มีแผนที่สถานการณ์เหนือกว่า ทำให้เป็นไปไม่ได้ที่จะบอกว่าคุณสมบัติได้รับการครอบคลุมอย่างสมบูรณ์แล้ว หรือแค่ถูกทดสอบอย่างหนักในมุมใดมุมหนึ่ง
อีกวิธีหนึ่งในการมองคือ: สถานการณ์สามารถระบุว่า “ครอบคลุมแล้ว” หรือ “ยังไม่ครอบคลุม” ส่วนกรณีทดสอบสามารถระบุได้เพียง “ผ่าน” หรือ “ไม่ผ่าน” คุณต้องมีทั้งสองสถานะเพื่อจัดการคุณภาพ
สถานการณ์และกรณีทำงานร่วมกันอย่างไร
ขั้นตอนการทำงานที่เป็นรูปธรรมจะย้ายจากแบบกว้างไปหาแบบเฉพาะเจาะจงในห้าขั้นตอน
1. ระบุสถานการณ์จากข้อกำหนด อ่านข้อกำหนดหรือเอกสารประกอบ API และระบุพฤติกรรมทุกอย่างที่ควรค่าแก่การตรวจสอบ รวมถึงเส้นทางที่ไม่สำเร็จ (unhappy paths) นี่คือจุดที่ความครอบคลุมที่ขาดหายไปจะถูกค้นพบ ดังนั้นควรใช้เวลาที่นี่อย่างจริงจัง
2. กำหนดวัตถุประสงค์ของแต่ละสถานการณ์ ระบุว่า “เสร็จสมบูรณ์” หมายถึงอะไร สำหรับ “ตรวจสอบการชำระเงินของผู้ใช้ทั่วไป” วัตถุประสงค์คือผู้ใช้ทั่วไปสามารถสั่งซื้อและได้รับการยืนยันได้ ในขณะที่คำสั่งซื้อที่ไม่ถูกต้องจะถูกปฏิเสธอย่างชัดเจน
3. เขียนกรณีทดสอบภายใต้แต่ละสถานการณ์ ขยายแต่ละสถานการณ์ให้เป็นกรณีที่เป็นรูปธรรมพร้อมข้อมูลนำเข้าและผลลัพธ์ที่คาดหวัง ครอบคลุมเส้นทางที่สำเร็จ (happy path) ทุกความล้มเหลวในการตรวจสอบ และเงื่อนไขขอบเขตที่เกี่ยวข้อง
4. ตรวจสอบความสมบูรณ์ ย้อนกลับไปดูโครงสร้าง มีอย่างน้อยหนึ่งกรณีเส้นทางที่สำเร็จและหนึ่งกรณีเชิงลบสำหรับทุกสถานการณ์หรือไม่? มีรหัสสถานะที่ระบุไว้ในเอกสารปรากฏอยู่ในผลลัพธ์ที่คาดหวังหรือไม่? ช่องว่างที่พบ ณ จุดนี้มีต้นทุนต่ำ แต่ช่องว่างที่พบในการผลิตมีต้นทุนสูงกว่า
5. ดำเนินการและติดตามผลลัพธ์ เรียกใช้กรณี บันทึกผลผ่านและไม่ผ่านสำหรับแต่ละกรณี และสรุปผลลัพธ์ในระดับสถานการณ์เพื่อให้ผู้มีส่วนได้ส่วนเสียเห็นความครอบคลุม ไม่ใช่แค่จำนวนเครื่องหมายถูกสีเขียว
สำหรับทีมที่ขับเคลื่อนด้วยพฤติกรรม สถานการณ์สามารถแมปเข้ากับรูปแบบ Given-When-Then ของ Gherkin ได้อย่างเป็นธรรมชาติ คู่มือ Gherkin สำหรับการทดสอบ API แบบ BDD แสดงให้เห็นว่าโครงสร้างดังกล่าวช่วยให้สถานการณ์อ่านง่ายและยังคงสามารถเรียกใช้งานได้
ตัวอย่างการทำงาน: จากสถานการณ์ไปสู่กรณี
ยกตัวอย่าง API สำหรับแอปจดบันทึก ซึ่งมีพฤติกรรมเดียวที่ควรค่าแก่การทดสอบ: ผู้ใช้สามารถสร้างบันทึกได้ นั่นคือสถานการณ์
สถานการณ์: ผู้ใช้สามารถสร้างบันทึกได้ หนึ่งบรรทัด อยู่ในแผนการทดสอบ ซึ่งทุกคนสามารถอ่านได้ ไม่ได้กล่าวถึงปลายทาง (endpoints) เพย์โหลด (payloads) หรือรหัสสถานะ และก็ไม่ควรกล่าวถึง
ตอนนี้ขยายเป็นกรณีต่างๆ แต่ละกรณีคือการตรวจสอบที่สามารถทำงานได้หนึ่งรายการพร้อมข้อมูลนำเข้าที่แน่นอนและผลลัพธ์ที่คาดหวังที่แน่นอน
- กรณีที่ 1, เส้นทางที่สำเร็จ
POST /notesด้วย{"title": "Groceries", "body": "milk, eggs"}และโทเค็นที่ถูกต้อง คาดหวัง201, เนื้อหาการตอบกลับพร้อมidที่ไม่ว่างเปล่า,titleเท่ากับGroceries, และการประทับเวลาcreated_atการตอบสนองภายใน 600 มิลลิวินาที - กรณีที่ 2, ฟิลด์ที่จำเป็นขาดหายไป
POST /notesด้วย{"body": "milk, eggs"}และโทเค็นที่ถูกต้อง คาดหวัง400,errorเท่ากับvalidation_error, และdetailsที่ระบุฟิลด์title - กรณีที่ 3, ไม่ได้ยืนยันตัวตน
POST /notesด้วยเนื้อหาที่ถูกต้องและไม่มีโทเค็น คาดหวัง401และไม่มีidในการตอบกลับ - กรณีที่ 4, เพย์โหลดมีขนาดใหญ่เกินไป
POST /notesด้วยbodyขนาด 2 MB คาดหวัง413และข้อความแสดงข้อผิดพลาดที่ชัดเจน
หนึ่งสถานการณ์ สี่กรณี สถานการณ์บอกคุณว่า อะไร; กรณีบอกคุณว่า อย่างไร ด้วยความแม่นยำเพียงพอที่ผู้ทดสอบหรือระบบอัตโนมัติใดๆ ก็จะให้ผลลัพธ์เดียวกัน หากคุณเพิ่ม “ผู้ใช้สามารถแนบไฟล์ไปยังบันทึกได้” ในภายหลัง นั่นคือสถานการณ์ใหม่ และจะก่อให้เกิดชุดกรณีของมันเอง แผนจะเติบโตในลักษณะที่มีโครงสร้างและตรวจสอบได้ แทนที่จะกลายเป็นกองการตรวจสอบแบบแบนราบ
การสร้างสถานการณ์และกรณีใน Apidog
Apidog สร้างแบบจำลองลำดับชั้นนี้โดยตรง ดังนั้นโครงสร้างในแผนการทดสอบของคุณจึงตรงกับโครงสร้างในเครื่องมือของคุณ
สถานการณ์ทดสอบ ใน Apidog คือลำดับของการร้องขอ API ที่จัดเรียงไว้ แต่ละรายการมีการยืนยัน (assertions) ของตัวเอง คุณสร้างมันด้วยภาพ: เพิ่มปลายทางที่เกี่ยวข้องกับพฤติกรรม เชื่อมโยงเข้าด้วยกันเพื่อให้ผลลัพธ์จากการร้องขอหนึ่งรายการป้อนไปยังรายการถัดไป (การเข้าสู่ระบบจะส่งคืนโทเค็น การร้องขอถัดไปจะใช้โทเค็นนั้น) และตั้งค่าการยืนยันในแต่ละขั้นตอน
แต่ละบล็อกของการร้องขอพร้อมการยืนยัน (request-plus-assertions block) จะมีประสิทธิภาพเหมือนกับ กรณีทดสอบ คุณยืนยันรหัสสถานะ ฟิลด์เนื้อหาการตอบกลับ การปฏิบัติตาม Schema และเวลาตอบสนองด้วยการคลิก โดยไม่ต้องเขียนสคริปต์ การทดสอบที่ขับเคลื่อนด้วยข้อมูล (Data-driven testing) ช่วยให้หนึ่งกรณีสามารถทำงานกับข้อมูลนำเข้าหลายแถวจากไฟล์ CSV หรือ JSON ดังนั้นกรณีเชิงลบเดียวจึงครอบคลุมทุกการรวมกันที่ไม่ถูกต้อง
จากนั้นสถานการณ์จะถูกจัดกลุ่มเป็น ชุดทดสอบ (test suites) สำหรับการทำงานที่จัดระเบียบและทำซ้ำได้ทั่วทั้ง API คุณสามารถเรียกใช้ชุดทดสอบในเครื่อง ตามกำหนดเวลา หรือภายใน CI และ Apidog จะสร้างรายงานที่แสดงผลลัพธ์ทั้งในระดับกรณีและระดับสถานการณ์ มุมมองสองด้านนั้นคือผลตอบแทน: วิศวกรเห็นว่ากรณีใดล้มเหลว และหัวหน้างานเห็นว่าสถานการณ์ใดมีความเสี่ยงในขณะนี้
ดาวน์โหลด Apidog เพื่อสร้างสถานการณ์แรกของคุณและดูการสรุปผลจากกรณีไปยังสถานการณ์ในทางปฏิบัติ
ทำไมคุณถึงต้องการทั้งสองอย่าง ไม่ใช่แค่หนึ่งเดียว
บางครั้งทีมพยายามข้ามเลเยอร์หนึ่ง การข้ามสถานการณ์และการเขียนเฉพาะกรณีจะสร้างรายการที่ยาวและแบนราบโดยไม่มีแผนที่ความครอบคลุม คุณไม่สามารถตอบได้ว่า “เราได้ทดสอบการชำระเงินของผู้ใช้ทั่วไปอย่างสมบูรณ์หรือไม่?” โดยไม่ต้องอ่านทุกกรณีซ้ำ การข้ามกรณีและเก็บเฉพาะสถานการณ์จะสร้างแผนที่ไม่มีใครสามารถดำเนินการได้อย่างสม่ำเสมอ เพราะ “ตรวจสอบการชำระเงิน” มีความหมายที่แตกต่างกันสำหรับผู้ทดสอบแต่ละคน
สองเลเยอร์ยังตอบสนองผู้อ่านที่แตกต่างกัน ผู้จัดการผลิตภัณฑ์อ่านสถานการณ์เพื่อยืนยันว่ากำลังทดสอบสิ่งที่ถูกต้อง วิศวกรระบบอัตโนมัติอ่านกรณีเพื่อสร้างตัวเรียกใช้ รายงานการทดสอบที่แสดงเฉพาะกรณีที่ผ่านไม่สามารถบอกอะไรแก่ผู้บริหารเกี่ยวกับความครอบคลุมได้ แต่รายงานที่สรุปกรณีเป็นสถานการณ์จะบอกพวกเขาได้อย่างชัดเจนว่าคุณสมบัติใดปลอดภัยที่จะนำออกใช้
รักษาสถานการณ์ให้คงที่และกรณีให้เป็นปัจจุบัน สถานการณ์จะเปลี่ยนเฉพาะเมื่อความตั้งใจของคุณสมบัติเปลี่ยนไป กรณีจะเปลี่ยนเมื่อสัญญา API เปลี่ยนแปลง เมื่อคุณปฏิบัติต่อสองสิ่งนี้เป็นสิ่งประดิษฐ์ที่แยกจากกันโดยมีวงจรชีวิตที่แยกจากกัน แผนการทดสอบของคุณก็จะยังคงถูกต้องและบำรุงรักษาได้
คำถามที่พบบ่อย
สถานการณ์ทดสอบเหมือนกับชุดทดสอบหรือไม่? ไม่ สถานการณ์อธิบายพฤติกรรมที่ต้องทดสอบ ชุดทดสอบคือชุดของการทดสอบที่เรียกใช้งานได้ซึ่งจัดกลุ่มเพื่อการทำงาน ชุดทดสอบสามารถมีกรณีจากหลายสถานการณ์ได้ ดูที่ ชุดทดสอบเทียบกับกรณีทดสอบ
สถานการณ์หนึ่งควรมีกรณีทดสอบกี่กรณี? มากพอที่จะครอบคลุมเส้นทางที่สำเร็จ (happy path) พร้อมกับทุกรูปแบบความล้มเหลวที่สถานการณ์บ่งชี้ สถานการณ์ที่เรียบง่ายอาจต้องการสามหรือสี่กรณี สถานการณ์ที่ซับซ้อนต้องการมากกว่านั้น
ใครเป็นผู้เขียนสถานการณ์เทียบกับกรณี? สถานการณ์มักจะถูกร่างขึ้นร่วมกับฝ่ายผลิตภัณฑ์และ QA เนื่องจากพวกเขารวมความตั้งใจไว้ ส่วนกรณีมักจะถูกเขียนโดย QA หรือนักพัฒนา เนื่องจากพวกเขารวมรายละเอียดทางเทคนิคไว้ รูปแบบข้อกำหนดกรณีทดสอบ ช่วยให้การเขียนกรณีมีความสอดคล้องกัน
จำเป็นต้องมีสถานการณ์หรือไม่หากการทดสอบของฉันเป็นแบบอัตโนมัติ? ใช่ ระบบอัตโนมัติเรียกใช้กรณี แต่สถานการณ์ยังคงตอบได้ว่ามีกรณีที่ถูกต้องอยู่หรือไม่ ระบบอัตโนมัติที่ไม่มีแผนที่ความครอบคลุมแค่ล้มเหลวเร็วขึ้น
