Skip to main content

สวัสดีครับกลับมาพบกับบทความป้ายยาเครื่องมือดี ๆ ใช้ฟรี ๆ กันอีกครั้ง! วันนี้ผมจะพาทุกคนไปรู้จักกับ Vitest เครื่องมือที่จะใช้ในการทดสอบโค้ดที่ใช้ง่าย และไวกัน 💨

Vitest คืออะไร?

Vitest เป็นเฟรมเวิร์กสำหรับทดสอบโค้ด JavaScript ที่ถูกพัฒนาโดย Vite ทีมพัฒนาเดียวกันกับ Vite.js ที่โด่งดังเรื่องความเร็วแรง เดี๋ยวนี้ตอนผมสร้างโปรเจกต์ React ก็ใช้เจ้า Vite นี่แหละ โดย Vitest จะรองรับการทดสอบทั้ง Unit Tests, Integration Tests และ End-to-End Tests แถม เร็วกว่า Jest ถึง 2-3 เท่า! เหมาะกับการทดสอบโค้ดจำนวนมาก

มือใหม่อยากลองเล่น เค้าก็มีเป็น Vitest Online ให้เราลองไปใช้ได้นะ https://stackblitz.com/edit/vitest-dev-vitest-2l5ntf?file=src%2Fbasic.ts,test%2Fbasic.test.ts&initialPath=__vitest__/

เริ่มต้นใช้งาน Vitest ในโปรเจกต์

1. ติดตั้ง Vitest

npm install -D vitest

โดยหมายเหตุไว้นิดนึงว่า Vitest 1.0 ต้องใช้ Vite >=v5.0.0 และ Node >=v18.00

2. เขียน Unit Test ด้วย Vitest

โดยเราจะมาเริ่มกันที่ฟังก์ชันง่าย ๆ อย่างฟังก์ชันที่ใช้ในการบวกเลขกัน  โดยการสร้างไฟล์ชื่อว่า sum.js โดยไฟล์นี้

// sum.js
export function sum(a, b) {
  return a + b
}

เมื่อเราได้ไฟล์หรือฟังก์ชันที่ต้องการทดสอบแล้วเราก็มาเขียนไฟล์ Test กันเลย โดยไฟล์ Test โดยไฟล์เทสจะต้องมีคำว่า “.test.” หรือ “.spec.” อยู่ในชื่อไฟล์ด้วย

// sum.test.js
import { expect, test } from 'vitest'
import { sum } from './sum'

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3)
})

สิ่งที่อยู่ในโค้ดตัวอย่าง (sum.test.js)

  1. import { expect, test } from 'vitest' : เรียกใช้งานโมดูล expect และ test จาก Vitest
  2. import { sum } from './sum' : โหลดฟังก์ชัน sum จากไฟล์ sum.js (ที่อยู่ในโฟลเดอร์เดียวกัน) เพื่อเอามารันเทส
  3. test('adds 1 + 2 to equal 3', () => { ... }) :
    • test : ฟังก์ชันสำหรับสร้าง test case หรือกรณีที่เราทดสอบ
    • 'adds 1 + 2 to equal 3' : ข้อความที่ใช้อธิบายว่า test case นี้ทำอะไร
  4. expect(sum(1, 2)).toBe(3) :
    • expect ใน Vitest คำสั่ง expect เป็นฟังก์ชันสำหรับสร้าง assertions เพื่อเอาไว้ดูว่าผลลัพธที่ได้จากโปรแกรมตรงกับค่าที่เราหวังมั้ย
    • expect(sum(1, 2)) : เป็นการเรียกฟังก์ชัน sum กับตัวเลข 1 และ 2 ใส่ไปใน expect เพื่อเอาค่าที่ได้นี้ไปเช็คกับ matcher ด้านล่าง
    • .toBe(3) : อันนี้เราเรียกว่า matcher ที่ชื่อ .toBe โดยมันจะทำการตรวจสอบว่าค่าใน Expect เท่ากันเป๊ะ ๆ กับ 3 มั้ย

โดย matcher ไม่ได้มีแค่ toBe เท่านั้น โดยใน Vitest มี matcher อื่น ๆ อีกมากมาย สามารถอ่านเพิ่มเติมเกี่ยวกับการใช้ matcher ได้ที่ลิงก์นี้ https://vitest.dev/api/expect-typeof.html#asserts

3. รันยังไง?

เมื่อเรามีฟังก์ชัน และเขียน Unit Test ให้กับฟังก์ชันเรียบร้อยแล้ว เราก็ต้องมาลองรันใช่มั้ยครับ โดยก่อนอื่นให้เราไปที่ไฟล์ package.json แล้วเปลี่ยนคำสั่ง test ใน scripts ให้เป็น vitest ดังนี้

package.json

{
  "scripts": {
    "test": "vitest"
  }
}

ตอนที่เรารันเราสามารกใช้คำสั่ง npm test ได้เลย แล้วเจ้าตัว vitest ก็จะแสดงข้อความตามนี้มา

  • DEV v1.4.0 C:/Users/User/Content/Vitest_Example
    • DEV: หมายถึงโปรเจกต์นี้กำลังอยู่ในโหมด development (การพัฒนา)
    • v.1.4.0: เวอร์ชั่นของ Vitest ที่ใช้
    • C:/Users/User/Content/Vitest_Example: ตำแหน่งของโปรเจกต์
  • ✓ sum.test.js (1)
    • : สัญลักษณ์บอกว่า test case ในไฟล์ sum.test.js ผ่าน
    • (1): ระบุว่ามี test case จำนวน 1 ในไฟล์นี้
  • ✓ adds 1 + 2 to equal 3
    • ข้อความอธิบาย test case ที่ผ่าน
  • Test Files 1 passed (1): มี 1 test file ผ่าน
  • Tests 1 passed (1): มี 1 test case ผ่าน
  • Start at 10:28:05: เวลาเริ่มต้นรัน test
  • Duration 270ms …: ระยะเวลาในการรัน test ทั้งหมด กับเวลาย่อยของแต่ละขั้นตอน
  • PASS Waiting for file changes…: การทดสอบเสร็จสมบูรณ์ Vitest กำลังรอตรวจจับการเปลี่ยนแปลงไฟล์อยู่เพื่อทดสอบใหม่อีกครั้ง
    • press h to show help: กด ‘h’ เพื่อดูเมนูช่วยเหลือ
    • press q to quit: กด ‘q’ เพื่อออกจาก Vitest

4. การเปิดใช้งาน Test Coverage

เราสามารถดูว่าการเขียน Unit Test ของเรามันคลุมทุกฟังก์ชันเลยหรือป่าว ขาดตกส่วนไหนไปบ้างสามารถใช้ coverage ดูตรงนี้ได้

อย่างเช่นไฟล์ math.js

function add(x, y) {
  return x + y;
}

function subtract(x, y) {
  return x - y;
}

function multiply(x, y) {
  return x * y;
}

function divide(x, y) {
  if (y === 0) {
    throw new Error("Cannot divide by zero!");
  }
  return x / y;
}

module.exports = { add, subtract, multiply, divide };

แล้วทำการเขียน Unit Test โดยขาดการเทสฟังก์ชัน divide ไป

import { describe, it, expect } from "vitest";
import { add, subtract, multiply, divide } from "./math"; // Adjust the path if necessary

describe("math functions", () => {
  it("add", () => {
    expect(add(2, 3)).toBe(5);
    expect(add(0, 5)).toBe(5);
    expect(add(-3, 5)).toBe(2);
  });

  it("subtract", () => {
    expect(subtract(5, 3)).toBe(2);
    expect(subtract(0, 5)).toBe(-5);
    expect(subtract(-3, 5)).toBe(-8);
  });

  it("multiply", () => {
    expect(multiply(2, 3)).toBe(6);
    expect(multiply(0, 5)).toBe(0);
    expect(multiply(-3, 5)).toBe(-15);
  });
});

