Framework Architecture
Layers
1. Test cases (Gherkin / spec files)
- Step definitions / page objects
- Action helpers
- Driver / WebDriver / Appium client
- Test data / fixtures
- Config / environment
- Reporting / logging
Design principles
- DRY — Don't Repeat Yourself.
- POM — Page Object Model.
- Single Responsibility — each class one job.
- Open/Closed — extend, don't modify.
Test code structure example
project/
├── tests/
│ ├── login.spec.ts
│ ├── checkout.spec.ts
├── pages/
│ ├── LoginPage.ts
│ ├── CheckoutPage.ts
├── helpers/
│ ├── auth.ts
│ ├── apiClient.ts
├── fixtures/
│ ├── users.ts
│ ├── products.ts
├── config/
│ ├── env.dev.json
│ ├── env.staging.json
└── playwright.config.ts
Anti-pattern code
// XẤU: locator scattered
test('login', async ({ page }) => {
await page.fill('#email', 'test@test.vn');
await page.fill('#password', 'pass');
await page.click('button[data-test="login"]');
});
Refactored với POM
class LoginPage {
constructor(public page) {}
async login(email, pwd) {
await this.page.fill('#email', email);
await this.page.fill('#password', pwd);
await this.page.click('button[data-test="login"]');
}
}test('login', async ({ page }) => {
const login = new LoginPage(page);
await login.login('test@test.vn', 'pass');
});
Reporting + retry
- Built-in retry: 1-2 lần for transient.
- Screenshot/video on fail.
- HTML report archive.
CI integration
- Run on PR (smoke).
- Run nightly (full).
- Slack notify on fail.
- Tag flaky tests, quarantine.