Visual Regression Testing với Playwright & Percy: Chấm dứt nỗi lo “vỡ layout” mỗi khi deploy

Development tutorial - IT technology blog
Development tutorial - IT technology blog

Ám ảnh mang tên “vỡ giao diện” sau mỗi lần cập nhật CSS

Tôi từng tham gia một dự án refactor hệ thống có quy mô hơn 50.000 dòng code. Bài học xương máu nhất mà tôi rút ra là: Dù Unit Test hay Integration Test có phủ kín 90% logic, giao diện vẫn có thể “nát” như thường. Chỉ cần một thay đổi nhỏ ở file variables.scss hoặc chỉnh lại padding của một component dùng chung, hàng loạt trang khác sẽ bị lệch vài pixel. Những lỗi nhỏ này cực kỳ khó nhận ra bằng mắt thường khi chỉ kiểm tra nhanh trên trình duyệt.

Hệ quả thường thấy là bug chỉ bị phát hiện khi khách hàng dùng thử trên Safari hoặc một màn hình tablet lạ. Lúc này, việc tìm ra nguyên nhân và sửa lỗi không chỉ gây tốn thời gian mà còn làm giảm uy tín của team với đối tác.

Tại sao Unit Test và E2E Test thông thường là chưa đủ?

Các công cụ như Jest hay React Testing Library vốn chỉ tập trung kiểm tra logic. Chúng trả lời câu hỏi: “Nếu tôi nhấn nút này, modal có hiện ra không?”. Tuy nhiên, chúng hoàn toàn mù tịt trước việc modal đó có bị tràn viền, font chữ bị lỗi hay màu sắc có đúng branding hay không.

Ba nguyên nhân chính khiến lỗi UI trở thành bài toán hóc búa:

  • Hiệu ứng cánh bướm của CSS: CSS có tính kế thừa. Thay đổi một thuộc tính ở component cha có thể phá hỏng layout của hàng tá component con.
  • Sự khác biệt giữa các trình duyệt: Giao diện hiển thị hoàn hảo trên Chrome nhưng có thể bị vỡ khung hoàn toàn trên Safari hoặc Firefox.
  • Giới hạn của việc Review thủ công: Khi xem Pull Request, chúng ta thường chỉ tập trung vào logic code. Việc chạy thử giao diện ở mọi ngóc ngách dự án là điều gần như không thể.

Ba hướng tiếp cận kiểm thử giao diện phổ biến

Trong quá trình làm dự án, tôi đã thử nghiệm qua 3 cách sau:

  1. Manual QA: Thuê tester ngồi check tay từng trang. Cách này quá chậm, tốn kém và không thể mở rộng khi dự án lớn dần.
  2. Snapshot Testing (với Jest): Lưu cấu trúc HTML của component. Tuy nhiên, HTML giống nhau không đồng nghĩa với hiển thị giống nhau. Chỉ cần đổi mã màu trong CSS là UI đã khác, nhưng HTML vẫn giữ nguyên.
  3. Visual Regression Testing: Chụp ảnh màn hình giao diện làm chuẩn (baseline). Hệ thống sẽ so sánh ảnh này với phiên bản mới sau khi code. Chỉ cần sai lệch 0.1% pixel, bạn sẽ nhận được cảnh báo ngay lập tức.

Sau nhiều lần thử nghiệm, bộ đôi PlaywrightPercy chính là “chân ái” cho các ứng dụng React hiện đại.

Sức mạnh của bộ đôi Playwright + Percy

Playwright đóng vai trò như một “người lái xe” điều khiển trình duyệt tự động. Trong khi đó, Percy là một “nhiếp ảnh gia” chuyên nghiệp trên đám mây. Percy không chỉ chụp ảnh mà còn xử lý việc lưu trữ, so sánh và quản lý các bản snapshot giữa các lần build.

Bước 1: Cài đặt thư viện

