Բոլոր դասերը
BackendՄիջին11 րոպե ընթերցումԱրժե իմանալ

End-to-end testing Playwright-ով

Թեստավորեք ձեր հավելվածն այնպես, ինչպես օգտատերերն են այն օգտագործում՝ իրական browser-ում, ավտոմատ։

  • E2E tests
  • Locators
  • Fixtures
  • CI
  • Visual tests
Քայլ 1/6
Ծրագրավորողը push է անում կոդը։ CI/CD pipeline-ը արթնանում է, և առաջինը linter-ն է ստուգում ոճը։ Կանաչ է։

30 վայրկյանում

End-to-end (E2E) թեստերը իրական browser-ը տանում են իրական օգտատիրոջ հոսքերով, օրինակ՝ գրանցում կամ checkout, ապացուցելու համար, որ ամբողջ համակարգը միասին աշխատում է։ Microsoft-ի Playwright-ը այս թեստերն աշխատեցնում է Chromium-ում, Firefox-ում և WebKit-ում՝ auto-waiting-ով, հուսալի locator-ներով, զուգահեռ run-երով և debugging-ի համար trace viewer-ով։ Այն ամենալայն ընտրվող ժամանակակից E2E framework-ն է, որի նոր minor release-ը դուրս է գալիս մոտավորապես ամեն ամիս (1.6x՝ 2026-ի վերջին)։

Իմ ամենօրյա stack-ում չէ․ գիտեմ հիմնական գաղափարները և մանրամասները կսովորեմ, երբ նախագիծը դա պահանջի։

Ինչու է սա կարևոր

  • Unit թեստերը կարող են բոլորն անցնել, մինչ login կոճակը ոչինչ չի անում։ E2E թեստերը բռնում են frontend-ի, backend-ի, database-ի և third-party script-երի միջև առաջացող խնդիրները։
  • Playwright-ի auto-waiting-ը և web-first assertion-ները վերացնում են այն flakiness-ի մեծ մասը, որը հին E2E գործիքներին վատ համբավ էր տվել։
  • Մեկ API-ն ընդգրկում է երեք browser engine, mobile emulation, API կանչեր և վիզուալ համեմատություններ, ուստի թիմին ավելի քիչ գործիքներ են պետք։
  • Այն գտնվում է testing pyramid-ի գագաթին՝ PHPUnit-ով կամ Jest-ով unit և integration թեստերից վեր․ ավելի քիչ թեստեր, բայց դրանք պաշտպանում են այն հոսքերը, որոնք գումար են բերում։

Ինչպես է աշխատում

01E2E-ի տեղը testing pyramid-ում

Testing pyramid-ն ունի շատ արագ unit թեստեր ներքևում, ավելի քիչ integration թեստեր մեջտեղում և փոքր քանակով E2E թեստեր գագաթին։ E2E թեստերն ամենաիրատեսականն են, բայց նաև ամենադանդաղն ու պահպանման համար ամենաթանկը, ուստի օգտագործեք դրանք կրիտիկական ճանապարհների համար․ գրանցում, մուտք, որոնում, զամբյուղում ավելացում, checkout, գաղտնաբառի վերականգնում, admin-ի հիմնական գործողություններ։ Մի թեստավորեք յուրաքանչյուր validation հաղորդագրություն browser-ով․ դա unit կամ component թեստերի գործն է։ Առողջ suite-ն ունի տասնյակից մինչև մի քանի հարյուր E2E թեստ, որոնք զուգահեռ աշխատում են րոպեների ընթացքում, և յուրաքանչյուրը պաշտպանում է մի բան, որի կոտրվելը կվնասեր օգտատերերին կամ եկամտին։

02Կարգավորում և ձեր առաջին թեստը

Տեղադրեք npm init playwright@latest-ով, որը ստեղծում է config, օրինակ թեստ և GitHub Actions workflow և ներբեռնում browser-ները։ Թեստը async ֆունկցիա է, որը ստանում է fixture-ներ․ ամենակարևորը page-ն է՝ թարմ browser tab մեկուսացված browser context-ում (ինչպես նոր incognito profile) յուրաքանչյուր թեստի համար։ Էլեմենտները գտեք օգտատիրոջը տեսանելի locator-ներով, ինչպիսիք են getByRole-ը, getByLabel-ը և getByText-ը, գործողություն կատարեք դրանց վրա և ստուգեք expect-ով։ Playwright-ը ավտոմատ սպասում է, մինչև էլեմենտները տեսանելի, ակտիվ և կայուն լինեն՝ նախքան սեղմելը, իսկ web-first assertion-ները, ինչպիսիք են toBeVisible-ը և toHaveURL-ը, կրկնվում են, մինչև անցնեն կամ timeout-ը լրանա։ Ձեռքով սպասումներ գրեթե երբեք պետք չեն։

ts
import { test, expect } from "@playwright/test";
 
