Skip to main content
Last updated on
Version: 1.0.0

Quy định sử dụng Test ID trong Frontend element

Quy định chung về việc dùng thuộc tính test-id trong các element/phần tử chủ đạo trong trang và component.

Version

Phạm vi: Tất cả các product và project trong ePlatform

Mục tiêu:

  • Đảm bảo automated test (Playwright) chọn element/phần tử ổn định, không phụ thuộc vào vị trí control, CSS hoặc text, ngôn ngữ.
  • Tạo quy ước đặt tên nhất quán, dễ bảo trì và truy xuất các thành phần trên trang, component, control phục vụ cho quá trình automated testing và nhập liệu tự đồng (data entry).

1. Thuộc tính sử dụng

  • Mặc định: data-testid
  • Team automated test tránh dùng id hoặc class cho mục đích test.
  • Không dùng Test ID cho styling hoặc logic runtime.

2. Nguyên tắc

  • Dùng Test ID trước khi:
    • Text có thể thay đổi (i18n, A/B test).
    • Không có role/label rõ ràng.
    • UI động (list, table, modal).
  • Đặt Test ID ở element tương tác (button, input) hoặc container logic (card, row).
  • Tiếp theo là ARIA nếu không có hoặc không thể gắn test-id: Nếu có thể dùng getByRole, getByLabel → không cần Test ID.
  • Không encode dữ liệu động (ID, index).

3. Quy ước đặt test-id

  • Format: kebab-case - Xem thêm: Snake Case VS Camel Case VS Pascal Case VS Kebab Case - What's the difference?

  • Cấu trúc:

    • <component>-<element>-<action>
    • Ví dụ: user-form-submit, form-button-approve, table-row-edit, dialog-create-user-name
  • Từ vựng chuẩn:

    • Hành động: add, edit, delete, submit, cancel, open, close
    • Thành phần: button, input, select, row, dialog, toast
    • Ngữ cảnh: form, table, card, menu, modal

4. Ví dụ

<!-- Form -->
<form data-testid="form">
<input data-testid="form-textbox-title" [(ngModel)]="name" />
<input data-testid="form-textbox-description" [(ngModel)]="description" />
<button data-testid="form-button-submit" (click)="submit()">Submit</button>
<button data-testid="form-button-approve" (click)="approve()">Approve</button>
<button data-testid="form-button-reject" (click)="reject()">Reject</button>
</form>
<!-- Dialog -->
<div role="dialog" data-testid="dialog-create-user">
<input data-testid="dialog-create-user-name" [(ngModel)]="name" />
<button data-testid="dialog-create-user-submit" (click)="create()">Create</button>
</div>
<!-- Table -->
<table data-testid="table-users">
<tr data-testid="table-row">
<td data-testid="table-cell-name">{{ user.name }}</td>
<td><button data-testid="table-row-edit" (click)="edit(user)">Edit</button></td>
</tr>
</table>

5. Checklist Review

  • Đúng thuộc tính data-testid.
  • Tên theo kebab-case, mô tả chức năng.
  • Không chứa dữ liệu động.
  • Đặt ở element tương tác hoặc container logic.

6. Best Practices cho Angular

  • Với component tái sử dụng, expose @Input() testIdPrefix để truyền prefix cho Test ID:
@Component({
selector: 'app-user-form',
template: `
<form [attr.data-testid]="testIdPrefix + '-form'">
<input [attr.data-testid]="testIdPrefix + '-email'" />
<button [attr.data-testid]="testIdPrefix + '-submit'">Submit</button>
</form>
`
})
export class UserFormComponent {
@Input() testIdPrefix = 'user-form';
}
  • Khi dùng ngFor, không encode index vào Test ID. Thay vào đó, dùng .nth() hoặc filter({ hasText }) trong test.

7. Cấu hình Playwright dành cho team automated test

// playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
use: {
testIdAttribute: 'data-testid',
},
});