ทดสอบ JavaScript ด้วย Jest
ในโลกของการพัฒนาซอฟต์แวร์ การทดสอบ (Testing) เป็นส่วนสำคัญที่ช่วยให้มั่นใจได้ว่าโค้ดที่เราเขียนทำงานได้อย่างถูกต้องตามที่คาดหวัง ลดข้อผิดพลาด และทำให้การแก้ไขปรับปรุงโค้ดในอนาคตเป็นไปได้ง่ายขึ้น ในบทความนี้ เราจะมาเรียนรู้เกี่ยวกับการทำ Unit Test ใน JavaScript โดยใช้ Jest ซึ่งเป็น Testing Framework ที่ได้รับความนิยมอย่างมาก
Jest เป็น Testing Framework ที่พัฒนาโดย Facebook มีจุดเด่นคือ ใช้งานง่าย, มี Mocking ในตัว, ทำงานได้รวดเร็ว, และรองรับการทำงานแบบ Parallel Testing ทำให้ Jest เป็นตัวเลือกที่น่าสนใจสำหรับโปรเจกต์ JavaScript ของคุณ
ทำไมต้องทำ Unit Test?
ก่อนที่จะไปดูวิธีการใช้งาน Jest เรามาทำความเข้าใจกันก่อนว่าทำไม Unit Test ถึงมีความสำคัญ:
- ลดข้อผิดพลาด: Unit Test ช่วยให้เราตรวจจับข้อผิดพลาดในโค้ดได้ตั้งแต่เนิ่นๆ ก่อนที่จะถูกรวมเข้ากับส่วนอื่นๆ ของระบบ
- ปรับปรุงคุณภาพโค้ด: การเขียน Unit Test ทำให้เราต้องคิดถึงการออกแบบโค้ดให้สามารถทดสอบได้ง่าย ซึ่งนำไปสู่โค้ดที่มีโครงสร้างที่ดีขึ้น
- เพิ่มความมั่นใจในการแก้ไขโค้ด: เมื่อเรามีการแก้ไขโค้ด Unit Test จะช่วยให้เรามั่นใจได้ว่าการเปลี่ยนแปลงของเราไม่ได้ทำให้ส่วนอื่นๆ ของระบบเสียหาย
- ช่วยในการ Refactoring: เมื่อเราต้องการปรับปรุงโครงสร้างโค้ด (Refactoring) Unit Test จะเป็นตัวช่วยยืนยันว่าฟังก์ชันการทำงานเดิมยังคงถูกต้อง
- เอกสารประกอบโค้ด: Unit Test สามารถทำหน้าที่เป็นเอกสารประกอบโค้ดได้ โดยแสดงให้เห็นว่าฟังก์ชันหรือคลาสต่างๆ ทำงานอย่างไร
Trade-off: การเขียน Unit Test ต้องใช้เวลาและทรัพยากร แต่ผลตอบแทนที่ได้คือโค้ดที่มีคุณภาพสูงขึ้น ลดค่าใช้จ่ายในการแก้ไขข้อผิดพลาดในระยะยาว และเพิ่มความมั่นใจในการพัฒนาซอฟต์แวร์
ติดตั้ง Jest
ในการเริ่มต้นใช้งาน Jest เราจะต้องติดตั้ง Jest ลงในโปรเจกต์ของเราก่อน โดยใช้ NPM หรือ Yarn
# ใช้ NPM
npm install --save-dev jest
# หรือใช้ Yarn
yarn add --dev jest
หลังจากติดตั้ง Jest แล้ว เราจะต้องเพิ่ม script สำหรับการรัน Test ในไฟล์ package.json ของเรา
{
"scripts": {
"test": "jest"
}
}
เมื่อเราเพิ่ม script นี้แล้ว เราสามารถรัน Test ได้โดยใช้คำสั่ง npm test หรือ yarn test
เขียน Test Case
เมื่อเราติดตั้ง Jest เรียบร้อยแล้ว เรามาลองเขียน Test Case กัน
สมมติว่าเรามีฟังก์ชันง่ายๆ ที่ใช้ในการบวกเลขสองจำนวน
// math.js
function add(a, b) {
return a + b;
}
module.exports = add;
เราจะสร้างไฟล์ Test สำหรับฟังก์ชันนี้ โดยตั้งชื่อว่า math.test.js (หรือ math.spec.js ก็ได้) โดย Jest จะค้นหาไฟล์ที่ลงท้ายด้วย .test.js หรือ .spec.js โดยอัตโนมัติ
// math.test.js
const add = require('./math');
test('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3);
});
ใน Test Case นี้ เราใช้ฟังก์ชัน test() เพื่อกำหนด Test Case หนึ่งๆ โดย argument แรกคือคำอธิบายของ Test Case และ argument ที่สองคือ Callback Function ที่จะรัน Test Logic
ภายใน Callback Function เราใช้ expect() เพื่อกำหนดสิ่งที่เราคาดหวัง (Expected Value) จากการทำงานของฟังก์ชัน add() และใช้ toBe() ซึ่งเป็น Matcher ที่ใช้ในการเปรียบเทียบค่าว่าเท่ากันหรือไม่
Matchers: Jest มี Matchers ให้เราเลือกใช้มากมาย เช่น
toBe(value): ตรวจสอบว่าค่าเท่ากัน (ใช้Object.isในการเปรียบเทียบ)toEqual(value): ตรวจสอบว่าค่าเท่ากันอย่างละเอียด (Deep Equality) เหมาะสำหรับ Object และ ArraytoBeNull(): ตรวจสอบว่าเป็นnulltoBeUndefined(): ตรวจสอบว่าเป็นundefinedtoBeDefined(): ตรวจสอบว่าไม่ได้เป็นundefinedtoBeTruthy(): ตรวจสอบว่าเป็น Truthy Value (ค่าที่แปลงเป็นtrueได้)toBeFalsy(): ตรวจสอบว่าเป็น Falsy Value (ค่าที่แปลงเป็นfalseได้)toBeGreaterThan(number): ตรวจสอบว่ามากกว่าtoBeLessThan(number): ตรวจสอบว่าน้อยกว่าtoBeGreaterThanOrEqual(number): ตรวจสอบว่ามากกว่าหรือเท่ากับtoBeLessThanOrEqual(number): ตรวจสอบว่าน้อยกว่าหรือเท่ากับtoContain(item): ตรวจสอบว่ามี Item ใน ArraytoThrow(error): ตรวจสอบว่าเกิด Error
การเลือกใช้ Matcher ที่เหมาะสมจะช่วยให้ Test Case ของเรามีความชัดเจนและสื่อความหมายได้ดีขึ้น
Run Test
หลังจากที่เราเขียน Test Case แล้ว เราสามารถรัน Test ได้โดยใช้คำสั่ง npm test หรือ yarn test
npm test
Jest จะทำการค้นหาไฟล์ Test และรัน Test Case ที่อยู่ในไฟล์เหล่านั้น หาก Test Case ผ่าน (Pass) Jest จะแสดงข้อความสีเขียว หาก Test Case ไม่ผ่าน (Fail) Jest จะแสดงข้อความสีแดง พร้อมทั้งรายละเอียดของข้อผิดพลาด
Test Driven Development (TDD): เทคนิคการพัฒนาซอฟต์แวร์โดยการเขียน Test Case ก่อนที่จะเขียนโค้ดจริง ทำให้เราต้องคิดถึงความต้องการของระบบอย่างละเอียดตั้งแต่เริ่มต้น และช่วยให้เรามั่นใจได้ว่าโค้ดที่เราเขียนตรงตามความต้องการ
ตัวอย่าง Test Case เพิ่มเติม
สมมติว่าเรามีฟังก์ชันที่ใช้ในการตรวจสอบว่าตัวเลขเป็นเลขคู่หรือไม่
// isEven.js
function isEven(number) {
return number % 2 === 0;
}
module.exports = isEven;
เราสามารถเขียน Test Case สำหรับฟังก์ชันนี้ได้ดังนี้
// isEven.test.js
const isEven = require('./isEven');
test('returns true if number is even', () => {
expect(isEven(2)).toBe(true);
expect(isEven(4)).toBe(true);
expect(isEven(10)).toBe(true);
});
test('returns false if number is odd', () => {
expect(isEven(1)).toBe(false);
expect(isEven(3)).toBe(false);
expect(isEven(9)).toBe(false);
});
ใน Test Case นี้ เราได้แบ่ง Test Case ออกเป็นสองส่วน ส่วนแรกตรวจสอบว่าฟังก์ชัน isEven() คืนค่า true เมื่อได้รับเลขคู่ ส่วนที่สองตรวจสอบว่าฟังก์ชัน isEven() คืนค่า false เมื่อได้รับเลขคี่
สรุป
การทดสอบ (Testing) เป็นส่วนสำคัญของการพัฒนาซอฟต์แวร์ การใช้ Jest ช่วยให้เราเขียน Unit Test ได้ง่ายและรวดเร็ว ทำให้เรามั่นใจได้ว่าโค้ดของเราทำงานได้อย่างถูกต้อง และลดข้อผิดพลาดที่อาจเกิดขึ้นในอนาคต การเขียน Unit Test ไม่ใช่เรื่องยาก แต่ต้องอาศัยการฝึกฝนและการทำความเข้าใจแนวคิดพื้นฐาน หวังว่าบทความนี้จะเป็นประโยชน์สำหรับผู้เริ่มต้นใช้งาน Jest และช่วยให้คุณเริ่มต้นเขียน Unit Test สำหรับโปรเจกต์ JavaScript ของคุณได้
ในบทความถัดไป เราจะมาเรียนรู้เกี่ยวกับ Best Practices ในการเขียน JavaScript เพื่อให้โค้ดของเรามีคุณภาพสูงขึ้น อ่านง่าย และบำรุงรักษาได้ง่าย