เขียน Test แรกด้วย Playwright
บทนี้จะพาเขียน test แรกแบบเข้าใจว่าแต่ละบรรทัดทำหน้าที่อะไร เพื่อให้คุณไม่รู้สึกว่า Playwright เป็นแค่สูตรลอกตามได้ แต่เป็นเครื่องมือที่อ่านและดัดแปลงต่อเองได้
จบบทนี้แล้วคุณจะ...
- เข้าใจโครงสร้างพื้นฐานของ test file ใน Playwright
- ใช้
test(),expect()และpageเขียน test ที่อ่านง่ายได้ - รู้ว่าการรัน test แล้วผลลัพธ์ที่เห็นใน terminal สื่อความหมายอะไร
- แยกบทบาทของ Arrange, Act, Assert ใน Playwright ได้
- เขียน test เริ่มต้นที่มี assertion มากกว่า 1 จุดอย่างมีเหตุผล
1 · โครงสร้างของ test หนึ่งตัว
Playwright test ที่ดีควรอ่านแล้วเข้าใจ flow ได้เกือบเหมือนอ่านภาษาคน
import { test, expect } from '@playwright/test';
test('should show the correct homepage title', async ({ page }) => {
await page.goto('https://playwright.dev/');
await expect(page).toHaveTitle(/Playwright/);
});
| ส่วน | หน้าที่ |
|---|---|
import { test, expect } |
นำ function หลักของ Playwright เข้ามาใช้ |
test('ชื่อ test', async ({ page }) => {}) |
ประกาศ test case หนึ่งตัว |
page |
object ที่แทน browser tab |
expect() |
ใช้ assertion เพื่อตรวจสอบผลลัพธ์ |
await |
ใช้กับ action และ assertion ที่ต้องรอผลแบบ async |
ถ้าคุณเคยเรียน AAA มาก่อน จะเห็นว่า:
- Arrange:
page.goto(...) - Act: คลิกหรือกรอกข้อมูล
- Assert:
expect(...)
2 · เริ่มจาก test ที่สั้นแต่ครบ
เป้าหมายแรกไม่ใช่เขียนเยอะ แต่เขียนให้เข้าใจ flow
ตัวอย่าง test แรก:
import { test, expect } from '@playwright/test';
test('should display correct page title', async ({ page }) => {
await page.goto('https://playwright.dev/');
await expect(page).toHaveTitle(/Playwright/);
});
เมื่อรัน:
npx playwright test
คุณจะเห็นผลลัพธ์ประมาณนี้:
Running 3 tests using 3 workers
✓ [chromium] tests/example.spec.ts:3:5 (1.2s)
✓ [firefox] tests/example.spec.ts:3:5 (1.5s)
✓ [webkit] tests/example.spec.ts:3:5 (1.3s)
3 passed (4.2s)
สิ่งที่ควรอ่านจาก output:
- test ถูกรันใน browser อะไรบ้าง
- test ไหนผ่านหรือ fail
- ใช้เวลานานเท่าไร
3 · เพิ่ม assertion ให้มีความหมายมากขึ้น
แต่ยังต้องไม่เผลอไปเช็กทุกอย่างบนหน้า
import { test, expect } from '@playwright/test';
test('should display Playwright homepage correctly', async ({ page }) => {
await page.goto('https://playwright.dev/');
await expect(page).toHaveTitle(/Playwright/);
const heading = page.getByRole('heading', { name: 'Playwright' });
await expect(heading).toBeVisible();
const getStartedLink = page.getByRole('link', { name: 'Get started' });
await expect(getStartedLink).toBeVisible();
});
ตรงนี้สอนหลักสำคัญ 2 อย่าง:
- title ผ่าน ไม่ได้แปลว่าหน้าใช้ได้ครบ
- แต่ถ้า assert รายละเอียดเล็กน้อยเกินไป test จะเปราะและอ่านยาก
4 · จัดหลาย test ในไฟล์เดียวอย่างไร
ใช้ `test.describe()` เมื่อ test หลายตัวพูดเรื่องเดียวกัน
import { test, expect } from '@playwright/test';
test.describe('Playwright Homepage', () => {
test('should have correct title', async ({ page }) => {
await page.goto('https://playwright.dev/');
await expect(page).toHaveTitle(/Playwright/);
});
test('should navigate to Get Started page', async ({ page }) => {
await page.goto('https://playwright.dev/');
await page.getByRole('link', { name: 'Get started' }).click();
await expect(page).toHaveURL(/.*intro/);
});
});
หลักคิดคือ:
- 1 test ควรพิสูจน์ 1 behavior
- test ใน describe เดียวกันควรพูดเรื่องเดียวกัน
- อย่าเอา flow หลายเรื่องมาเบียดอยู่ใน test ยาวตัวเดียว
5 · เวลาทดสอบ fail ให้ดูอะไร
อย่าเพิ่งเดา ให้เริ่มจากหลักฐานที่ Playwright ให้มา
คำสั่งที่ใช้บ่อย:
npx playwright test --ui
npx playwright test --headed
npx playwright show-report
เวลาผลลัพธ์ fail ให้ไล่เช็กทีละข้อ:
- locator ถูกไหม
- หน้ายังโหลดไม่เสร็จหรือเปล่า
- assertion กำลังเช็กสิ่งที่ผู้ใช้เห็นจริงหรือไม่
- test กำลังพยายามทำหลายเรื่องเกินไปหรือเปล่า
Practice
แบบฝึก: เขียน test แรกให้ครบ flow สั้น ๆ
เขียน test ที่ตรวจสอบ 3 อย่างบนหน้า Playwright:
- title ของหน้าต้องมีคำว่า
Playwright - ต้องมีลิงก์
Get startedที่มองเห็นได้ - เมื่อคลิกลิงก์นั้นแล้ว URL ต้องมีคำว่า
intro
ดูคำตอบแนะนำ
import { test, expect } from '@playwright/test';
test('should verify Playwright homepage', async ({ page }) => {
await page.goto('https://playwright.dev/');
await expect(page).toHaveTitle(/Playwright/);
const getStartedBtn = page.getByRole('link', { name: 'Get started' });
await expect(getStartedBtn).toBeVisible();
await getStartedBtn.click();
await expect(page).toHaveURL(/.*intro/);
});
สิ่งที่ต้องเอาติดตัวไปจากบทนี้
test()คือหน่วยพื้นฐานของ Playwright test filepageแทน browser tab ที่คุณใช้เปิดหน้า คลิก และโต้ตอบกับเว็บexpect()ใช้ยืนยันผลลัพธ์ และเป็นหัวใจของการบอกว่า test ผ่านหรือไม่- test ที่ดีควรอ่านเป็น flow ได้ชัด และทดสอบเพียง behavior เดียวต่อหนึ่ง test
- เวลา test fail ให้เริ่มจาก report, locator และ assertion ก่อนเดาสาเหตุอื่น