Playwright Academy
0 dari 17
Fase 3 · Dunia NyataModul 11 dari 17

Test Data

.env, data JSON, pengaturan retry/timeout/browser, dan menyimpan status login.

Modul ini memisahkan data dan rahasia dari kode test, lalu mengatur konfigurasi supaya test yang sama bisa jalan di laptop, CI, atau server staging.

Di dunia QA

Kamu tidak menulis password produksi di test case, dan satu test case bisa dijalankan dengan banyak set data. Modul ini membawa dua kebiasaan itu ke dalam kode: rahasia di .env, data di file JSON.

1. Rahasia di .env, bukan di kode

Password, token, dan URL server jangan ditulis di kode test, karena kode masuk ke Git dan bisa dibaca siapa pun yang punya akses. Simpan di file .env.

env
# .env di folder project   ← TIDAK di-commit (tambahkan ke .gitignore)
BASE_URL=https://playground.aminhamzah.com
TOKOQA_USERNAME=customer
TOKOQA_PASSWORD=rahasia123
env
# .env.example   ← DI-commit, berisi contoh nilai (bukan nilai asli) untuk anggota tim baru
BASE_URL=https://playground.aminhamzah.com
TOKOQA_USERNAME=isi-username
TOKOQA_PASSWORD=isi-password

Buat file .env di folder project, sejajar dengan pyproject.toml atau package.json. Lalu tambahkan satu baris .env di file .gitignore, supaya file ini tidak ikut ke Git. Di Windows Explorer, pastikan namanya persis .env, bukan .env.txt.

Cara membacanya dari kode:

# conftest.py: dimuat sekali sebelum test berjalan
from dotenv import load_dotenv
load_dotenv()                           # paket python-dotenv: mencari .env dari folder ini ke atas

# di test
import os
username = os.environ["TOKOQA_USERNAME"]   # error jelas kalau variabelnya lupa diisi
// playwright.config.ts: pola dari docs resmi (npm i -D dotenv)
import dotenv from 'dotenv';
import path from 'path'; // alat untuk menyusun path file

// Docs memakai __dirname (CommonJS). Di project ES module, padanannya import.meta.dirname.
dotenv.config({ path: path.resolve(import.meta.dirname, '.env'), quiet: true });

// di test
const username = process.env.TOKOQA_USERNAME!;

Di GitHub Actions, file .env tidak ada. Nilainya diambil dari Secrets repository sebagai environment variable, tanpa mengubah kode test (Modul 15).

2. Test data dari file JSON

Data yang banyak, misalnya isian checkout yang salah, simpan di file terpisah. Kasus baru bisa ditambah tanpa menyentuh kode.

data/checkout_cases.jsondata/checkout-cases.jsonLulus test
Memuat data/checkout_cases.json…
Memuat data/checkout-cases.json…

Lalu setiap baris data dijadikan satu test:

tests/academy/test_m11_data.pytests/academy/m11-data.spec.tsLulus test
Memuat tests/academy/test_m11_data.py…
uv run pytest tests/academy/test_m11_data.py -v
Memuat tests/academy/m11-data.spec.ts…
npx playwright test m11-data --project=chromium

CSV juga bisa dipakai (modul csv di Python, paket csv-parse di Node). Data yang harus unik setiap kali test jalan, misalnya email pendaftaran, buat saat test berjalan: f"user_{uuid4().hex[:8]}@contoh.com" (Python) / 'user_' + Date.now() + '@contoh.com' (TS).

3. Konfigurasi

Pengaturan pytest ada di pyproject.toml (bagian [tool.pytest.ini_options]), ditambah opsi yang bisa kamu ketik saat menjalankan test:

toml
[tool.pytest.ini_options]  # pengaturan pytest
testpaths = ["tests"]  # file test dicari di folder ini
pythonpath = ["."]  # supaya folder pages/ bisa di-import
base_url = "https://playground.aminhamzah.com"  # URL dasar untuk page.goto
addopts = "--tracing retain-on-failure --screenshot only-on-failure --video retain-on-failure --output test-results"  # simpan trace, screenshot, dan video hanya kalau gagal
markers = ["smoke: test penting", "regression: test lengkap"]  # tag yang boleh dipakai
Opsi CLI pytest-playwrightFungsi
--browser chromium/firefox/webkitPilih browser (boleh diulang untuk beberapa sekaligus)
--browser-channel chromePakai Google Chrome / Edge asli
--headed, --slowmo 500Tampilkan browser, perlambat setiap aksi
--device "iPhone 13"Pura-pura jadi perangkat tertentu
--base-url https://staging...Ganti server yang diuji
--tracing / --video / --screenshoton, off, retain-on-failure / only-on-failure

Mau mengubah pengaturan context, misalnya bahasa, zona waktu, atau ukuran layar? Timpa fixture browser_context_args di conftest.py:

Python
@pytest.fixture(scope="session")  # fixture bawaan pytest-playwright, ditimpa untuk semua test
def browser_context_args(browser_context_args):  # nilai bawaannya ikut diterima
    return {  # pengaturan context baru
        **browser_context_args,
        "viewport": {"width": 1366, "height": 768},
        "locale": "id-ID",
        "timezone_id": "Asia/Jakarta",
    }

Semua pengaturan ada di playwright.config.ts:

TypeScript
export default defineConfig({ // isi konfigurasi Playwright Test
  testDir: './tests',
  timeout: 30_000,                  // timeout per test
  expect: { timeout: 5_000 },       // timeout per assertion
  retries: process.env.CI ? 2 : 0,  // retry hanya di CI
  workers: process.env.CI ? 1 : undefined,
  reporter: [['list'], ['html', { open: 'never' }]],
  use: {
    baseURL: 'https://playground.aminhamzah.com',
    trace: 'retain-on-failure',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
    locale: 'id-ID',
    timezoneId: 'Asia/Jakarta',
    viewport: { width: 1366, height: 768 },
  },
  // webServer: { command: 'npm run start', url: 'http://localhost:3000' },  // kalau aplikasinya perlu dinyalakan dulu
  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
    { name: 'webkit', use: { ...devices['Desktop Safari'] } },
    { name: 'mobile', use: { ...devices['iPhone 13'] } },
  ],
});

Projects artinya menjalankan test yang sama dengan pengaturan berbeda (browser, perangkat, atau server). Mau menjalankan satu project saja? Ketik npx playwright test --project=mobile.

4. Retry

Retry menjalankan ulang test yang gagal. Di CI, ini membantu kalau gagalnya karena hal di luar kendali, misalnya jaringan lambat.

Lulus setelah retry tetap perlu dicek

Playwright menandai test seperti ini sebagai flaky. Selidiki penyebabnya (Modul 12), karena test flaky yang didiamkan membuat hasil test tidak bisa dipercaya.

5. Storage state: login sekali, pakai berkali-kali

Login lewat UI di setiap test memakan waktu. Storage state menyimpan cookies dan localStorage ke file JSON, dan context baru yang memakai file ini langsung dalam kondisi sudah login.

# Simpan setelah login
context.storage_state(path="auth.json")

# Pakai di context baru
context = browser.new_context(storage_state="auth.json")
// Simpan setelah login
await context.storageState({ path: 'auth.json' });

// Pakai di context baru
const context = await browser.newContext({ storageState: 'auth.json' });

Contoh lengkapnya ada di test simpan dan pakai ulang storage state di file asli Modul 11 di atas.

Cara resmi untuk project besar: buat project setup yang login sekali dan menyimpan auth.json, lalu project lain menunggu project itu selesai dulu:

TypeScript
// tests/auth.setup.ts
import { test as setup, expect } from '@playwright/test';