Đầu tiên, hãy cài đặt các package cần thiết vào dự án React của bạn (Vite, Next.js hoặc CRA):

npm install --save-dev @playwright/test @percy/cli @percy/playwright

Sau đó, khởi tạo cấu hình Playwright nếu bạn chưa có:

npx playwright install

Bước 2: Viết kịch bản test

Thay vì viết code so sánh ảnh phức tạp, bạn chỉ cần gọi hàm percySnapshot. Hãy tạo file tests/visual.spec.ts với nội dung sau:

import { test } from '@playwright/test';
import percySnapshot from '@percy/playwright';

test.describe('Visual Regression Testing', () => {
  test('Trang chủ hiển thị đúng thiết kế', async ({ page }) => {
    await page.goto('http://localhost:3000');
    
    // Đợi dữ liệu hoặc animation hoàn tất
    await page.waitForLoadState('networkidle');

    // Chụp ảnh và gửi lên Percy cloud
    await percySnapshot(page, 'Trang chủ - Desktop');
  });

  test('Trang sản phẩm hiển thị đúng', async ({ page }) => {
    await page.goto('http://localhost:3000/products');
    await percySnapshot(page, 'Danh sách sản phẩm');
  });
});

Bước 3: Cấu hình Percy Token

Bạn cần tạo tài khoản miễn phí tại percy.io để lấy PERCY_TOKEN. Token này giúp định danh dự án của bạn trên server của Percy.

# Linux/macOS
export PERCY_TOKEN=your_token_here

# Windows (PowerShell)
$env:PERCY_TOKEN = "your_token_here"

Bước 4: Chạy kiểm thử và xem kết quả

Để chạy test, bạn bọc lệnh Playwright trong lệnh của Percy:

npx percy exec -- npx playwright test

Kết thúc quá trình, Percy sẽ gửi một đường link dashboard. Tại đây, những vùng bị thay đổi sẽ được highlight màu đỏ rực rỡ. Nếu đó là thay đổi chủ đích (ví dụ: đổi màu nút bấm theo thiết kế mới), bạn chỉ cần nhấn “Approve”. Nếu là lỗi ngoài ý muốn, bạn sẽ biết chính xác mình đã làm hỏng ở đâu trước khi khách hàng kịp thấy.

Kinh nghiệm thực chiến để tránh “báo động giả”

Khi áp dụng vào dự án thực tế, bạn sẽ gặp tình trạng test thất bại dù UI không lỗi (flaky tests). Dưới đây là cách xử lý:

1. Xử lý dữ liệu động

Nếu trang web hiển thị ngày giờ hiện tại, Percy sẽ báo lỗi liên tục vì thời gian luôn thay đổi. Hãy dùng percyCSS để ẩn các phần tử này khi chụp ảnh:

await percySnapshot(page, 'Dashboard', {
  percyCSS: '.current-date { visibility: hidden; }'
});

2. Vô hiệu hóa Animation

Các hiệu ứng chuyển động thường khiến ảnh chụp không ổn định. Bạn nên tắt sạch animation trong môi trường test để kết quả so sánh chính xác nhất.

3. Tận dụng CI/CD

Đừng chỉ chạy test ở máy cá nhân. Hãy tích hợp Percy vào GitHub Actions. Mỗi khi mở Pull Request, Percy sẽ tự động kiểm tra và comment kết quả vào PR. Cách làm này giúp team review code cực kỳ an tâm vì mọi sai lệch UI đều được phơi bày.

Kết luận

Đầu tư cho Visual Testing là cách tốt nhất để bảo vệ giấc ngủ của bạn trước mỗi đợt deploy lớn. Nó giúp rút ngắn thời gian review UI và loại bỏ hoàn toàn những lỗi vỡ layout ngớ ngẩn. Nếu bạn đang phát triển các ứng dụng yêu cầu độ chỉn chu cao về trải nghiệm người dùng, hãy thử áp dụng Playwright và Percy ngay hôm nay.

Share: