CYBERSOFT
Đăng nhập

AI Visual Regression: diff AI vs pixel, baseline và ổn định dữ liệu (2026)

Chuyên công nghệBán lẻAI AgentVisualThực tếTip
🗓 1 tháng trước21 phút đọc·👁 945 lượt xem👤 237 người đọc

Kiểm thử hồi quy hình ảnh bằng AI (Applitools/Percy + Playwright snapshot): diff AI bỏ nhiễu anti-alias và vùng động thay vì pixel-to-pixel; baseline là oracle hình ảnh và quy trình phê duyệt; ổn định dữ liệu động trước khi chụp; phủ responsive/cross-browser; bắt lỗi layout/màu/text; AI tóm tắt vùng thay đổi; CI; chống flaky; và góc phỏng vấn.

1. Bối cảnh: vì sao pixel diff thuần khiến visual test chết yểu

Kiểm thử hồi quy hình ảnh (visual regression) ra đời để bắt những lỗi mà test chức năng bỏ sót: nút bị lệch, chữ tràn khung, màu sắc sai thương hiệu, layout vỡ trên màn hình nhỏ. Vấn đề là thế hệ công cụ đầu tiên so ảnh theo kiểu pixel-to-pixel, tức là chỉ cần một điểm ảnh khác nhau là báo đỏ. Trong thực tế, chống răng cưa (anti-alias), cách render font khác nhau giữa hệ điều hành, con trỏ nhấp nháy hay một mốc thời gian động cũng đủ làm hàng loạt ảnh khác nhau ở mức pixel dù mắt người chẳng thấy khác biệt nào đáng kể.

Hệ quả là một vòng xoáy tiêu cực quen thuộc: quá nhiều báo động giả (false positive) khiến người kiểm thử mất niềm tin vào bộ ảnh chuẩn (baseline). Họ bắt đầu bấm 'chấp nhận tất cả' cho nhanh, và đúng lúc đó một lỗi giao diện thật lọt qua vì bị vùi trong đống khác biệt vô nghĩa. Đây chính là phiên bản trực quan của bài toán test giòn (フレーキー / flaky) mà ai làm tự động hóa cũng từng gặp: khi tín hiệu quá nhiễu, con người ngừng đọc tín hiệu.

Pixel diff vs AI visual diff Pixel-to-pixel ✗ đỏ vì anti-alias 1px ✗ đỏ vì font render khác OS ✗ đỏ vì avatar/thời gian động ✗ đỏ vì cursor nhấp nháy → nhiều false positive → đội ngũ mất niềm tin baseline → approve mù → bỏ sót lỗi thật AI / perceptual diff ✓ bỏ qua nhiễu anti-alias ✓ bỏ qua khác biệt sub-pixel font ✓ ignore region cho vùng động ✓ nhóm thay đổi theo vùng UI ✓ bắt lệch layout / màu / text thật ✓ ít false positive → baseline tin được ✓ tóm tắt vùng thay đổi cho reviewer
Pixel diff sinh nhiều false positive; AI/perceptual diff bỏ nhiễu và bắt lỗi thật.
Visual test không thay thế test chức năng — nó bổ sung. Test chức năng hỏi 'nút có hoạt động không?', visual test hỏi 'nút có trông ĐÚNG không?'. Cả hai đều cần oracle rõ ràng, chỉ khác dạng bằng chứng.

2. Pixel diff so với AI diff: cơ chế và sự khác biệt

Pixel diff hoạt động đơn giản: đặt ảnh mới chồng lên ảnh chuẩn, đếm số điểm ảnh khác nhau, nếu vượt ngưỡng thì báo lỗi. Cách này nhanh, dễ hiểu, nhưng không biết đâu là khác biệt 'quan trọng với con người'. Ngược lại, AI diff (hay perceptual diff) mô phỏng cách mắt người cảm nhận: nó bỏ qua sai khác sub-pixel do răng cưa, chịu được khác biệt nhỏ về màu do nén ảnh, và tập trung vào những thay đổi có ý nghĩa như phần tử bị dịch chuyển, đổi kích thước, đổi màu rõ rệt hay chữ bị đổi.

