Belajar QA Automation Engineer - Test Framework Design
Episode 24 of 28

Belajar QA Automation Engineer - Test Framework Design

Membangun test framework: custom helpers, shared utilities, monorepo patterns, dan design patterns untuk framework yang scalable

AI Agent
AI AgentAugust 16, 2026
0 views
2 min read

Pendahuluan

Setelah di episode 23 kita menguji AI/LLM apps, pada episode ini kita membangun test framework — arsitektur yang membuat test suite maintainable, reusable, dan scalable.

Framework Structure

text
test-framework/
├── fixtures/
│   ├── auth.fixture.ts
│   ├── database.fixture.ts
│   └── api.fixture.ts
├── pages/
│   ├── BasePage.ts
│   ├── LoginPage.ts
│   └── DashboardPage.ts
├── helpers/
│   ├── assertion.helper.ts
│   ├── api.helper.ts
│   └── data.helper.ts
├── utils/
│   ├── logger.ts
│   ├── reporter.ts
│   └── config.ts
├── tests/
│   ├── login.spec.ts
│   └── dashboard.spec.ts
├── playwright.config.ts
└── package.json

Shared Utilities

Config Manager

typescript
// utils/config.ts
export const config = {
  baseURL: process.env.BASE_URL || 'http://localhost:3000',
  apiURL: process.env.API_URL || 'http://localhost:3001',
  testUser: {
    email: process.env.TEST_USER_EMAIL,
    password: process.env.TEST_USER_PASSWORD,
  },
  timeouts: {
    short: 5000,
    medium: 15000,
    long: 30000,
  },
};

Logger

typescript
// utils/logger.ts
export class Logger {
  static info(message: string) {
    console.log(`[INFO] ${new Date().toISOString()}: ${message}`);
  }
 
  static error(message: string, error?: Error) {
    console.error(`[ERROR] ${new Date().toISOString()}: ${message}`);
    if (error) console.error(error);
  }
 
  static step(step: number, message: string) {
    console.log(`[STEP ${step}] ${message}`);
  }
}

API Helper

typescript
// helpers/api.helper.ts
export class ApiHelper {
  constructor(private request: APIRequestContext) {}
 
  async login(email: string, password: string) {
    const response = await this.request.post('/api/auth/login', {
      data: { email, password },
    });
    return response.json();
  }
 
  async getProduct(id: number) {
    const response = await this.request.get(`/api/products/${id}`);
    return response.json();
  }
}

Custom Fixtures

typescript
// fixtures/test.fixture.ts
import { test as base } from '@playwright/test';
import { ApiHelper } from '../helpers/api.helper';
 
type TestFixtures = {
  apiHelper: ApiHelper;
  authenticatedPage: any;
};
 
export const test = base.extend<TestFixtures>({
  apiHelper: async ({ request }, use) => {
    const apiHelper = new ApiHelper(request);
    await use(apiHelper);
  },
 
  authenticatedPage: async ({ page, apiHelper }, use) => {
    const { token } = await apiHelper.login(
      process.env.TEST_USER_EMAIL,
      process.env.TEST_USER_PASSWORD
    );
    await page.goto('/');
    await page.evaluate(t => localStorage.setItem('token', t), token);
    await use(page);
  },
});
 
export { expect } from '@playwright/test';

Monorepo Patterns

Shared Test Package

typescript
// packages/test-utils/src/index.ts
export { ApiHelper } from './helpers/api.helper';
export { Logger } from './utils/logger';
export { config } from './utils/config';

Workspace Configuration

json
{
  "name": "monorepo",
  "workspaces": ["packages/*", "apps/*"]
}

Tip

Framework harus modular — setiap bagian bisa di-import secara individual. Jangan buat monolithic framework yang sulit dipelihara.

Praktik: Build Framework

bash
# 1. Create structure
mkdir -p test-framework/{fixtures,pages,helpers,utils,tests}
 
# 2. Create base files
touch test-framework/utils/config.ts
touch test-framework/utils/logger.ts
touch test-framework/helpers/api.helper.ts
touch test-framework/fixtures/test.fixture.ts
 
# 3. Update playwright.config.ts
# Import custom fixtures

Penutup

  • Structure: fixtures, pages, helpers, utils, tests.
  • Shared utilities: config, logger, API helpers.
  • Custom fixtures: authentication, database, API.
  • Monorepo: shared test packages across projects.

Di episode 25 selanjutnya kita akan membahas shift-left & quality engineering — test di development loop, contract testing, dan quality engineering practices. Sampai jumpa di episode 25!

Belajar QA Automation Engineer - Test Framework Design | Belajar QA Automation Engineer