การตั้งชื่อและการดูแลรักษา
จบบทนี้แล้วคุณจะ...
- ตั้งชื่อ test ให้สื่อความหมายและค้นหาง่าย
- จัดกลุ่ม test ด้วย tagging/labeling ได้อย่างมีระบบ
- เข้าใจต้นทุนของ maintenance และวิธีจัดการ
- รู้วิธีจัดการกับ flaky tests
- ตัดสินใจได้ว่าเมื่อไหร่ควรลบ test ออก
ทีม QA ของบริษัทประกันภัยภูมิใจมากที่สร้าง automation test ได้ 2,000 เคสภายใน 2 ปี จำนวนเพิ่มขึ้นเรื่อย ๆ ทุก sprint
แต่ปัญหาค่อย ๆ สะสม:
- 30% ของ test (600 เคส) เป็น flaky — fail แบบ random ไม่ใช่เพราะบั๊กจริง
- ทีมต้องใช้เวลา 2-3 ชั่วโมงต่อวัน ในการ re-run และ investigate flaky tests
- ชื่อ test ไม่สื่อ เช่น
test_001,test_new,test_flow_A— ไม่รู้ว่าทดสอบอะไร - ไม่มีใครกล้าลบ test เพราะกลัวว่า "อาจจะยังใช้อยู่"
- คนใหม่ที่เข้ามาในทีมต้องใช้เวลา 2 สัปดาห์กว่าจะเข้าใจว่า test ไหนทำอะไร
ผลลัพธ์: ทีมเสียเวลามากกว่า 50% ของเวลาทำงานในการ maintain test แทนที่จะเพิ่ม test coverage ใหม่
บทเรียน: จำนวน test ไม่ใช่เป้าหมาย — test ที่ maintain ได้คือเป้าหมาย
หลักการตั้งชื่อ
ชื่อ test ที่ดีต้องบอกได้ 3 อย่าง:
- ทดสอบอะไร (feature/function)
- สถานการณ์อะไร (condition/input)
- ผลลัพธ์ที่คาด (expected outcome)
Pattern: [feature] [scenario] [expected result]
| แบบแย่ | แบบดี |
|---|---|
| test_001 | login ด้วย credentials ที่ถูกต้อง ควร redirect ไปหน้า dashboard |
| test_login | login ด้วย email ที่ไม่มีในระบบ ควรแสดง error "ไม่พบบัญชี" |
| test_cart_new | เพิ่มสินค้าลงตะกร้าเมื่อตะกร้าว่าง ควรแสดงจำนวน 1 ชิ้น |
| test_flow_A | ค้นหาสินค้าด้วยชื่อที่มีอยู่ ควรแสดงผลลัพธ์ที่ตรงกัน |
| test_checkout | ชำระเงินด้วยบัตรที่ถูก declined ควรแสดง error "บัตรถูกปฏิเสธ" |
Naming Format ในภาษาต่าง ๆ
// English (common format)
"should redirect to dashboard when login with valid credentials"
"should show error when email is not registered"
// Thai (ใช้ในรายงาน)
"ควร redirect ไปหน้า dashboard เมื่อ login ด้วย credentials ที่ถูกต้อง"
"ควรแสดง error เมื่ออีเมลไม่ได้ลงทะเบียน"
ทำไมต้อง tag
เมื่อมี test 500 เคส คุณไม่ต้องการรันทั้งหมดทุกครั้ง:
- ก่อน deploy → รันแค่ @smoke (critical paths)
- หลัง sprint → รันทั้ง @regression
- เฉพาะ feature ที่แก้ → รันแค่ @cart หรือ @payment
ประเภท Tags ที่นิยม
| ประเภท | ตัวอย่าง | ใช้เมื่อ |
|---|---|---|
| Priority | @smoke, @critical, @low | เลือกรัน test ตามความสำคัญ |
| Feature | @auth, @cart, @payment, @search | รันเฉพาะ feature ที่ต้องการ |
| Type | @regression, @sanity, @e2e | รันตามประเภทของ test |
| Status | @flaky, @skip, @wip | track สถานะของ test |
| Speed | @fast, @slow | เลือกรัน test ที่เร็วก่อน |
ข้อควรระวัง
- อย่ามี tag มากเกินไป — 5-10 ประเภทก็พอ
- ทุก test ต้องมีอย่างน้อย 1 feature tag + 1 priority tag
- review tags เป็นประจำ — tag ที่ไม่มีใครใช้ให้ลบทิ้ง
ต้นทุนที่ซ่อนอยู่
ทุก test ที่เขียนมี "ค่าบำรุงรักษา" ตลอดชีวิต:
| กิจกรรม | เวลาที่ใช้ (ต่อ test ต่อเดือน) |
|---|---|
| อัปเดต locator เมื่อ UI เปลี่ยน | 15-30 นาที |
| Investigate flaky failure | 30-60 นาที |
| อัปเดต test data | 10-20 นาที |
| อัปเดตเมื่อ business logic เปลี่ยน | 30-60 นาที |
| Review และ code review | 15-30 นาที |
test 1 เคสอาจใช้เวลา maintain 1-3 ชั่วโมงต่อเดือน → 2,000 เคส = 2,000-6,000 ชั่วโมงต่อเดือน
วิธีลด maintenance cost
- ใช้ Page Object Model — UI เปลี่ยน แก้ที่เดียว
- ใช้ stable locators — data-testid, semantic locators
- Test data independence — ไม่พึ่งพา shared data
- Explicit waits — ไม่ใช้ sleep()
- ลบ test ที่ไม่จำเป็น — ดีกว่า maintain test ที่ไม่มีค่า
Flaky test คืออะไร
test ที่ให้ผลลัพธ์ไม่คงที่ — บางรอบ pass บางรอบ fail โดยไม่มีการเปลี่ยนแปลง code
สาเหตุหลัก
- Timing issues — ไม่รอให้ element พร้อม (ใช้ sleep หรือ wait ไม่เพียงพอ)
- Test data dependency — พึ่งพา data ที่ถูกแก้โดย test อื่น
- Environment instability — server ช้า, network ไม่เสถียร
- Order dependency — test ต้องรันเรียงลำดับ
- Race conditions — หลาย test แข่งกัน access resource เดียวกัน
วิธีจัดการ
ระยะสั้น:
- Tag flaky tests ด้วย @flaky เพื่อ track
- แยก flaky tests ออกจาก main suite — อย่าให้ block deployment
- ตั้ง retry policy (re-run ไม่เกิน 2 ครั้ง)
ระยะยาว:
- วิเคราะห์สาเหตุรากของ flakiness ทีละตัว
- แก้ timing issues ด้วย explicit waits
- แก้ data dependency ด้วย test data independence
- ลบ test ที่ไม่สามารถ stabilize ได้ แล้วเขียนใหม่
สัญญาณว่า test ควรถูกลบ
- Feature ถูกลบ — test สำหรับ feature ที่ไม่มีแล้ว
- Duplicate — test หลายตัวทดสอบสิ่งเดียวกัน
- Permanently flaky — แก้แล้วยังพัง ไม่คุ้มค่า maintain
- Low value — test ที่ทดสอบสิ่งที่ไม่สำคัญ (เช่น สี font)
- Covered by other tests — unit test ครอบคลุมแล้ว ไม่จำเป็นต้องมี E2E ซ้ำ
- ไม่มีใครเข้าใจ — test ที่ไม่มีใครรู้ว่าทำอะไร และไม่มี documentation
การตัดสินใจ
ถามตัวเอง:
- ถ้า test นี้ fail ตอนเช้า มันจะทำให้เราเจอบั๊กจริงไหม?
- ถ้าลบ test นี้ จะมีความเสี่ยงอะไรเพิ่มขึ้น?
- ต้นทุน maintain test นี้ คุ้มค่ากับความเสี่ยงที่มันป้องกันหรือเปล่า?
โจทย์ ส่วนที่ 1: Refactor Test Names
เปลี่ยนชื่อ test ต่อไปนี้ให้สื่อความหมาย:
test_001test_login_newtest_carttest_payment_v2test_search_fix
Context: ทั้งหมดเป็น test ของระบบ e-commerce
test_001ดูคำตอบแนะนำ
`test_001` → "login ด้วย username และ password ที่ถูกต้อง ควรเข้าสู่ระบบสำเร็จ"
แนวคิดคือชื่อใหม่ต้องบอกทั้ง feature, สถานการณ์ และผลลัพธ์ที่คาด ถ้าเปิดอ่าน code แล้วพบว่าเป็น happy path login ก็ควรตั้งชื่อให้ชัดแบบนี้
test_login_newดูคำตอบแนะนำ
test_login_new→ <strong>"login ด้วย email ที่ยังไม่ได้ verify ควรแสดง error ขอ verify email ก่อน"</strong>test_cartดูคำตอบแนะนำ
test_cart→ <strong>"เพิ่มสินค้า 3 ชิ้นลงตะกร้า ควรแสดงยอดรวมที่ถูกต้อง"</strong>test_payment_v2ดูคำตอบแนะนำ
test_payment_v2→ <strong>"ชำระเงินด้วย QR code ควรแสดง QR code ที่มียอดตรงกับตะกร้า"</strong>test_search_fixดูคำตอบแนะนำ
test_search_fix→ <strong>"ค้นหาสินค้าด้วยคำที่มี special characters ควรแสดงผลลัพธ์โดยไม่ error"</strong>
โจทย์ ส่วนที่ 2: ตัดสินว่า test ไหนควรลบ
| # | Test | สถานะ | หมายเหตุ |
|---|---|---|---|
| A | ทดสอบ feature "แชร์ไปยัง Google+" | Pass | Google+ ปิดให้บริการแล้ว |
| B | ทดสอบ login ด้วย Facebook | Flaky (6 เดือน) | แก้แล้ว 5 ครั้ง ยัง flaky อยู่ |
| C | ทดสอบสีปุ่ม "สั่งซื้อ" เป็นสีเขียว | Pass | UI team เปลี่ยนสีบ่อย |
| D | ทดสอบคำนวณภาษีมูลค่าเพิ่ม | Pass | critical business logic |
| E | ทดสอบ login ด้วย email ที่ถูกต้อง | Pass | มี test อื่นที่ครอบคลุม flow เดียวกัน 3 ตัว |
| F | ทดสอบ timeout เมื่อ API ไม่ตอบ | Pass | เป็น edge case ที่เคยเกิดจริง |
Test A
ดูคำตอบแนะนำ
<strong>ลบ</strong> เพราะ feature ไม่มีแล้ว test จึงไม่สร้างคุณค่าอีกต่อไป
Test B
ดูคำตอบแนะนำ
<strong>ลบแล้วเขียนใหม่</strong> เพราะ flaky ต่อเนื่องนานเกินไปไม่คุ้ม maintain ควรเปลี่ยน approach เช่นลดการพึ่ง UI เต็ม flow ถ้าทำได้
Test C
ดูคำตอบแนะนำ
<strong>ลบ</strong> เพราะเป็น test ที่เช็กสิ่งเปลี่ยนบ่อยและไม่ใช่ critical functionality ถ้าจำเป็นจริงควรใช้ visual regression หรือ design review แทน
Test D
ดูคำตอบแนะนำ
<strong>เก็บไว้</strong> เพราะเป็น critical business logic ที่มีผลกับความถูกต้องของระบบโดยตรง
Test E
ดูคำตอบแนะนำ
<strong>ลบ 2 ตัว เก็บ 1 ตัว</strong> ถ้าทั้ง 3 ตัวครอบคลุม flow เดียวกันจริง ควรเก็บตัวที่ชัดและเสถียรที่สุดเพื่อลด duplication
Test F
ดูคำตอบแนะนำ
<strong>เก็บไว้</strong> เพราะเป็น edge case ที่เคยเกิดจริง และช่วยกัน regression ในสถานการณ์สำคัญได้
สิ่งที่ต้องเอาติดตัวไปจากบทนี้
- ชื่อ test ที่ดี บอกได้ว่าทดสอบอะไร สถานการณ์อะไร ผลลัพธ์อะไร — ไม่ต้องเปิดอ่าน code
- Tags/Labels ช่วยจัดกลุ่มและเลือกรัน test ตามสถานการณ์ — ใช้ 5-10 ประเภทก็พอ
- ทุก test มีค่า maintenance — จำนวน test ไม่ใช่เป้าหมาย test ที่ maintain ได้คือเป้าหมาย
- Flaky tests ต้อง track, isolate, และแก้ไข — อย่าปล่อยให้สะสม
- กล้าลบ test ที่ไม่มีค่า — test 1,400 ตัวที่ stable ดีกว่า test 2,000 ตัวที่ 30% flaky