หากใช้ npm test เราจะเห็นแต่เทสผ่านกี่ไฟล์ กี่ฟังก์ชัน แต่ไม่เห็นว่าเทสครบมั้ย

หากเราจะเปิดใช้งาน coverage ให้ไปที่ไฟล์ package.json แล้วเพิ่ม “coverage”: “vitest run –coverage” ขึ้นมา

  "scripts": {
    "test": "vitest",
    "coverage": "vitest run --coverage"
  },

หลังจากนั้นลองรันโดยใช้คำสั่ง

npm run coverage

จะเห็นได้ว่ามี coverage report เพิ่มมาให้

  • ไฟล์ sum.js ถูกทดสอบครบถ้วน 100%
  • ไฟล์ math.js มีบางส่วนที่ยังไม่ได้ทดสอบ: บรรทัด 13-18
  • % Stmts: เปอร์เซ็นต์ของคำสั่งในไฟล์ที่ถูกทดสอบ
  • % Branch: เปอร์เซ็นต์ของเงื่อนไขในไฟล์ที่ถูกทดสอบ
  • % Funcs: เปอร์เซ็นต์ของฟังก์ชันในไฟล์ที่ถูกทดสอบ
  • % Lines: เปอร์เซ็นต์ของบรรทัดในไฟล์ที่ถูกทดสอบ
  • Uncovered Line #s: หมายเลขบรรทัดที่ไม่ได้ทดสอบ

Vitest UI

ซึ่งนอกจากนั้น Vitest ยังมี Report ที่เป็น UI สวย ๆ มาให้ใช้ได้ด้วย เพียงเราทำการติดตั้งโดยใช้คำสั่ง

npm i -D @vitest/ui

และทำการรันโดยการใช้คำสั่ง

npx vitest --ui

โดยเราสามารถดู Vitest UI ได้เลยที่ http://localhost:51204/__vitest__/

และนี่ก็จะวิธีการใช้งาน Vitest ในการทำ Unit Test สำหรับโค้ด JavaScript แบบง่าย ๆ ถ้าใครอยากไปลองเล่นต่อสามารถลองใช้งานตาม Document นี้ได้เลยยย https://vitest.dev/guide/why.html

Sirasit Boonklang

Author Sirasit Boonklang

More posts by Sirasit Boonklang

เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า

ตั้งค่าความเป็นส่วนตัว

คุณสามารถเลือกการตั้งค่าคุกกี้โดยเปิด/ปิด คุกกี้ในแต่ละประเภทได้ตามความต้องการ ยกเว้น คุกกี้ที่จำเป็น

ยอมรับทั้งหมด
จัดการความเป็นส่วนตัว
  • คุกกี้ที่จำเป็น
    เปิดใช้งานตลอด

    ประเภทของคุกกี้มีความจำเป็นสำหรับการทำงานของเว็บไซต์ เพื่อให้คุณสามารถใช้ได้อย่างเป็นปกติ และเข้าชมเว็บไซต์ คุณไม่สามารถปิดการทำงานของคุกกี้นี้ในระบบเว็บไซต์ของเราได้
    รายละเอียดคุกกี้

  • คุกกี้สำหรับการติดตามทางการตลาด

    ประเภทของคุกกี้ที่มีความจำเป็นในการใช้งานเพื่อการวิเคราะห์ และ นำเสนอโปรโมชัน สินค้า รวมถึงหลักสูตรฟรี และ สิทธิพิเศษต่าง ๆ คุณสามารถเลือกปิดคุกกี้ประเภทนี้ได้โดยไม่ส่งผลต่อการทำงานหลัก เว้นแต่การนำเสนอโปรโมชันที่อาจไม่ตรงกับความต้องการ
    รายละเอียดคุกกี้

บันทึกการตั้งค่า