0Pricing
React Academy · บทเรียน

การทดสอบแบบผสานรวมด้วย React Testing Library

เรนเดอร์คอมโพเนนต์ในการทดสอบ จำลองอีเวนต์ และตรวจสอบผลลัพธ์ที่มองเห็นได้แทนรายละเอียดการทำงานภายใน

การทดสอบแบบผสานรวมด้วย React Testing Library เป็นบทเรียน React Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

React Testing Library คืออะไร

React Testing Library (RTL) สนับสนุนการทดสอบจากมุมมองของผู้ใช้ ได้แก่ แสดงผลคอมโพเนนต์ โต้ตอบกับคอมโพเนนต์เหมือนที่ผู้ใช้ทำ และตรวจสอบผลลัพธ์ที่มองเห็นได้แทนรายละเอียดการทำงานภายใน

การตั้งค่า

RTL รวมอยู่ใน Create React App และเทมเพลต React ของ Vite หากตั้งค่าด้วยตนเอง ให้ติดตั้ง @testing-library/react และ @testing-library/jest-dom

// package.json
// "@testing-library/react": "^14.0.0",
// "@testing-library/jest-dom": "^6.0.0"

// setupTests.ts
import '@testing-library/jest-dom';

การแสดงผลคอมโพเนนต์

render() เมานต์คอมโพเนนต์ใน DOM เสมือน และส่งคืนฟังก์ชันคิวรีที่จำกัดขอบเขตอยู่ภายในผลลัพธ์ที่แสดงผล

import { render, screen } from '@testing-library/react';
import { Button } from './Button';

test('renders button label', () => {
  render(<Button label="Submit" onClick={() => {}} />);
  expect(screen.getByText('Submit')).toBeInTheDocument();
});

การค้นหาองค์ประกอบ

แนะนำให้ใช้คิวรีตามลำดับนี้: getByRole > getByLabelText > getByPlaceholderText > getByText คิวรีตามบทบาทจะสอดคล้องกับความหมายด้านการเข้าถึง

// Best: query by role
const button = screen.getByRole('button', { name: /submit/i });

// Good: query by label (for form inputs)
const input = screen.getByLabelText('Email address');

// Acceptable: query by text
const heading = screen.getByText('Welcome');

การส่งเหตุการณ์

ใช้ userEvent จาก @testing-library/user-event ซึ่งเป็นวิธีที่แนะนำ หรือใช้ fireEvent สำหรับกรณีพื้นฐาน userEvent จำลองการโต้ตอบกับเบราว์เซอร์จริง รวมถึงการโฟกัสและการสูญเสียโฟกัส

import userEvent from '@testing-library/user-event';

test('types into input', async () => {
  const user = userEvent.setup();
  render(<SearchBar />);
  const input = screen.getByRole('textbox');
  await user.type(input, 'react');
  expect(input).toHaveValue('react');
});

การทดสอบการส่งแบบฟอร์ม

แสดงผลแบบฟอร์ม กรอกอินพุตด้วย userEvent.type คลิกปุ่มส่ง และตรวจสอบผลลัพธ์ เช่น ข้อความสำเร็จ การนำทาง หรือการเรียกฟังก์ชันเรียกกลับ

test('submits the login form', async () => {
  const onLogin = jest.fn();
  const user = userEvent.setup();
  render(<LoginForm onLogin={onLogin} />);

  await user.type(screen.getByLabelText('Email'), 'test@example.com');
  await user.type(screen.getByLabelText('Password'), 'password123');
  await user.click(screen.getByRole('button', { name: /log in/i }));

  expect(onLogin).toHaveBeenCalledWith({ email: 'test@example.com', password: 'password123' });
});

การตรวจสอบการมองเห็น

ตัวจับคู่ของ jest-dom เช่น toBeInTheDocument(), toBeVisible() และ toHaveValue() ช่วยให้การตรวจสอบอ่านเข้าใจได้ง่าย

expect(screen.getByText('Error: required')).toBeInTheDocument();
expect(screen.getByRole('dialog')).toBeVisible();
expect(screen.getByRole('textbox')).toHaveValue('hello');
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();

การทดสอบการแสดงผลแบบมีเงื่อนไข

ใช้ queryBy ซึ่งส่งคืน null เมื่อไม่พบ เพื่อตรวจสอบว่าองค์ประกอบไม่ได้ถูกแสดงผล และใช้ getBy เมื่อคาดว่าองค์ประกอบจะปรากฏอยู่

test('shows error message when validation fails', async () => {
  const user = userEvent.setup();
  render(<SignUpForm />);
  await user.click(screen.getByRole('button', { name: /submit/i }));
  expect(screen.getByText('Email is required')).toBeInTheDocument();
});

การห่อด้วยผู้ให้บริการ

คอมโพเนนต์ส่วนใหญ่ต้องใช้บริบทหรือตัวจัดการเส้นทาง ให้ห่อคอมโพเนนต์ด้วยผู้ให้บริการภายในการเรียก render หรือสร้างตัวช่วย renderWithProviders แบบกำหนดเอง

function renderWithProviders(ui: React.ReactElement) {
  return render(
    <QueryClientProvider client={new QueryClient()}>
      <MemoryRouter>
        {ui}
      </MemoryRouter>
    </QueryClientProvider>
  );
}

test('shows user data', () => {
  renderWithProviders(<UserProfile />);
});

การทดสอบการเปลี่ยนแปลงสถานะ

ดำเนินการกับคอมโพเนนต์ แล้วตรวจสอบว่าสถานะใหม่สะท้อนอยู่ใน UI หรือไม่ RTL จะห่อการโต้ตอบส่วนใหญ่ไว้ใน act โดยอัตโนมัติเมื่อใช้ userEvent

test('counter increments', async () => {
  const user = userEvent.setup();
  render(<Counter />);
  expect(screen.getByText('Count: 0')).toBeInTheDocument();
  await user.click(screen.getByRole('button', { name: /increment/i }));
  expect(screen.getByText('Count: 1')).toBeInTheDocument();
});

ตัวช่วยดีบักหน้าจอ

เรียก screen.debug() เพื่อพิมพ์ HTML ที่แสดงผลอยู่ในปัจจุบันไปยังคอนโซล ซึ่งมีประโยชน์เมื่อคิวรีล้มเหลวและต้องการดูว่าสิ่งใดถูกแสดงผลจริง

test('debugging a failing query', () => {
  render(<MyComponent />);
  screen.debug(); // prints rendered HTML
  screen.getByRole('button', { name: /save/i }); // then inspect output
});

ตรวจสอบอย่างรวดเร็ว

ควรเลือกใช้คิวรีใดเมื่อต้องการทดสอบปุ่มใน React Testing Library

สรุปทบทวน

RTL ทดสอบโดยแสดงผลคอมโพเนนต์และโต้ตอบกับคอมโพเนนต์ผ่านคิวรีตามบทบาทและ userEvent ห่อคอมโพเนนต์ด้วยผู้ให้บริการที่จำเป็น ใช้ตัวจับคู่ของ jest-dom เพื่อให้การตรวจสอบอ่านเข้าใจได้ง่าย และเลือกใช้ queryBy เมื่อตรวจสอบการไม่มีอยู่

คำถามที่พบบ่อย

บทเรียน “การทดสอบแบบผสานรวมด้วย React Testing Library” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การทดสอบแบบผสานรวมด้วย React Testing Library” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การทดสอบแบบผสานรวมด้วย React Testing Library”

เรนเดอร์คอมโพเนนต์ในการทดสอบ จำลองอีเวนต์ และตรวจสอบผลลัพธ์ที่มองเห็นได้แทนรายละเอียดการทำงานภายใน คุณปฏิบัติ React Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “การทดสอบแบบผสานรวมด้วย React Testing Library” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน React Academy นี้ได้ไหม

ได้ บทเรียน React Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การทดสอบแบบผสานรวมด้วย React Testing Library
  2. การทดสอบ UI แบบอะซิงก์และการเรียก API ด้วย MSW
  3. เริ่มต้นใช้งาน Playwright สำหรับ React
  4. การทดสอบฟอร์มและขั้นตอนการใช้งานตั้งแต่ต้นจนจบ
← กลับไปที่ React Academy