CYBERSOFT
Đăng nhập

Component Testing với Playwright (React · Vue · Svelte · Solid)

Chuyên công nghệDịch vụ SaaSPlaywrightVisualNền tảngThực tế
🗓 1 tháng trước21 phút đọc·👁 1,713 lượt xem👤 158 người đọc

Mount component vào trình duyệt thật, mock network qua router fixture, cô lập và kiểm thử biến thể UI nhanh — khi nào dùng CT thay E2E, cách chạy CI và né cạm bẫy.

1. Component Testing là gì và vì sao 2026 nên dùng

Component Testing (CT) của Playwright cho phép bạn gắn (mount) một component React, Vue, Svelte hoặc Solid trực tiếp vào một trình duyệt thật rồi kiểm thử nó như thể đó là một trang web thu nhỏ. Khác với unit test chạy trên jsdom giả lập, CT dựng component trong Chromium thực, nên layout, CSS, animation, focus và sự kiện chuột đều đúng như production. Đây là điểm giao thoa quý giá giữa tốc độ của unit test và độ trung thực của E2E.

Trong hệ thống SaaS thực tế, một component như bảng giá, giỏ hàng hay biểu đồ dashboard chứa rất nhiều nhánh logic: trạng thái loading, empty, error, quyền theo gói dịch vụ. Viết E2E cho mọi tổ hợp đó vừa chậm vừa giòn, còn unit test lại không bắt được lỗi CSS đè lên nút bấm. CT lấp đúng khoảng trống ấy: bạn kiểm được hành vi tương tác thật trên một đơn vị nhỏ, chạy nhanh trong mili-giây và cô lập khỏi backend.

Component Testing vs E2E — cùng trình duyệt thật COMPONENT TEST mount(<Cart items={fx}/>) network mock qua router fixture 1 component · ms · cô lập E2E TEST page.goto('/checkout') DB + API + routing + auth thật cả hệ thống · giây · toàn cục
CT cô lập một component với network mock; E2E chạy cả hệ thống.

Một lý do khiến CT trở nên thiết yếu năm 2026 là các đội front-end ngày càng chia nhỏ giao diện thành hàng trăm component tái sử dụng, và mỗi component lại là điểm hồi quy tiềm tàng. Khi một thư viện thiết kế dùng chung được nâng cấp, chỉ CT mới cho bạn kiểm nhanh từng component trong trình duyệt thật để phát hiện thay đổi vô tình về khoảng cách, màu sắc hay hành vi focus. Nếu không có lớp này, đội thường phát hiện lỗi quá muộn ở E2E, nơi việc truy nguyên component nào gây ra khác biệt tốn rất nhiều công. CT đưa phản hồi về đúng đơn vị nhỏ nhất, nơi chi phí sửa thấp nhất.

Gói CT vẫn mang tiền tố experimental (@playwright/experimental-ct-*) nhưng đã ổn định để dùng thật; API mount() gần như không đổi qua nhiều bản.

2. Cài đặt và khởi tạo CT cho từng framework

Playwright cung cấp một trình khởi tạo riêng cho CT. Lệnh init sẽ tạo playwright-ct.config.ts, thư mục playwright/ chứa index.html và index.ts (nơi bạn nạp CSS toàn cục, provider, theme), rồi cài đúng gói experimental theo framework bạn chọn. Với React bạn dùng ct-react, Vue dùng ct-vue, Svelte dùng ct-svelte, Solid dùng ct-solid — mỗi gói bọc một adapter mount riêng nhưng chia sẻ chung runner Playwright.

bash
# Khởi tạo Component Testing (chọn framework khi được hỏi)
npm init playwright@latest -- --ct

# hoặc cài trực tiếp gói theo framework
npm i -D @playwright/experimental-ct-react   # React
npm i -D @playwright/experimental-ct-vue     # Vue
npm i -D @playwright/experimental-ct-svelte  # Svelte
npm i -D @playwright/experimental-ct-solid   # Solid