setup('login sekali', async ({ page }) => { // test khusus persiapan: login sekali
  await page.goto('/login-toko.html');
  await page.getByLabel('Username').fill(process.env.TOKOQA_USERNAME!); // kredensial dari .env
  await page.getByLabel('Password').fill(process.env.TOKOQA_PASSWORD!); // password dari .env
  await page.getByRole('button', { name: 'Masuk' }).click(); // klik Masuk
  await expect(page.getByTestId('greeting')).toBeVisible(); // sudah masuk
  await page.context().storageState({ path: 'playwright/.auth/user.json' }); // simpan status login ke file
});

// playwright.config.ts → projects:
// { name: 'setup', testMatch: /.*\.setup\.ts/ },
// { name: 'chromium', use: { ...devices['Desktop Chrome'], storageState: 'playwright/.auth/user.json' }, dependencies: ['setup'] },

Cara untuk project besar: buat fixture scope="session" yang login sekali dan menyimpan auth.json, lalu timpa browser_context_args supaya memakai storage_state itu. Semua test langsung dalam kondisi login.

auth.json juga rahasia

File storage state berisi cookie atau token yang masih aktif, jadi siapa pun yang memegangnya bisa masuk sebagai kamu. Masukkan ke .gitignore, sama seperti .env.

Lebih jauh (opsional)Trik komunitas
  • Setup project + storage state (TypeScript) adalah cara resmi untuk login sekali lalu dipakai semua test.
  • Pengaturan yang dicek otomatis di Python: pydantic-settings membaca .env ke dalam class dan langsung protes kalau ada variabel yang lupa diisi.
  • Data acak dengan Faker: faker (Python) atau @faker-js/faker (TypeScript) membuat nama, email, dan alamat yang berbeda setiap kali test jalan.
  • Satu pengaturan, banyak server: ambil BASE_URL dari environment variable, jadi test yang sama bisa diarahkan ke lokal, staging, atau produksi.
  • Storage state lengkap: aplikasi yang menyimpan sesi di IndexedDB bisa ikut disimpan dengan opsi indexed_db=True / indexedDB: true (v1.51+).
import os  # untuk membaca environment variable
BASE_URL = os.getenv("BASE_URL", "https://playground.aminhamzah.com")   # uv run pytest --base-url juga bisa
context.storage_state(path="auth.json", indexed_db=True)  # ikut simpan IndexedDB (untuk aplikasi yang memakainya)
// playwright.config.ts
use: { baseURL: process.env.BASE_URL ?? 'https://playground.aminhamzah.com' },
// simpan sesi termasuk IndexedDB
await context.storageState({ path: 'auth.json', indexedDB: true });

Latihan

Latihan 1

Lihat apa yang terjadi kalau password salah

Ubah TOKOQA_PASSWORD di .env menjadi salah, jalankan test Modul 11, baca errornya, lalu kembalikan nilainya.

Hasiltest yang login lewat .env gagal, lalu lulus lagi setelah dikembalikan

Latihan 2

Tambah kasus data tanpa mengubah kode

Tambahkan kasus baru di data/checkout_cases.json (Python) atau data/checkout-cases.json (TypeScript): kode pos berisi huruf, misalnya 40A11. Jalankan test Modul 11 tanpa menyentuh kodenya.

Hasilsatu test baru lulus dengan pesan "Kode pos harus 5 digit angka."

Latihan 3

Jalankan di ukuran layar ponsel

Jalankan test Modul 10 dengan profil perangkat iPhone 13.

Hasiltest tetap lulus di layar kecil

Latihan 4

Storage state untuk KlinikQA

Brief: KlinikQA menyimpan token login di localStorage (klinikqa_token). Storage state ikut menyimpan localStorage, jadi login cukup sekali.

  1. Login ke KlinikQA lewat UI sebagai pasien / sehat123.
  2. Simpan storage state context itu ke file.
  3. Buat browser context baru dari file itu, lalu buka /klinik.html.

Hasilhalaman langsung menyapa Halo, Budi Santoso tanpa mengisi form login