test("user can search and open a product", async ({ page }) => {
  await page.goto("/");
  await page.getByRole("searchbox", { name: "Search" }).fill("running shoes");
  await page.getByRole("button", { name: "Search" }).click();
 
  const results = page.getByRole("listitem").filter({ hasText: "Trail" });
  await expect(results.first()).toBeVisible();
 
  await results.first().getByRole("link").click();
  await expect(page).toHaveURL(/\/products\//);
  await expect(page.getByRole("heading", { level: 1 })).toContainText("Trail");
});

03Locator-ներ, որոնք վերապրում են redesign-ները

Flaky և փխրուն թեստերը սովորաբար գալիս են վատ selector-ներից։ div > div:nth-child(3) > button-ի նման CSS ուղին կոտրվում է, երբ դիզայները wrapper է ավելացնում։ Նախընտրեք locator-ներ, որոնք արտացոլում են այն, ինչ տեսնում են օգտատերերը և assistive technology-ն․ առաջինը getByRole՝ accessible name-ով, ապա getByLabel ձևի դաշտերի համար, getByPlaceholder, getByText, և getByTestId որպես բացահայտ պայմանագիր, երբ ոչ մի այլ բան կայուն չէ։ Locator-ները lazy և strict են․ դրանք վերագնահատվում են յուրաքանչյուր գործողության ժամանակ, և եթե մեկը համընկնում է մի քանի էլեմենտի հետ, Playwright-ը սխալ է նետում՝ սխալ էլեմենտը սեղմելու փոխարեն։ Շղթայեք և filter արեք locator-ները՝ դրանց շրջանակը սահմանելու համար, օրինակ՝ որոշակի պատվերի համար պարունակող տող։ Բոնուս․ role-ի վրա հիմնված locator-ները հավելվածը մղում են դեպի ավելի լավ accessibility։

  • Լավ է՝ page.getByRole("button", { name: "Place order" })
  • Լավ է՝ page.getByLabel("Email")
  • Խուսափեք՝ page.locator(".btn.btn-primary:nth-child(2)")

04Կոնֆիգուրացիա, project-ներ և authentication

playwright.config.ts-ը սահմանում է base URL-ը, browser-ները (project-ներ), retry-ները, reporter-ները և ինչպես գործարկել հավելվածը։ Տարածված pattern է setup project-ը, որը մեկ անգամ մուտք է գործում և պահում browser-ի storage state-ը (cookie-ներ և localStorage) ֆայլում․ մյուս project-ները նորից օգտագործում են այն, ուստի թեստերի մեծ մասը սկսվում է արդեն authenticated վիճակում՝ առանց login UI-ը կրկնելու։ webServer-ը գործարկում է ձեր հավելվածը թեստերից առաջ և սպասում դրան։ Պահեք trace-եր ձախողված retry-ների համար, ինչը տալիս է ամբողջական ձայնագրություն CI-ի ձախողումները debug անելու համար։ Մի commit արեք պահված auth ֆայլը․ թղթապանակն ավելացրեք .gitignore-ում։

ts
import { defineConfig, devices } from "@playwright/test";
 
export default defineConfig({
  testDir: "./e2e",
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  reporter: [["html"], ["list"]],
  use: { baseURL: "http://localhost:3000", trace: "on-first-retry" },
  projects: [
    { name: "setup", testMatch: /.*\.setup\.ts/ },
    { name: "chromium", dependencies: ["setup"],
      use: { ...devices["Desktop Chrome"], storageState: "playwright/.auth/user.json" } },
    { name: "mobile", dependencies: ["setup"],
      use: { ...devices["iPhone 15"], storageState: "playwright/.auth/user.json" } },
  ],
  webServer: { command: "npm run start", url: "http://localhost:3000", reuseExistingServer: !process.env.CI },
});

05Fixture-ներ և page object-ներ

Fixture-ները Playwright-ի dependency injection-ն են․ թեստը հայտարարում է, թե ինչ է իրեն պետք (page, request կամ ձեր սեփական fixture-ը, օրինակ՝ մուտք գործած admin կամ seed արված ապրանք), և Playwright-ը այն կարգավորում և մաքրում է թեստի շուրջ։ Custom fixture-ները փոխարինում են beforeEach շղթաներին և թեստերը կարճ են պահում։ Page object model-ները էջի locator-ներն ու գործողությունները փաթաթում են class-ի մեջ, ուստի UI-ի փոփոխությունը շտկվում է մեկ տեղում։ Page object-ները պահեք բարակ․ դրանք բացում են գործողություններ օգտատիրոջ լեզվով (addToCart, checkout) և assertion-ները թողնում թեստերին։ Օգտագործեք request fixture-ը՝ թեստային տվյալները API-ով ստեղծելու համար, ինչը շատ ավելի արագ է, քան UI-ով սեղմելը։

ts
import { test as base, expect } from "@playwright/test";
 
type Fixtures = { product: { slug: string } };
 
export const test = base.extend<Fixtures>({
  product: async ({ request }, use) => {
    const res = await request.post("/api/test/products", { data: { name: "E2E shoe", price: 50 } });
    const product = await res.json();
    await use(product);                                   // run the test
    await request.delete("/api/test/products/" + product.slug); // clean up
  },
});
 
test("product page shows price", async ({ page, product }) => {
  await page.goto("/products/" + product.slug);
  await expect(page.getByTestId("price")).toHaveText("$50.00");
});

06Debugging և CI

Playwright-ը գալիս է ուժեղ գործիքներով։ npx playwright test --ui-ը բացում է UI mode՝ watch mode-ով և յուրաքանչյուր քայլով time-travel-ով։ --debug-ը բացում է inspector-ը՝ գործողություններով քայլ առ քայլ անցնելու համար։ codegen-ը ձեր սեղմումները ձայնագրում է թեստի մեջ, ինչը լավ մեկնարկային կետ է, որը հետո մաքրում եք։ Trace viewer-ը ցույց է տալիս ձախողված թեստի յուրաքանչյուր գործողություն, DOM snapshot, ցանցային հարցում և console log, և այդպես եք debug անում CI-ի ձախողումները՝ առանց դրանք տեղում վերարտադրելու։ CI-ում browser-ները տեղադրեք npx playwright install --with-deps-ով, աշխատեցրեք զուգահեռ worker-ներով, մեծ suite-երը բաժանեք մեքենաների միջև --shard-ով և HTML report-ը և trace-երը վերբեռնեք որպես artifact-ներ։ Պաշտոնական Docker image-ը պարունակում է browser-ների բոլոր dependency-ները։

yaml
# .github/workflows/e2e.yml (steps)
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
  with: { node-version: 22, cache: npm }
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test --shard=${{ matrix.shard }}/4
- uses: actions/upload-artifact@v4
  if: ${{ !cancelled() }}
  with: { name: report-${{ matrix.shard }}, path: playwright-report/ }

Օգտագործեք, երբ

  • Կրիտիկական ճանապարհների, ինչպիսիք են գրանցումը, մուտքը, checkout-ը և վճարումները, պաշտպանություն regression-ներից։
  • Cross-browser ստուգումներ, հատկապես Safari-ի վարքը WebKit-ի միջոցով, և mobile viewport emulation։
  • Smoke թեստեր յուրաքանչյուր deployment-ից հետո՝ հաստատելու, որ live միջավայրն աշխատում է։
  • Visual regression ստուգումներ հիմնական էջերի և component-ների վրա։

Մի՛ օգտագործեք, երբ

  • Բիզնես տրամաբանության կամ validation-ի յուրաքանչյուր edge case-ի թեստավորում․ unit և integration թեստերն ավելի արագ և ճշգրիտ են։
  • Load testing․ մեկ browser յուրաքանչյուր օգտատիրոջ համար չափազանց ծանր է, տրաֆիկի համար օգտագործեք k6 կամ նմանատիպ գործիք։
  • Անկայուն prototype-ներ, որոնց UI-ը փոխվում է ամեն օր․ մինչև հոսքերը կայունանան, թեստերը ավելի թանկ կարժենան, քան կխնայեն։

Այլընտրանքներ

  • Cypress

    Հայտնի E2E գործիք՝ հիանալի ինտերակտիվ runner-ով․ աշխատում է browser-ի ներսում, multi-tab և multi-origin հոսքերի վրա ավելի շատ սահմանափակումներով։

  • Selenium / WebDriver

    Երկարամյա ստանդարտը՝ բոլոր լեզուներով և Selenium Grid-ով․ ավելի շատ boilerplate, ձեռքով սպասումներն ավելի տարածված են։

  • WebdriverIO

    Node.js framework WebDriver-ի և WebDriver BiDi-ի վրա, որն օգտագործվում է նաև mobile-ի համար Appium-ի հետ։

  • Vitest browser mode / Testing Library

    Component թեստեր իրական browser-ում․ UI տրամաբանության համար ավելի արագ, քան E2E-ն։

Լավագույն պրակտիկաներ

  1. Թեստավորեք օգտատիրոջը տեսանելի վարքը role, label և text locator-ներով․ data-testid-ն օգտագործեք միայն որպես բացահայտ պայմանագիր։
  2. Հենվեք auto-waiting-ի և web-first assertion-ների վրա․ երբեք մի օգտագործեք ֆիքսված waitForTimeout sleep-եր։
  3. Թեստերը պահեք անկախ․ յուրաքանչյուրը ստեղծում է իր տվյալները, իդեալում API-ով, և կարող է աշխատել ցանկացած կարգով։
  4. Մեկ անգամ մուտք գործեք setup project-ում և նորից օգտագործեք storageState-ը՝ յուրաքանչյուր թեստում UI-ով մուտք գործելու փոխարեն։
  5. Mock արեք միայն այն, ինչը ձերը չէ (third-party վճարային widget-ներ, analytics) page.route-ով․ ձեր սեփական backend-ը պահեք իրական։
  6. Trace-եր հավաքեք առաջին retry-ի ժամանակ և CI-ում վերբեռնեք report-ները․ flaky թեստին վերաբերվեք որպես շտկելու bug, ոչ թե անվերջ retry անելու։
  7. Աշխատեցրեք թեստերը զուգահեռ և CI-ում shard արեք, որպեսզի suite-ը մնա մոտ տասը րոպեից ցածր։

Տարածված սխալներ

  • Layout-ին և class-երի անուններին կապված փխրուն CSS կամ XPath selector-ների օգտագործում։
  • Flakiness-ը շտկելու համար waitForTimeout(3000)-ի ավելացում, ինչը թեստերը դարձնում է և՛ դանդաղ, և՛ դեռ flaky։
  • Թեստեր, որոնք կախված են միմյանց տվյալներից կամ կարգից և կոտրվում են զուգահեռ run-երի ժամանակ։
  • Ամեն ինչ UI-ով թեստավորելը, ինչը ստեղծում է դանդաղ suite, որը ոչ ոք տեղում չի աշխատեցնում։
  • Իրական ձախողումները թաքցնել retry-ների մեծ քանակով՝ trace-երն ուսումնասիրելու փոխարեն։

Խորը վերլուծություն

07Ինչպես է Playwright-ը կառավարում browser-ները

Playwright-ը ձեր թեստային կոդն աշխատեցնում է Node.js-ում և browser-ների հետ խոսում մշտական connection-ով․ Chromium-ի համար Chrome DevTools Protocol-ով, իսկ Firefox-ի և WebKit-ի համար՝ իր սեփական patch արված protocol-ներով։ Այս out-of-process դիզայնը թույլ է տալիս մեկ թեստին կառավարել մի քանի էջ, context և նույնիսկ browser և ուղղակիորեն դիտարկել ցանցային տրաֆիկը։ Browser context-ները էժան, մեկուսացված session-ներ են մեկ browser պրոցեսի ներսում, և ահա թե ինչու յուրաքանչյուր թեստ կարող է միլիվայրկյանների ընթացքում թարմ context ստանալ։ Playwright-ը յուրաքանչյուր release-ին կցում է browser-ների կոնկրետ build-եր․ 1.57-ից ի վեր Chromium-ի համար օգտագործում է Chrome for Testing build-եր, և դրանք տեղադրում եք npx playwright install-ով։ Լրացուցիչ վստահության համար կարող եք նաև աշխատեցնել branded Chrome-ի կամ Edge-ի դեմ channel տարբերակով։

08Ցանցի վերահսկում՝ mocking, HAR և API testing

page.route-ը intercept է անում URL pattern-ին համապատասխանող հարցումները, որպեսզի կարողանաք դրանք կատարել ֆիքսված տվյալներով, փոփոխել կամ abort անել՝ ձախողումները մոդելավորելու համար։ Այդպես եք թեստավորում «վճարային պրովայդերը չի աշխատում» իրավիճակը՝ առանց իրական պրովայդերը կոտրելու։ routeFromHAR-ը replay է անում ձայնագրված տրաֆիկը կայուն demo-ների կամ offline թեստերի համար։ request fixture-ը լիարժեք HTTP client է, որը, ցանկության դեպքում, կիսում է cookie-ները browser context-ի հետ, ուստի կարող եք ստեղծել տվյալներ, կանչել ներքին endpoint-ներ կամ գրել մաքուր API թեստեր նույն framework-ում։ Համատեղեք դրանք․ ստեղծեք պատվեր API-ով, ապա ստուգեք, որ UI-ն այն ցույց է տալիս, ինչը արագ է և ստուգում է երկու շերտն էլ։

ts
test("shows a friendly error when payments fail", async ({ page }) => {
  await page.route("**/api/payments/intent", (route) =>
    route.fulfill({ status: 503, json: { error: "unavailable" } }),
  );
  await page.goto("/checkout");
  await page.getByRole("button", { name: "Pay now" }).click();
  await expect(page.getByRole("alert")).toContainText("try again");
});

09Visual regression testing

expect(page).toHaveScreenshot()-ը screenshot է անում և այն պիքսել առ պիքսել համեմատում պահված baseline-ի հետ՝ ձախողվելով, եթե տարբերությունը գերազանցում է threshold-ը։ Առաջին run-ը ստեղծում է baseline-ը․ թարմացրեք այն միտումնավոր --update-snapshots-ով։ Screenshot-ները տարբերվում են operating system-ների և font rendering-ի միջև, ուստի baseline-ները ստեղծեք և համեմատեք նույն միջավայրում, սովորաբար CI-ում պաշտոնական Playwright Docker image-ում։ Նվազեցրեք աղմուկը․ դինամիկ տարածքները (ամսաթվեր, գովազդ, avatar-ներ) դիմակավորեք mask տարբերակով, անջատեք անիմացիաները, սպասեք font-երին և, հնարավորության դեպքում, screenshot արեք կոնկրետ component-ներ ամբողջ էջերի փոխարեն։ toMatchAriaSnapshot-ով accessibility snapshot-ները accessibility tree-ն համեմատում են որպես տեքստ, ինչը պիքսելներից պակաս փխրուն է և բռնում է կառուցվածքային regression-ները։

ts
await expect(page).toHaveScreenshot("checkout.png", {
  fullPage: true,
  mask: [page.getByTestId("order-date"), page.locator(".promo-banner")],
  animations: "disabled",
  maxDiffPixelRatio: 0.01,
});

10Suite-ի մասշտաբավորում՝ զուգահեռություն, sharding և flakiness-ի վերահսկում

Playwright-ը լռելյայն test ֆայլերն աշխատեցնում է զուգահեռ worker պրոցեսներում․ fullyParallel-ը զուգահեռացնում է նաև ֆայլի ներսի թեստերը։ Յուրաքանչյուր worker ստանում է իր browser-ը, ուստի թեստերը չպետք է կիսեն փոփոխվող տվյալներ․ ստեղծեք եզակի գրառումներ յուրաքանչյուր թեստի համար կամ օգտագործեք worker-scoped fixture-ներ, որոնք ստեղծում են մեկ account յուրաքանչյուր worker-ի համար (testInfo.workerIndex-ը օգնում է)։ CI-ում shard արեք մեքենաների միջև --shard=1/4-ով և blob report-ները միավորեք npx playwright merge-reports-ով մեկ HTML report-ի մեջ։ Հետևեք flakiness-ին․ թեստը, որը անցնում է retry-ից հետո, հաղորդվում է որպես flaky․ վերանայեք այդ ցանկը շաբաթական և շտկեք արմատային պատճառը, սովորաբար ընդհանուր state, բաց թողնված await-ներ կամ անիմացիաներ։ --repeat-each-ը և --fail-on-flaky-tests-ը օգնում են վերարտադրել և պարտադրել։ Վերջին տարբերակներն առաջարկում են նաև AI-ի օգնությամբ test agent-ներ, որոնք պլանավորում, ստեղծում և «բուժում» են թեստերը, բայց դեռ review են պահանջում։

Իրական իրավիճակներ

01

Checkout թեստը ձախողվում է միայն CI-ում

Խնդիր

Checkout E2E թեստը տեղում ամեն անգամ անցնում է, բայց CI-ում մոտավորապես հինգ run-ից մեկում ձախողվում է «element not found» սխալով։

Ինչպես լուծել

Միացրեք trace: "on-first-retry" և ձախողված run-ից ներբեռնեք trace artifact-ը։ Անցեք մինչև ձախողվող գործողությունը և ստուգեք DOM snapshot-ը և network tab-ը․ հաճախ հարցումը դեռ ընթացքի մեջ էր, toast-ը ծածկել էր կոճակը, կամ մեկ այլ զուգահեռ թեստի տվյալները փոխել էին զամբյուղը։ Դիրքով համընկնող ցանկացած locator փոխարինեք role-ով և անունով, ձեռքով սպասումները փոխարինեք web-first assertion-ներով և թեստին տվեք իր սեփական զամբյուղը fixture-ի միջոցով, որը տվյալները ստեղծում է API-ով։ Merge-ից առաջ շտկումը հաստատելու համար վերարտադրեք տեղում --repeat-each=20 --workers=4-ով։

02

Suite-ը տևում է 45 րոպե, և ոչ ոք դրան չի սպասում

Խնդիր

E2E suite-ը աճել է մինչև 600 թեստ, որոնք հաջորդաբար աշխատում են մեկ CI job-ում։ Ծրագրավորողները merge են անում առանց սպասելու, և ձախողումները հայտնաբերվում են օրեր անց։

Ինչպես լուծել

Նախ՝ կրճատեք․ validation-ի և edge case-երի թեստերը տեղափոխեք unit և component թեստեր՝ E2E-ն պահելով կրիտիկական ճանապարհների համար։ Յուրաքանչյուր թեստում UI login-ը փոխարինեք setup project-ով և storageState-ով, և տվյալները seed արեք API-ով՝ UI-ի փոխարեն։ Թեստերը դարձրեք անկախ, որպեսզի fullyParallel-ը միացնել հնարավոր լինի, ապա shard արեք չորս կամ ավելի CI մեքենաների միջև և միավորեք blob report-ները։ Tag արեք արագ @smoke ենթաբազմություն՝ յուրաքանչյուր pull request-ի ժամանակ աշխատեցնելու համար, իսկ ամբողջական suite-ը աշխատեցրեք main branch-ում և գիշերը։ Pull request-ի ստուգումների համար թիրախավորեք տասը րոպեից պակաս և flaky թեստերին հետևեք որպես bug-երի։

03

E2E թեստերի ավելացում legacy հավելվածին՝ առանց test id-ների

Խնդիր

Հին web հավելվածը չունի թեստեր, ունի անհետևողական markup և քիչ accessible label-ներ։ Թիմը մեծ refactor-ից առաջ ուզում է E2E ծածկույթ login-ի և պատվիրման համար։

Ինչպես լուծել

Սկսեք codegen-ից՝ երկու հիմնական հոսքերը ձայնագրելու համար, ապա ստեղծված selector-ները, որտեղ հնարավոր է, վերագրեք role և label locator-ներով։ Որտեղ markup-ը կայուն կեռ չի տալիս, մի քանի հիմնական էլեմենտների վրա ավելացրեք data-testid ատրիբուտներ, ինչը փոքրիկ, անվտանգ փոփոխություն է։ Ճանապարհին շտկեք բացակայող label-ները և կոճակների անունները, ինչը նաև բարելավում է accessibility-ն։ Օգտագործեք seed արված թեստային database և authentication-ի համար setup project։ Որպես անվտանգության ցանց ավելացրեք պատվերի հաստատման էջի visual snapshot։ Այս թեստերն աշխատեցրեք CI-ում refactor-ը սկսելուց առաջ, որպեսզի դրանք գործեն որպես characterisation suite, որը պաշտպանում է ընթացիկ վարքը։

Արագ ուղեցույց

Ստեղծել նոր Playwright project
npm init playwright@latest
Աշխատեցնել բոլոր թեստերը
npx playwright test
Ինտերակտիվ UI mode
npx playwright test --ui
Debug անել մեկ թեստ
npx playwright test checkout.spec.ts --debug
Ձայնագրել թեստ
npx playwright codegen http://localhost:3000
Բացել trace
npx playwright show-trace trace.zip
Տեղադրել browser-ները CI-ում
npx playwright install --with-deps
Shard անել մեքենաների միջև
npx playwright test --shard=2/4
Թարմացնել visual baseline-ները
npx playwright test --update-snapshots
Աշխատեցնել միայն tag արված թեստերը
npx playwright test --grep @smoke

Հարցեր և պատասխաններ

Q1Ինչո՞ւ է Playwright-ը ավելի քիչ flaky, քան հին E2E գործիքները։

Flakiness-ի մեծ մասը գալիս է timing-ից․ սեղմել, նախքան էլեմենտը պատրաստ է, կամ ստուգել, նախքան տվյալները բեռնվեն։ Playwright-ը յուրաքանչյուր գործողությունից առաջ կատարում է actionability ստուգումներ՝ սպասելով, մինչև էլեմենտը կցված լինի, տեսանելի, կայուն, ակտիվ և ի վիճակի լինի ստանալ իրադարձություններ։ Նրա web-first assertion-ները, ինչպիսիք են toBeVisible-ը կամ toHaveText-ը, կրկնվում են, մինչև պայմանը բավարարվի կամ timeout-ը լրանա, ուստի ձեռքով sleep-երի կարիք չկա։ Յուրաքանչյուր թեստ նաև աշխատում է թարմ browser context-ում՝ մեկուսացնելով cookie-ները և storage-ը։ Strict locator-ները սխալ են նետում, երբ համընկնում են մեկից ավելի էլեմենտի հետ՝ սխալը սեղմելու փոխարեն։ Միասին սրանք վերացնում են պատահական ձախողումների տարածված պատճառները։

Q2Ո՞ր locator-ները պետք է օգտագործել։

Օգտագործեք locator-ներ, որոնք արտացոլում են, թե ինչպես են օգտատերերը ընկալում էջը։ Առաջարկվող հերթականությունն է getByRole՝ accessible name-ով, օրինակ՝ Place order անունով կոճակ, ապա getByLabel ձևի դաշտերի համար, getByPlaceholder, getByText և getByAltText։ Օգտագործեք getByTestId, երբ օգտատիրոջը տեսանելի ոչ մի ատրիբուտ կայուն չէ՝ test id-ն դիտարկելով որպես բացահայտ պայմանագիր ծրագրավորողների և թեստերի միջև։ Խուսափեք կառուցվածքին կամ ոճավորման class-երին կապված CSS և XPath selector-ներից, քանի որ դրանք կոտրվում են redesign-ների ժամանակ։ Role locator-ները նաև ծառայում են որպես թեթև accessibility ստուգում․ եթե չեք կարող կոճակը գտնել ըստ role-ի և անվան, screen reader-ի օգտատերերը, հավանաբար, նույնպես չեն կարող։

Q3Ինչպե՞ս մշակել authentication-ը E2E թեստերում։

Յուրաքանչյուր թեստից առաջ UI-ով մուտք գործելը դանդաղ է և flakiness է ավելացնում։ Առաջարկվող մոտեցումը setup project-ն է, որը մեկ անգամ մուտք է գործում՝ UI-ով կամ API-ով, և պահում browser-ի storage state-ը, այսինքն՝ cookie-ները և localStorage-ը, ֆայլում։ Մյուս project-ները կախված են setup-ից և բեռնում են այդ state-ը, ուստի յուրաքանչյուր թեստ սկսվում է արդեն authenticated՝ իր մեկուսացված context-ում։ Տարբեր role-երի համար պահեք մեկ state յուրաքանչյուր role-ի համար, օրինակ՝ admin և customer։ Auth ֆայլը պահեք version control-ից դուրս, օգտագործեք նվիրված թեստային account-ներ՝ environment variable-ներից եկող գաղտնիքներով, և պահեք մեկ թեստ, որը ծածկում է իրական login հոսքը։

Q4Ի՞նչ է trace viewer-ը և ինչո՞ւ է այն կարևոր։

Trace viewer-ը թեստի run-ի ձայնագրությունն է․ յուրաքանչյուր գործողություն, DOM snapshot դրանից առաջ և հետո, ցանցային հարցումներ, console հաղորդագրություններ, screenshot-ներ և source-ի տողը։ Այն միացնում եք config-ում, սովորաբար trace on-first-retry, ուստի CI-ը trace է պահում ամեն անգամ, երբ թեստը մեկ անգամ ձախողվում է։ Այն բացում եք տեղում npx playwright show-trace-ով կամ trace.playwright.dev-ում և քայլ առ քայլ անցնում ձախողման միջով, կարծես օգտատիրոջ ուսի վրայով եք նայում։ Այն միայն CI-ում ձախողվող թեստերի «իմ մեքենայի վրա աշխատում է» debugging-ը ժամերից դարձնում է րոպեներ, ինչը Playwright-ի ամենամեծ գործնական առավելություններից մեկն է։

Q5Պե՞տք է արդյոք E2E թեստերը mock անեն backend-ը։

Հիմնականում՝ ոչ։ E2E testing-ի նպատակն է ստուգել, որ frontend-ը, backend-ը և database-ը միասին աշխատում են, ուստի ձեր սեփական backend-ը mock անելը այն վերածում է ավելի դանդաղ component թեստի։ Mock արեք այն, ինչը չեք վերահսկում և չեք կարող հուսալիորեն աշխատեցնել․ third-party վճարային էջեր, analytics, քարտեզներ, email պրովայդերներ կամ անկայուն partner API։ Playwright-ի page.route-ը թույլ է տալիս intercept անել այդ հարցումները և վերադարձնել ֆիքսված պատասխաններ կամ սխալներ, ինչը նաև հիանալի է սխալի վիճակները թեստավորելու համար։ Ձեր սեփական համակարգի համար տվյալները seed արեք թեստային API-ներով կամ database fixture-ներով և աշխատեցրեք նվիրված միջավայրի դեմ, որը կարող եք reset անել։

Q6Playwright, թե՞ Cypress։

Երկուսն էլ ուժեղ են։ Cypress-ը աշխատում է browser-ի ներսում և առաջարկում է շատ փայլեցված ինտերակտիվ runner, և շատ թիմեր այն լավ գիտեն։ Playwright-ը կառավարում է browser-ները դրսից՝ դրանց protocol-ների միջոցով, ինչը տալիս է բնիկ աջակցություն մի քանի tab-երի, մի քանի origin-ների, iframe-ների, download-ների և WebKit-ի համար՝ Safari-ի ծածկույթով։ Զուգահեռ կատարումը և sharding-ը ներկառուցված են և անվճար, և այն աջակցում է TypeScript, JavaScript, Python, Java և .NET։ 2026-ին նոր project-ի համար ես սովորաբար կընտրեի Playwright-ը այդ լայնության և արագության համար․ մեծ, առողջ Cypress suite ունեցող թիմի համար միգրացիան իմաստ ունի միայն այն դեպքում, եթե դրա սահմանափակումներն իսկապես ցավ են պատճառում։

Սենիոր մակարդակի հարցեր

S1Ինչպե՞ս նախագծել թեստային տվյալների կառավարումը զուգահեռ E2E suite-ի համար։

Զուգահեռ թեստերը ձախողվում են, երբ կիսում են փոփոխվող state, ուստի յուրաքանչյուր թեստի պետք են իրեն պատկանող տվյալներ։ Ես նախընտրում եմ տվյալներ ստեղծել միայն թեստերի համար նախատեսված API-ով կամ ոչ production միջավայրերում բացված factory-ներով՝ փաթաթված fixture-ներում, որոնք ստեղծում և մաքրում են։ Թանկ setup-ի համար worker-scoped fixture-ները ստեղծում են մեկ account յուրաքանչյուր worker-ի համար՝ workerIndex-ով։ Ընդհանուր read-only reference տվյալները, օրինակ՝ ապրանքների կատալոգը, seed են արվում մեկ անգամ յուրաքանչյուր միջավայրի համար։ Եզակի նույնացուցիչները (timestamp-ներ կամ UUID-ներ email-ներում և անուններում) կանխում են բախումները։ Միջավայրը պետք է reset անելի լինի․ իդեալը ephemeral database է յուրաքանչյուր pipeline-ի համար, հակառակ դեպքում՝ գիշերային reset։ Փոխզիջումը ջանքն է․ թեստային API-ները պետք է պաշտպանված և production-ում անջատված լինեն, բայց դրանք թեստերը դարձնում են ավելի արագ և շատ ավելի հուսալի, քան UI-ով setup-ը։

S2Ինչպե՞ս որոշել, թե ինչն է պատկանում E2E-ին, իսկ ինչը՝ ավելի ցածր թեստային մակարդակներին։

Ես քարտեզագրում եմ ռիսկն ու արժեքը։ E2E թեստերը լավագույնն են ամբողջ stack-ով ինտեգրացիան ստուգելու համար այն ճանապարհներով, որոնք ամենակարևորն են․ եկամուտ, անվտանգություն և onboarding։ Յուրաքանչյուր այդպիսի ճանապարհ ստանում է մեկ happy path և գուցե մեկ կարևոր failure path։ Բազմաթիվ համակցություններով բիզնես կանոնները, օրինակ՝ զեղչի հաշվարկը, պատկանում են unit թեստերին․ API պայմանագրերը և database-ի վարքը՝ integration թեստերին․ UI state-ը և validation-ը՝ component թեստերին։ Օգտակար կանոն․ եթե bug-ը կարող էր բռնվել միայն իրական browser-ով և իրական backend-ով միասին, այն արժանի է E2E ծածկույթի։ Ես նաև վերանայում եմ production-ի incident-ները․ եթե մեկը վրիպել է, թեստ եմ ավելացնում ամենացածր մակարդակում, որը կբռներ այն, և E2E բարձրանում եմ միայն անհրաժեշտության դեպքում։

S3Ինչպե՞ս կներդնեիք Playwright-ը դանդաղ, flaky Selenium suite ունեցող թիմում։

Ես ամեն ինչ միանգամից չէի վերագրի։ Նախ չափեք ընթացիկ suite-ը․ տևողություն, flake rate և որ թեստերն են իրական bug-եր բռնում։ Ապա ընտրեք հինգ ամենաարժեքավոր ճանապարհները և իրականացրեք դրանք Playwright-ով՝ role-ի վրա հիմնված locator-ներով, fixture-ներով, storageState-ով և trace-երով, աշխատեցնելով CI-ում հին suite-ի կողքին։ Մի քանի շաբաթվա ընթացքում ցույց տվեք տևողության և կայունության տարբերությունը։ Կարճ ուղեցույցում համաձայնեցրեք convention-ները․ locator-ների առաջնահերթություն, ոչ մի ֆիքսված սպասում, տվյալներ API-ով, page object-ներ ընդհանուր էջերի համար։ Միգրացիա արեք ըստ առաջնահերթության և ջնջեք յուրաքանչյուր Selenium թեստ, երբ դրա փոխարինողը կայուն է, կրկնօրինակներ պահպանելու փոխարեն։ Հիմնական ռիսկերն են թեստային տվյալների աշխատանքի և ուսուցման կորի թերագնահատումը, ուստի pair programming-ը և թեստերի code review-ները նույնքան կարևոր են, որքան գործիքը։

Բառարան

End-to-end test
Թեստ, որը իրական հավելվածը տանում է ամբողջական օգտատիրոջ հոսքով՝ frontend-ից մինչև database։
Locator
Էջում էլեմենտ գտնելու lazy, վերագնահատվող նկարագրություն։
Auto-waiting
Playwright-ը սպասում է, մինչև էլեմենտը պատրաստ լինի՝ նախքան դրա վրա գործողություն կատարելը, առանց ձեռքով sleep-երի։
Web-first assertion
Expect ստուգում, որը կրկնվում է, մինչև պայմանը բավարարվի կամ timeout-ը լրանա։
Browser context
Մեկուսացված browser session՝ իր cookie-ներով և storage-ով, ինչպես թարմ profile։
Fixture
Setup-ի և teardown-ի բազմակի օգտագործվող մաս, որը թեստը պահանջում է անունով։
storageState
Պահված cookie-ներ և local storage, որոնք օգտագործվում են թեստերն արդեն մուտք գործած վիճակում սկսելու համար։
Trace
Թեստի run-ի ձայնագրություն՝ գործողություններով, DOM snapshot-ներով, ցանցով և console log-երով։
Sharding
Test suite-ի բաժանում մի քանի մեքենաների միջև՝ այն ավելի արագ աշխատեցնելու համար։
Flaky test
Թեստ, որը երբեմն անցնում է, երբեմն ձախողվում՝ առանց կոդի որևէ փոփոխության։

Պրոդուկտի գաղափար ունե՞ք։Եկեք ստեղծենք այն։

Պատմեք ձեր գաղափարի, պրոդուկտի կամ թիմի մասին։ Սովորաբար պատասխանում եմ մեկ աշխատանքային օրվա ընթացքում։