กลยุทธ์จัดการ Test Data
จบบทนี้แล้วคุณจะ...
- อธิบายได้ว่า test data คืออะไร และทำไมมันถึงสำคัญ
- แยกแยะ static vs dynamic test data ได้
- เข้าใจหลักการ test data independence
- รู้วิธีจัดการข้อมูลที่ sensitive ใน test
- ออกแบบ test data strategy สำหรับ scenario จริงได้
ทีม QA ของระบบ HR มี automation test 150 เคสที่รันทุกเช้า 6 โมง test ทั้งหมดใช้ข้อมูลพนักงานชุดเดียวกันในฐานข้อมูล staging
วันหนึ่ง test fail 40 เคสพร้อมกัน สาเหตุคือ:
- ทีม dev รัน script อัปเดตข้อมูลเงินเดือนบน staging เมื่อคืน
- พนักงาน "สมชาย" ที่ test ใช้เช็คยอดเงินเดือน ถูกเปลี่ยนจาก 50,000 เป็น 55,000
- พนักงาน "สมหญิง" ถูกลบออกจากระบบเพราะ dev ทดสอบ feature ลบพนักงาน
- สถานะของ "สมศักดิ์" ถูกเปลี่ยนจาก "active" เป็น "resigned"
ทีมเสียเวลา 2 วัน กว่าจะแยกได้ว่าไม่มีบั๊กจริง — แค่ data เปลี่ยน
บทเรียน: test ที่พึ่งพา shared data ที่ใครก็แก้ได้ = ระเบิดเวลา
Static Test Data
- ข้อมูลที่เตรียมไว้ล่วงหน้าและไม่เปลี่ยนแปลง
- เช่น: fixture files, seed data, hardcoded values
- ข้อดี: predictable, ง่ายต่อการ debug
- ข้อเสีย: อาจ outdated, ไม่ครอบคลุม edge case, ต้อง maintain
Dynamic Test Data
- ข้อมูลที่ถูกสร้างขึ้นใหม่ทุกรอบการทดสอบ
- เช่น: generated users, random values, API-created data
- ข้อดี: สดใหม่เสมอ, ทดสอบ edge case ได้กว้างกว่า
- ข้อเสีย: debug ยากกว่า (ค่าเปลี่ยนทุกรอบ), ต้อง cleanup
เมื่อไหร่ใช้อะไร?
| สถานการณ์ | แนะนำ |
|---|---|
| Reference data (รหัสจังหวัด, ประเภทสินค้า) | Static |
| User accounts สำหรับ login test | Static (dedicated test accounts) |
| Order/transaction data | Dynamic (สร้างใหม่ทุกรอบ) |
| Form validation test | Dynamic (generate ค่าที่ valid/invalid) |
| Performance test | Dynamic (volume ที่ต้องการ) |
หลักการสร้าง test data ที่ดี
- Realistic — ใกล้เคียงข้อมูลจริง (ชื่อคนจริง ไม่ใช่ "test123")
- Unique — ไม่ซ้ำกันระหว่าง test run (ใส่ timestamp หรือ random suffix)
- Self-contained — test สร้าง data ที่ต้องการเอง ไม่พึ่งพา data ที่อาจถูกแก้
- Traceable — ระบุได้ว่า data ถูกสร้างโดย test ไหน (prefix เช่น "AUTO_")
ตัวอย่าง
| แบบแย่ | แบบดี |
|---|---|
| email: [email protected] | email: [email protected] |
| name: test | name: AUTO_สมชาย_ทดสอบ_1710489022 |
| phone: 0812345678 | phone: 089XXXRANDOM |
ทุกครั้งที่ test สร้าง data ต้องมีแผนว่าจะจัดการกับมันอย่างไร
กลยุทธ์ Cleanup
Teardown after each test — ลบ data ที่สร้างไว้หลังจบแต่ละ test
- ข้อดี: environment สะอาดเสมอ
- ข้อเสีย: ช้าลง, ถ้า teardown fail จะมี orphaned data
Dedicated test database — ใช้ database แยกสำหรับ test แล้ว reset ทั้งก้อน
- ข้อดี: สะอาดที่สุด, ไม่กระทบใคร
- ข้อเสีย: ต้อง setup infrastructure เพิ่ม
Prefix + periodic cleanup — ใส่ prefix "AUTO_" แล้วมี scheduled job ลบ
- ข้อดี: ง่าย, ไม่ต้อง cleanup ทุกรอบ
- ข้อเสีย: data สะสมชั่วคราว
แนวคิดที่แยก test logic กับ test data ออกจากกัน:
- เขียน test case เดียว
- ให้ data หลายชุดวิ่งผ่าน test เดียวกัน
ตัวอย่าง: ทดสอบ login
แทนที่จะเขียน 5 test cases:
- test login ด้วย email ถูก + password ถูก
- test login ด้วย email ผิด
- test login ด้วย password ผิด
- test login ด้วย email ว่าง
- test login ด้วย password ว่าง
เขียน test case เดียว แล้วให้ data 5 ชุดวิ่งผ่าน:
| password | expected result | |
|---|---|---|
| [email protected] | correct123 | login success |
| [email protected] | correct123 | "อีเมลไม่ถูกต้อง" |
| [email protected] | wrong | "รหัสผ่านไม่ถูกต้อง" |
| (empty) | correct123 | "กรุณากรอกอีเมล" |
| [email protected] | (empty) | "กรุณากรอกรหัสผ่าน" |
ข้อดี: เพิ่ม test case ใหม่แค่เพิ่ม data row ไม่ต้องเขียน test logic ซ้ำ
สิ่งที่ห้ามอยู่ใน test data
- รหัสผ่านจริงของใครก็ตาม
- เลขบัตรเครดิตจริง
- เลขบัตรประชาชนจริง
- ข้อมูลส่วนบุคคลจริงของลูกค้า (ชื่อ-สกุล, ที่อยู่, เบอร์โทร)
วิธีจัดการ
- Fake data — ใช้ข้อมูลปลอม (fake name generator, test credit card numbers)
- Masking — เอาข้อมูลจริงมาปิดบัง (เช่น ชื่อจริง → hash)
- Environment variables — เก็บ credentials ใน env vars ไม่ใช่ใน code
- Test credit cards — ใช้เลขบัตรที่ payment gateway ให้สำหรับ testing
หลักการ: แต่ละ test ต้องจัดการ data ของตัวเองได้โดยไม่พึ่งพา test อื่น
ตัวอย่างปัญหา
Test A: สร้าง order #001
Test B: เช็คว่า order #001 มี status "pending"
Test C: อัปเดต order #001 เป็น "shipped"
Test D: เช็คว่า order #001 มี status "shipped"
ถ้า Test A fail → Test B, C, D fail หมด (cascade failure) ถ้ารัน Test C ก่อน Test B → Test B fail เพราะ status ไม่ใช่ "pending" แล้ว
วิธีแก้
Test B: สร้าง order ใหม่ → เช็คว่ามี status "pending"
Test C: สร้าง order ใหม่ → อัปเดตเป็น "shipped" → เช็ค
Test D: สร้าง order ที่มี status "shipped" → เช็ค
แต่ละ test สร้าง data ของตัวเอง → รันลำดับไหนก็ได้ → ไม่กระทบกัน
โจทย์
คุณต้องออกแบบ test data strategy สำหรับ ระบบสั่งอาหารออนไลน์ ที่มี features:
- สมัครสมาชิก / login
- ค้นหาร้านอาหาร
- สั่งอาหาร (เพิ่ม/ลบ items, คำนวณราคา)
- ชำระเงิน (บัตรเครดิต, โอนเงิน, COD)
- ติดตามสถานะ order
- ให้คะแนนร้านอาหาร
คำถาม:
- data อะไรควรเป็น static? อะไรควรเป็น dynamic?
- จะจัดการ sensitive data (บัตรเครดิต) อย่างไร?
- จะทำ cleanup อย่างไร?
- ออกแบบ data-driven test สำหรับ feature ชำระเงิน
ดูคำตอบแนะนำ
1. Static vs Dynamic:
- Static: ข้อมูลร้านอาหาร (ชื่อ, เมนู, ราคา), ข้อมูล test accounts สำหรับ login, รหัสโปรโมชั่นสำหรับทดสอบ
- Dynamic: orders (สร้างใหม่ทุกรอบ), user registration (ใช้ email unique ทุกรอบ), reviews/ratings
2. Sensitive data:
- ใช้ test credit card numbers ที่ payment gateway ให้ (เช่น Stripe test cards: 4242424242424242)
- เก็บ API keys ใน environment variables
- ไม่เก็บ credentials ใน test code หรือ version control
- ใช้ fake names/addresses จาก data generator
3. Cleanup:
- Orders: ใส่ prefix "AUTO_TEST_" + teardown หลังจบ test
- User registrations: ใช้ dedicated test domain (e.g., @autotest.local) + periodic cleanup
- Reviews: teardown after each test เพราะอาจ affect ค่าเฉลี่ยคะแนนร้าน
4. Data-driven test สำหรับชำระเงิน:
| วิธีชำระ | ยอดเงิน | โปรโมชั่น | expected |
|---|---|---|---|
| บัตรเครดิต (valid) | ฿350 | ไม่มี | สำเร็จ, ยอด ฿350 |
| บัตรเครดิต (valid) | ฿350 | ลด 10% | สำเร็จ, ยอด ฿315 |
| บัตรเครดิต (declined) | ฿350 | ไม่มี | "บัตรถูกปฏิเสธ" |
| โอนเงิน | ฿500 | ไม่มี | สำเร็จ, แสดง QR code |
| COD | ฿200 | ไม่มี | สำเร็จ, ไม่เก็บเงินทันที |
| COD | ฿5,000 | ไม่มี | "ยอด COD สูงสุด ฿3,000" |
สิ่งที่ต้องเอาติดตัวไปจากบทนี้
- Test data ที่ดี คือ data ที่ predictable, independent, และ traceable
- Static data เหมาะกับ reference data / Dynamic data เหมาะกับ transactional data
- Test data independence = แต่ละ test จัดการ data ของตัวเอง ไม่พึ่งพา test อื่น
- อย่าเอาข้อมูลจริง (โดยเฉพาะ PII และ financial data) มาใช้ใน test
- Data cleanup ต้องวางแผนตั้งแต่ต้น ไม่ใช่มาคิดทีหลัง