หมวดหมู่: typescript

Unit Testing Frameworks: การเขียน Unit Test และ Assertion ด้วย Jest / Vitest สำหรับ JavaScript/TypeScriptUnit Testing Frameworks: การเขียน Unit Test และ Assertion ด้วย Jest / Vitest สำหรับ JavaScript/TypeScript

ในโลกของการพัฒนาซอฟต์แวร์ที่โค้ดเบสมีขนาดใหญ่ขึ้นเรื่อยๆ ความเสี่ยงในการเกิดบั๊ก (Bugs) ก็เพิ่มตามไปด้วย การพึ่งพาการทดสอบด้วยสายตาหรือการทดสอบแบบ End-to-End เพียงอย่างเดียวจึงไม่เพียงพออีกต่อไป เราจำเป็นต้องมีกลไกที่ช่วยรับประกันว่าแต่ละส่วนย่อยของโค้ดทำงานได้อย่างถูกต้องและเป็นอิสระจากส่วนอื่น ๆ ซึ่งนี่คือจุดกำเนิดของแนวคิด Unit Testing ที่เข้ามาเป็นรากฐานสำคัญของการพัฒนาคุณภาพสูง


เจาะลึกรายละเอียดและประเด็นสำคัญ

Unit Testing คือการทดสอบหน่วยที่เล็กที่สุดของแอปพลิเคชัน ซึ่งโดยทั่วไปคือฟังก์ชัน (Function) หรือคลาส (Class) ที่ถูกแยกออกมาให้ทำงานอย่างโดดเดี่ยว (Isolated) เครื่องมืออย่าง Jest และ Vitest ได้เข้ามาปฏิวัติวงการนี้ด้วยความเร็วในการรันเทสต์และการรองรับทั้ง JavaScript และ TypeScript ทำให้เราสามารถเขียนชุดทดสอบที่ครอบคลุมได้อย่างง่ายดาย

หัวใจสำคัญของการทำ Unit Test คือการใช้ Assertion ซึ่งเป็นคำสั่งที่เราใช้ยืนยันว่าผลลัพธ์ที่ได้จากการรันโค้ดนั้น “ควรจะเป็น” อย่างไร เช่น ถ้าเราเรียกฟังก์ชัน `add(2, 3)` เราต้อง Assert ว่าค่าที่ส่งกลับมาจะต้องเท่ากับ `5` การทำ Mocking และ Spying ก็เป็นเทคนิคสำคัญที่ช่วยให้เราสามารถจำลองการทำงานของ Dependency ภายนอก (เช่น API calls หรือ Database) เพื่อให้ Unit Test ของเราไม่ขึ้นอยู่กับสภาพแวดล้อมจริง

describe('Calculator', () => {
  // ทดสอบฟังก์ชันการบวก
  test('should correctly add two numbers', () => {
    const result = (a, b) => a + b;
    expect(result(1, 2)).toBe(3); // Assertion: คาดหวังว่าผลลัพธ์คือ 3
  });

  // ทดสอบฟังก์ชันที่ต้องมีการ Mocking Dependency
  test('should handle API call success', async () => {
    const mockFetch = jest.fn(() => Promise.resolve({ data: 'success' }));
    await apiService.fetchData(mockFetch); // ใช้ Mock เพื่อควบคุมผลลัพธ์ภายนอก
    expect(mockFetch).toHaveBeenCalledTimes(1);
  });
});

การนำไปประยุกต์ใช้ในชีวิตและการทำงานยุคใหม่

  • การสร้าง Safety Net สำหรับ Refactoring: เมื่อโค้ดเบสใหญ่ขึ้น การแก้ไขฟังก์ชันหนึ่งอาจส่งผลกระทบต่อส่วนอื่นโดยไม่ตั้งใจ ชุด Unit Test ที่แข็งแกร่งจะทำหน้าที่เป็นตาข่ายนิรภัย (Safety Net) ทำให้เรามั่นใจได้ว่าทุกครั้งที่เราปรับปรุงหรือเปลี่ยนโครงสร้างโค้ดเดิม ฟังก์ชันที่เคยทำงานได้ก็จะยังคงทำงานได้อย่างถูกต้อง
  • การบูรณาการกับ CI/CD Pipeline: ในสภาพแวดล้อมการพัฒนาสมัยใหม่ การรัน Unit Test เป็นขั้นตอนแรกและสำคัญที่สุดใน Continuous Integration (CI) เมื่อมีการ Commit โค้ดใหม่ ระบบจะเรียกใช้ชุดทดสอบทั้งหมดโดยอัตโนมัติ หากมีเทสต์ใดล้มเหลว (Test Failure) กระบวนการ Deploy จะถูกหยุดทันที ทำให้มั่นใจได้ว่าโค้ดที่ขึ้น Production นั้นผ่านการตรวจสอบคุณภาพมาแล้ว

สรุปได้ว่า การเรียนรู้และนำ Unit Testing Frameworks อย่าง Jest หรือ Vitest มาใช้ ไม่ใช่เพียงแค่การเพิ่มงานให้กับนักพัฒนา แต่เป็นการลงทุนในความยั่งยืนของโปรเจกต์ (Project Sustainability) มันช่วยลดภาระในการ Debugging ในระยะยาว เพิ่มความมั่นใจให้ทีม และทำให้เราสามารถทำงานร่วมกันบนโค้ดเบสขนาดใหญ่ได้อย่างมีประสิทธิภาพและปราศจากความเสี่ยงที่มองไม่เห็น


อ่านเพิ่มเติม