Testing
test behavior ไม่ใช่ implementation
หัวข้อที่มีชื่อว่า “test behavior ไม่ใช่ implementation”แนวทางหลักในการ test React component คือ React Testing Library (RTL) ปกติรันบน Vitest (หรือ Jest) หลักการนำทางของตัวเองคือ:
ยิ่ง test ของคุณเหมือนวิธีที่ software ถูกใช้จริงมากเท่าไร ก็ยิ่งให้ความมั่นใจมากขึ้นเท่านั้น
หมายความว่าคุณไม่ test internal state, ชื่อ prop หรือว่า component เรียก hooks ตัวไหน คุณ render component, โต้ตอบกับ component แบบที่ user ทำ (click, type) แล้ว assert สิ่งที่ user เห็น เมื่อคุณ refactor internal — สลับ useState เป็น useReducer, แยก hook — test ที่อิง behavior ก็ยังผ่าน เพราะ behavior ไม่เปลี่ยน ส่วน test ที่อิง implementation จะพังโดยไม่มีเหตุผลจริง
test widget แบบ end to end
หัวข้อที่มีชื่อว่า “test widget แบบ end to end”import { render, screen } from '@testing-library/react';import userEvent from '@testing-library/user-event';import { expect, test } from 'vitest';import Counter from './Counter';
test('increments when the button is clicked', async () => { const user = userEvent.setup(); render(<Counter />);
// Query the way a user finds things: by role and accessible name. const button = screen.getByRole('button', { name: /count: 0/i });
await user.click(button);
// Assert on what the user sees, not on internal state. expect(screen.getByRole('button', { name: /count: 1/i })).toBeInTheDocument();});นิสัยสำคัญ:
- query ด้วย role/label/text ตามลำดับนี้ —
getByRoleดีที่สุดเพราะสะท้อนวิธีที่ assistive tech (และ user) หา element ซึ่งยัง nudge ให้คุณเขียน markup ที่ accessible - ใช้
userEventไม่ใช่fireEventดิบ ๆ สำหรับ interaction — simulate การกระทำของ user จริง (focus, key sequence) ได้แม่นกว่า - assert สิ่งที่ render ออกมา (
toBeInTheDocument, text ที่เห็น) ไม่ใช่component.state
testing pyramid ฉบับ React
หัวข้อที่มีชื่อว่า “testing pyramid ฉบับ React”| ระดับ | เครื่องมือ | ครอบคลุมอะไร |
|---|---|---|
| Unit | Vitest | pure function, custom hook (renderHook), reducer |
| Component | RTL + Vitest | behavior ของ component แบบ isolate (test ส่วนใหญ่ของคุณ) |
| End-to-end | Playwright / Cypress | browser จริง, user flow เต็มข้ามหลายหน้า |
flowchart TB e2e["End-to-end (few) Playwright — real browser, whole flows"] comp["Component (many) RTL + Vitest — behavior in isolation"] unit["Unit (some) Vitest — pure logic, hooks, reducers"] e2e --> comp --> unit
แรงส่วนใหญ่ของคุณอยู่ตรงกลาง — RTL component test — เพราะที่นั่นคือที่ที่ logic ของ React อยู่จริง test end-to-end ไม่กี่ตัวครอบ happy path สำคัญข้าม app จริง