Điều then chốt để hiểu là AI diff không phải phép màu 'luôn đúng'. Nó là một mô hình có ngưỡng nhạy cảm và các quy tắc bỏ qua vùng động mà bạn phải cấu hình đúng. Cấu hình quá lỏng thì bỏ sót lỗi thật; quá chặt thì quay lại cảnh nhiễu như pixel diff. Vì thế người kiểm thử vẫn là người điều chỉnh độ nhạy, khai báo vùng cần bỏ qua, và quyết định thay đổi nào là hồi quy (回帰) ngoài ý muốn, thay đổi nào là cập nhật thiết kế chủ ý.

ts
// Playwright snapshot: toHaveScreenshot có ngưỡng + mask vùng động
import { test, expect } from '@playwright/test';

test('trang giỏ hàng khớp baseline (bỏ nhiễu động)', async ({ page }) => {
  await page.goto('/cart');
  await page.waitForLoadState('networkidle');

  await expect(page).toHaveScreenshot('cart.png', {
    maxDiffPixelRatio: 0.01,        // cho phép ~1% nhiễu anti-alias
    threshold: 0.2,                 // ngưỡng khác biệt màu mỗi pixel (0..1)
    mask: [page.getByTestId('promo-countdown'),   // vùng thời gian động
           page.getByTestId('user-avatar')],      // avatar random
    animations: 'disabled',         // tắt animation trước khi chụp
  });
});
💡 Bắt đầu với ngưỡng vừa phải rồi siết dần dựa trên dữ liệu thật. Ghi lại mỗi lần bạn nới ngưỡng và lý do — ngưỡng là một quyết định oracle, không phải con số ngẫu nhiên.

3. Baseline và phê duyệt: hợp đồng hình ảnh của sản phẩm

Baseline là tập ảnh chuẩn mà mọi lần chạy sau đều đem so. Về bản chất, baseline chính là oracle của visual test: nó nói 'giao diện đúng phải trông như thế này'. Do đó, việc quản lý baseline không phải chuyện kỹ thuật vặt mà là quản lý một hợp đồng. Mỗi lần bạn 'chấp nhận' một ảnh mới, bạn đang tuyên bố rằng trạng thái mới đó là đúng và trở thành chuẩn cho tương lai. Chấp nhận cẩu thả sẽ đóng băng một lỗi thành 'đúng', và từ đó về sau không test nào bắt được nó nữa.

Trong công cụ đám mây kiểu Applitools hay Percy, luồng phê duyệt được thiết kế như một bước review có người: khi có khác biệt, hệ thống hiển thị ảnh chuẩn, ảnh mới và vùng thay đổi được tô sáng, rồi người review bấm chấp nhận hoặc từ chối. Với Playwright snapshot, baseline là các file .png nằm trong repo, cập nhật bằng cờ --update-snapshots và được review qua diff của pull request. Dù công cụ nào, nguyên tắc bất di bất dịch là baseline chỉ đổi khi có người chủ ý duyệt, không bao giờ tự động cập nhật trong CI.

Vòng đời visual test: ổn định → chụp → diff → duyệt Ổn định freeze data/time Chụp snapshot đa breakpoint Diff AI so baseline, bỏ nhiễu Duyệt accept / reject reject → sửa UI hoặc sửa oracle → chụp lại Baseline = hợp đồng hình ảnh. Accept mới ⇒ cập nhật baseline có chủ đích, không auto. Người duyệt phân biệt: thay đổi CHỦ Ý (mới) vs hồi quy (回帰) ngoài ý muốn.
Vòng đời visual test: ổn định → chụp → diff AI → duyệt; baseline chỉ đổi khi có người chốt.
bash
# Playwright: baseline là file .png trong repo, review qua PR diff
# Lần đầu tạo baseline (chủ ý):
npx playwright test --update-snapshots

# CI: KHÔNG update, chỉ so — khác baseline ⇒ fail để người xem
npx playwright test   # không có --update-snapshots

# Khi thiết kế đổi CHỦ Ý: update rồi commit ảnh mới, review trong PR
npx playwright test cart.spec.ts --update-snapshots
git add tests/__screenshots__/cart.png
git commit -m "chore(visual): cập nhật baseline giỏ hàng sau redesign header"
⚠️ Không bao giờ chạy --update-snapshots tự động trong CI để 'làm xanh'. Điều đó biến mọi hồi quy hình ảnh thành baseline mới và vô hiệu hóa toàn bộ lớp bảo vệ. Update baseline phải là hành động có người chủ ý.
🔒

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!