# chạy CT (khác lệnh 'test' của E2E)
npx playwright test -c playwright-ct.config.ts
ts
// playwright-ct.config.ts
import { defineConfig, devices } from '@playwright/experimental-ct-react';

export default defineConfig({
  testDir: './src',
  testMatch: /.*\.ct\.(ts|tsx)$/,   // tách file CT khỏi file E2E
  snapshotDir: './__snapshots__',
  use: {
    trace: 'on-first-retry',
    ctPort: 3100,                     // cổng Vite của CT
    ctViteConfig: { resolve: { alias: { '@': '/src' } } },
  },
  projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
});
ts
// playwright/index.ts — chạy MỘT LẦN trước mọi mount
import '../src/styles/global.css';
import { beforeMount } from '@playwright/experimental-ct-react/hooks';
import { ThemeProvider } from '../src/theme';

// bọc mọi component bằng provider chung (theme, i18n, query client...)
beforeMount(async ({ App }) => {
  return (
    <ThemeProvider theme="light">
      <App />
    </ThemeProvider>
  );
});
💡 Đặt tên file CT theo mẫu *.ct.tsx và E2E theo *.spec.ts để hai bộ dùng hai config khác nhau mà không giẫm chân nhau trong CI.

3. mount(): trái tim của Component Testing

Hàm mount() nhận vào một component cùng props, sự kiện và children, đóng gói chúng bằng Vite, rồi render trong trình duyệt thật và trả về một locator gốc để bạn thao tác. Điều tinh tế cần nhớ: mọi giá trị bạn truyền vào props phải serialize được qua ranh giới Node ↔ browser, còn callback thì được Playwright bọc lại để bạn spy trong tiến trình test. Sau mount, bạn dùng đúng bộ locator getByRole, getByText và assertion expect quen thuộc.

Vòng đời mount() — component chạy trong browser thật Test processNode Vite dev bundlecomponent + fixtures ChromiumDOM · CSS · event assert 1) mount() bundle component + props/fixtures → 2) Vite build ⚡ → 3) render trong Chromium thật (layout, CSS, animation, focus) → 4) locator + expect chạy y như E2E, nhưng phạm vi 1 component.
mount() bundle component qua Vite rồi render trong Chromium thật.
tsx
// PriceTag.ct.tsx — React
import { test, expect } from '@playwright/experimental-ct-react';
import { PriceTag } from './PriceTag';

test('hiển thị giá đã định dạng theo locale', async ({ mount }) => {
  const cmp = await mount(<PriceTag amount={1990000} currency="VND" locale="vi-VN" />);
  await expect(cmp).toContainText('1.990.000');
  await expect(cmp.getByRole('note')).toHaveText('₫');
});

test('bắn event khi bấm "Chọn gói"', async ({ mount }) => {
  let picked = null;
  const cmp = await mount(<PriceTag amount={99} onSelect={(id) => (picked = id)} planId="pro" />);
  await cmp.getByRole('button', { name: 'Chọn gói' }).click();
  expect(picked).toBe('pro');   // callback được bắc cầu về test process
});
🔒

Nội dung bị khoá

Bạn đang xem bản xem trước. Đăng nhập để mở khoá toàn bộ bài viết và tất cả tài liệu Tester/QA.

Đã xem 25% nội dung
  • Đọc trọn vẹn mọi bài viết
  • Lưu bài & ghi chú cá nhân
  • Theo dõi tiến độ đã đọc
  • Luyện phỏng vấn, ISTQB, Mock
Đăng nhập để đọc tiếp

Chưa có mã? Lấy mã qua Fanpage / Zalo CyberSoft.

0

💬 Bình luận (0)

Bạn có thể đọc mọi bình luận. Đăng nhập để bình luận

Chưa có bình luận nào. Hãy là người đầu tiên!