Automated Testing ใน CI Pipeline: Unit Test, Integration Test, E2E Test
ในโลกของ Software Development ที่เปลี่ยนแปลงอย่างรวดเร็ว Automated Testing ได้กลายมาเป็นส่วนสำคัญที่ไม่สามารถพลาดได้เมื่อพูดถึง Continuous Integration (CI) Pipeline การทำ Test แบบอัตโนมัติช่วยให้ทีมพัฒนาสามารถจับ Bug ได้เร็วขึ้น ลดต้นทุนการบำรุงรักษา และมั่นใจได้ว่าโค้ดใหม่ไม่ทำให้ฟังก์ชันเดิมหยุดทำงาน บทความนี้จะนำเสนอแนวทางการใช้งาน Automated Testing ในลักษณ์ต่าง ๆ และวิธีการผสมผสานเข้ากับ CI Pipeline ของคุณ
Automated Testing คืออะไร ทำไมต้องทำใน CI Pipeline
Automated Testing คือกระบวนการทดสอบซอฟต์แวร์โดยใช้ Script หรือเครื่องมือเฉพาะเพื่อตรวจสอบความถูกต้องของโค้ดโดยอัตโนมัติ แทนการทำ Manual Testing ด้วยมนุษย์ซ้ำ ๆ การทำ Automated Testing ใน CI Pipeline มีความสำคัญหลายประการ:
- ตรวจจับ Bug เร็ว: เมื่อมีการ Push Code ใหม่ Test จะทำงานโดยอัตโนมัติ และแจ้งเตือนหากพบปัญหา
- ประหยัดเวลา: ไม่ต้องทำ Manual Testing ซ้ำ ๆ โปรแกรมเมอร์สามารถเน้นที่การพัฒนาฟีเจอร์ใหม่
- ลดความเสี่ยง: ทำให้การ Deploy เป็นไปอย่างมั่นใจมากขึ้น เพราะรู้ว่าโค้ดที่ Deploy นั้นผ่านการทดสอบแล้ว
- บำรุงรักษาง่าย: หากต้องการแก้ Bug หรือ Refactor Code สามารถตรวจสอบได้ว่ามีสิ่งที่เสียหายหรือไม่
- ความยืดหยุ่น: ช่วยให้ทีม Deploy บ่อยขึ้นและรวดเร็วขึ้น ซึ่งเป็นเป้าหมายของ DevOps
ประเภทของ Test: Unit Test, Integration Test, E2E Test
Automated Testing มีหลายระดับ แต่ละระดับมีวัตถุประสงค์และขอบเขตการทดสอบที่แตกต่างกัน ลองมาดูความแตกต่างของแต่ละประเภท:
1. Unit Test
Unit Test เป็นการทดสอบ Function หรือ Method เดี่ยว ๆ ในระดับที่เล็กที่สุด โดยแยกมันออกจากส่วนอื่น ๆ ของระบบ
- ขอบเขต: ทดสอบ Function หรือ Class เดี่ยว
- ความเร็ว: รวดเร็วมากที่สุด (มิลลิวินาที)
- Mocking: ใช้ Mock Objects เพื่อแยกส่วนที่ทดสอบ
- จำนวน: ควรมี Unit Test จำนวนมากที่สุด
2. Integration Test
Integration Test ทดสอบการทำงานของหลาย Component หรือ Module เมื่อมาทำงานร่วมกัน ตรวจสอบว่าส่วนต่าง ๆ สามารถสื่อสารและทำงานกันได้อย่างถูกต้อง
- ขอบเขต: ทดสอบหลาย Component ที่ทำงานร่วมกัน
- ความเร็ว: ช้ากว่า Unit Test (วินาที)
- Database: อาจต้องใช้ฐานข้อมูลทดสอบจริง
- จำนวน: ควรมี Integration Test น้อยกว่า Unit Test
3. E2E Test (End-to-End Test)
E2E Test ทดสอบแอปพลิเคชันทั้งหมดจากมุมมองของผู้ใช้ (User Journey) ตั้งแต่เริ่มต้นจนถึงจบ เช่น การล็อกอิน การเพิ่มสินค้าลงตะกร้า และการชำระเงิน
- ขอบเขต: ทดสอบแอปพลิเคชันทั้งหมดในสิ่งแวดล้อมที่เหมือนการใช้จริง
- ความเร็ว: ช้าที่สุด (นาที)
- Browser: จำลองการกระทำของผู้ใช้จริง (click, type, scroll)
- จำนวน: ควรมี E2E Test ที่สำคัญเท่านั้น
Testing Pyramid: การสมดุลระหว่าง Test ต่าง ๆ
Testing Pyramid เป็นแนวคิดที่แนะนำว่า ควรทำให้มี Unit Test จำนวนมาก Integration Test จำนวนปานกลาง และ E2E Test จำนวนน้อยสุด เพราะเหตุผลคือ:
- Unit Test รวดเร็ว สามารถเขียนได้เยอะ และให้ Coverage สูง
- Integration Test ช่วยให้แน่ใจว่า Component ต่าง ๆ ทำงานร่วมกันได้
- E2E Test ทำได้ช้า แต่ยืนยันการใช้งานจริงของระบบ
สัดส่วนที่แนะนำ:
| ประเภท Test | สัดส่วน | เวลา |
| Unit Test | 70-80% | เร็ว (มิลลิวินาที) |
| Integration Test | 15-20% | ปานกลาง (วินาที) |
| E2E Test | 5-10% | ช้า (นาที) |
Unit Testing Framework
Jest (JavaScript/TypeScript)
Jest เป็น Testing Framework ยอดนิยมสำหรับ JavaScript และ React โดย Facebook พัฒนา
- เขียนได้ง่าย มี Built-in Assertion Library
- รองรับ Snapshot Testing และ Mock
- ความเร็วสูง ด้วย Parallel Execution
- Coverage Report ออกมาสวยงาม
Pytest (Python)
Pytest เป็น Testing Framework ที่มีความยืดหยุ่นสูงสำหรับ Python
- Syntax ที่ง่ายและอ่านเข้าใจได้
- รองรับ Fixture สำหรับการเตรียม Setup
- Plugin ที่หลากหลายเพื่อขยายความสามารถ
Integration & E2E Testing Tools
Cypress
Cypress เป็น Modern E2E Testing Framework ที่ให้ความสะดวกสูงในการเขียน Test
- Visual Feedback ขณะ Test ทำงาน
- API ที่ใช้งานง่าย สำหรับ Interaction กับ Browser
- Debugging Tools ที่ทรงพลัง
- รองรับการทำ Screenshot และ Video Recording
Playwright
Playwright เป็น Modern Automation Library ที่พัฒนาโดย Microsoft เพื่อ Cross-browser Testing
- รองรับ Chromium, Firefox, WebKit
- เร็วและเสถียร
- สามารถทำ Multi-device Testing และ Visual Testing
1. เขียน Test ก่อน Code (Test-Driven Development)
วิธีการ TDD (Test-Driven Development) ให้คุณเขียน Test ก่อน เพื่อเป็น Specification ของ Code ที่ต้องการ จากนั้นค่อยเขียน Implementation เพื่อให้ Test ผ่าน
2. ให้ Test ชื่ออย่างชัดเจน
ชื่อ Test ควรอธิบายสิ่งที่ Test นั้นทำ และสิ่งที่คาดหวัง เช่น should_return_error_when_email_is_invalid
3. ใช้ Arrange-Act-Assert Pattern
แบ่ง Test ออกเป็น 3 ส่วน: Arrange (เตรียมข้อมูล), Act (ทำการ Test), Assert (ตรวจสอบผล)
4. ทำให้ Test Isolated และ Independent
Test แต่ละตัวควรสามารถทำงานได้อย่างอิสระ และไม่ควรพึ่งพิงกันเพื่อให้มั่นใจว่า Test ทำงานได้ถูกต้องทั้งเมื่อทำงานเดี่ยวและเมื่อทำงานร่วมกัน
5. ใช้ Mock และ Stub อย่างเหมาะสม
Mock ใช้สำหรับ Replace External Dependencies เพื่อ Control Input/Output ของ Test ซึ่งช่วยให้ Test ทำงานไม่ขึ้นกับ External Service
6. Keep Test Fast
Test ควรทำงานเร็ว เพราะว่า Test Suite ที่ช้าจะทำให้ Developer ไม่อยากรัน Test บ่อย เหตุผลที่ทำให้ Test ช้า:
- Database Query ที่ช้า → ใช้ In-Memory Database แทน
- API Call ที่ช้า → Mock API Response
- File I/O ที่ช้า → Mock File System
Code Coverage และ Test Reports
Code Coverage คือการวัดว่าโค้ดของคุณได้รับการ Test คร่อมตัวกี่เปอร์เซ็นต์ เป็นตัวชี้วัดที่สำคัญสำหรับคุณภาพของ Test Suite
บทสรุป
Automated Testing เป็นส่วนสำคัญของ Modern Software Development ที่ช่วยให้คุณ Deploy Code ได้อย่างมั่นใจ โดยการผสมผสาน Unit Test, Integration Test, และ E2E Test ในสัดส่วนที่ถูกต้องตามแบบ Testing Pyramid เราสามารถสร้าง Test Suite ที่มีประสิทธิภาพและสามารถจับ Bug ได้เร็ว
เมื่อ Deploy แอปพลิเคชันของคุณไปยังโปรดักชั่น การมี Automated Testing ที่ดีจะทำให้คุณรู้สึกมั่นใจมากขึ้นว่า Code ที่ Deploy นั้นมีคุณภาพดีและปราศจากจาก Bug ที่อาจทำให้ Service หยุดทำงาน
