Wiki

← Tất cả bài wiki

Annotations — skip, fixme, fail, slow (đánh dấu trạng thái test)

automationplaywright

Annotations là các cờ đánh dấu trạng thái của test: test.skip bỏ qua, test.fixme đánh dấu 'biết hỏng chưa fix', test.fail kỳ vọng fail (known bug), test.slow nới timeout gấp 3 — tất cả đều hỗ trợ điều kiện runtime. Chúng giải quyết việc quản lý test flaky, test chờ bug fix, và test browser-specific mà không phải comment code hay xoá test.

Khái niệm & Bản chất

  • test.skip — không chạy test, report hiển thị skipped. Dùng cho test chưa sẵn sàng, hoặc không áp dụng cho env hiện tại.
  • test.fixme — về mặt chạy giống skip, nhưng ngữ nghĩa là 'biết là hỏng, chưa fix'; report tách riêng nhóm fixme để nhìn nợ kỹ thuật.
  • test.fail — test được kỳ vọng fail: chạy bình thường, fail thật → báo 'expected to fail' (đếm pass), pass thật → báo 'unexpectedly passed' (coi như cần gỡ cờ).
  • test.slow — đánh dấu test chạy chậm hợp lệ, timeout tự nhân 3 so với timeout mặc định.
  • Tất cả đều có dạng conditional: test.skip(condition, 'lý do') — chỉ áp dụng khi condition true; lý do hiển thị trên report.

Cách hoạt động & API chính

  • Gọi trong body test → annotation áp dụng tại thời điểm runtime gọi (có thể đặt sau vài dòng logic check).
  • Gọi trong describe (ngoài test) → áp dụng cho toàn bộ test trong nhóm: test.describe('x', () => { test.fixme(); ... }).
  • Gọi trong beforeEach → skip có điều kiện theo env/browser/feature flag trước khi test chạy.
  • Dạng khai báo tĩnh qua details object: test('name', { annotation: { type: 'issue', description: 'JIRA-123' } }, fn) — metadata custom, render trên HTML report.
  • Kết hợp được: test.describe.skip, test.describe.fixme, hoặc tag kèm annotation cùng lúc.

Ví dụ & Cú pháp thực tế

  • Các annotation cơ bản trong body test: ``ts import { test, expect } from '@playwright/test'; test('upload file lớn', async ({ page }) => { test.slow(); // upload chậm hợp lệ — timeout x3 // ... }); test('tính năng export PDF', async ({ page }) => { test.fixme(); // TODO: chờ BE release API v2 // ... }); test('chỉ chạy trên Chromium', async ({ page, browserName }) => { test.skip(browserName !== 'chromium', 'Chỉ hỗ trợ Chromium'); // ... }); ``
  • test.fail cho known-bug — tự 'bật đèn' khi dev fix xong: ``ts test('hiển thị đúng ngày 29/02', async ({ page }) => { test.fail(true, 'BUG-88: lỗi timezone năm nhuận'); await page.goto('/calendar/2024-02'); // khi BUG-88 được fix, test này pass → report báo // 'unexpectedly passed' → nhắc mình gỡ test.fail }); ``
  • Skip cả nhóm trong describe + skip có điều kiện theo env: ``ts test.describe('Payment - thẻ quốc tế', () => { test.fixme(); // toàn nhóm đang chờ fix PAY-102 test('thanh toán Visa', async ({ page }) => { /* ... */ }); }); test.describe('Mobile-only', () => { test.skip(({ isMobile }) => !isMobile, 'Chỉ chạy trên project mobile'); // ... }); ``
  • Annotation tĩnh kèm link ticket trên report: ``ts test( 'đồng bộ giỏ hàng sau khi login', { annotation: { type: 'issue', description: 'https://jira.local/BUG-88' } }, async ({ page }) => { /* ... */ } ); ``

Best practices & Khi nào dùng

  • Luôn kèm lý do/ticket: test.fixme('PAY-102: chờ API v2') hoặc annotation description — ai đọc report cũng biết test này liên quan bug nào, khi nào gỡ.
  • Ưu tiên test.fail cho known-bug thay vì skip: test vẫn chạy mỗi build, bug fix xong nó 'unexpectedly passed' → nhắc gỡ cờ. Skip thì im lặng mãi mãi.
  • Conditional skip cho test browser/env-specific thay vì comment out — nhưng nếu cả nhóm chỉ chạy 1 browser, cân nhắc dùng grep trong project cho gọn.
  • test.slow cho test chậm hợp lý (upload, report nặng, ví điện tử) — nhưng nó chỉ né timeout, không phải phép màu; test chậm vô lý vẫn phải tối ưu.
  • Review định kỳ danh sách fixme trên report — nhiều fixme dồn = nợ test suite, không phải 'coverage'.

Gotchas, So sánh & Lưu ý

  • Skip trong beforeEach vẫn tốn thời gian chạy hook trước đó (và mọi test vẫn được 'khởi động') — với điều kiện tĩnh (browser, OS), lọc bằng --grep/project grepInvert hiệu quả hơn.
  • test.fail đảo ngữ nghĩa pass/fail — dễ confuse khi debug: test 'xanh' nhưng thực chất nó đang fail đúng như kỳ vọng. Đọc kỹ cột annotation trên report.
  • test.slow() nhân 3 test timeout — nếu test timeout đã 60s thì slow = 180s; không tính vào expect timeout riêng.
  • Annotation gọi sau action vẫn hợp lệ (runtime), nhưng code sau test.skip() trong cùng test không chạy — nó throw ngầm để abort test.
  • So sánh Jest: tương đương xit/test.todo, nhưng Playwright thêm fail (expected-fail) và slow — hai thứ Jest không có sẵn.
  • Đừng lạm dụng fixme để 'giữ chỗ' test chưa viết — dùng test.fixme('tên', async () => {}) body rỗng hoặc chỉ khai báo test.fixme('tên', ...) cũng hiển thị fixme trên report.