QA1 · Шпаргалка: тест зі сценарію, навмисний дефект, healer, Stryker

Команди, промпти й перевірки для кожного кроку завдання QA1 у навчальному застосунку «Пакунок»: агенти Playwright пишуть e2e-тест за сценарієм, а ви доводите, що тест щось ловить, — навмисним дефектом, healer під контролем і мутаційним тестуванням.

Перед початком

gitlab.com/koldovsky/ai-qa-ba-qa1

У корені копії є: playwright.config.ts

1. Старт

Форк, клон, приватна пошта для комітів — як у С1–С6. Потім залежності, браузер і перевірка, що все працює. Займає 15–30 хвилин; більшість часу — завантаження пакетів.

Де / що: Браузер · сторінка gitlab.com/koldovsky/ai-qa-ba-qa1

Fork → namespace: ваш username → Fork project

Очікуваний результат: Відкрилася ваша копія: gitlab.com/ваш-username/ai-qa-ba-qa1.

Якщо не працює

Форк робіть зі сторінки koldovsky/ai-qa-ba-qa1, а не з чужої копії.

Де / що: cmd, Git Bash чи Terminal · тека, де тримаєте проєкти курсу

git clone https://gitlab.com/ваш-username/ai-qa-ba-qa1.git
cd ai-qa-ba-qa1
git config user.email 12345678-ваш-username@users.noreply.gitlab.com
git config user.name ваш-username
git switch -c qa1

Очікуваний результат: Тека ai-qa-ba-qa1 з README.md і playwright.config.ts; ви на гілці qa1. Пошта — ваша приватна адреса з gitlab.com (Edit profile → Commit email), без --global.

Якщо не працює

Git просить пароль — використовуйте токен доступу gitlab.com як пароль, але не вставляйте його в чат агента.

Де / що: Корінь копії · один раз

npm ci
npx playwright install chromium

Очікуваний результат: Пакети встановлено з package-lock.json; браузер Chromium завантажено у ваш профіль. Попередження «2 moderate severity vulnerabilities» — відоме (Stryker).

Якщо не працює

npm audit fix не запускайте: оновлення зламає точні версії. Chromium заблоковано — розділ 10, PW_CHANNEL=msedge.

Де / що: Корінь копії · перевірка середовища

npm test
npm run e2e
npm run defects:check

Очікуваний результат: Tests 38 passed (38); 16 passed; «спіймано 3 з 3». Якщо так — середовище готове.

Якщо не працює

PowerShell пише «running scripts is disabled» — npm.cmd test, npm.cmd run e2e. Порт 4173 зайнятий — закрийте інший npm run preview чи dev.

Де / що: Корінь копії · застосунок для ручної перевірки

npm run dev

Очікуваний результат: Адреса http://localhost:5173; ваша функція — у меню. Прочитайте materials/features/NN-назва/scenarios.md до того, як просити агента.

Якщо не працює

Сторінка порожня — перевірте адресу і що команда не завершилась помилкою. Зупинити — Ctrl+C.

Що є у вашій функції

У кожній функції — усе для завдання: правила і сценарії, один «порожній» тест і дві зміни для L2.

src/features/NN-назва/
├── rules.ts            # правила функції — не змінювати
└── page.ts             # поля сторінки — не змінювати
materials/features/NN-назва/
├── scenarios.md        # правила і сценарії — джерело правди
├── ui-change.json      # L2: зміна інтерфейсу
└── behaviour-change.json  # L2: зміна поведінки
e2e/features/NN-назва.spec.ts   # один наявний тест
Чому сценарії — джерело правди

Агент, якого попросили «напиши тест на сторінку», подивиться, що сторінка показує, і запише це як очікуване. Якщо на сторінці дефект — тест його закріпить. Тому очікуване значення — зі scenarios.md, а розбіжність зі сторінкою — знахідка для звіту.

2. Агенти Playwright

Одна команда створює три агенти — planner, generator, healer — і підключає MCP-сервер playwright-test, вбудований у Playwright проєкту. Без агентів Playwright теж можна: попросіть свого агента написати і запустити тест — зараховується однаково.

Де / що: Корінь копії · один раз · для Claude Code

npx playwright init-agents --loop=claude

Очікуваний результат: Створено .claude/agents/playwright-test-{planner,generator,healer}.md, .mcp.json і specs/README.md. Наявний e2e/seed.spec.ts не перезаписано.

Якщо не працює

Інший агент — --loop=codex, copilot, opencode чи vscode: файли будуть у форматі того агента.

Де / що: Після init-agents · Claude Code

вийти з агента → запустити знову в корені копії → погодитися підключити сервер playwright-test
/mcp

Очікуваний результат: /mcp показує сервер playwright-test зі статусом connected.

Якщо не працює

Сервер не підключився — /mcp → reconnect. Не допомогло — npx playwright install chromium ще раз і перезапуск агента.

Де / що: Агент у корені копії · planner · замініть NN-назва і назву сторінки

Використай агента playwright-test-planner: склади план тестування сторінки «NN · Назва функції» (адреса /#/NN-назва) нашого застосунку. Правила функції — у materials/features/NN-назва/scenarios.md. План збережи в specs/NN-назва.md. Наприкінці коротко: скільки сценаріїв і які межі ти знайшов.

Очікуваний результат: Файл specs/NN-назва.md: групи сценаріїв, межі точками під, на і над, окремо — спірні місця. Агент працює у фоні 1–2 хвилини.

Якщо не працює

Цифри з підсумку агента звіряйте з файлом плану: у демо підсумок казав 21 сценарій, а у файлі було 23.

Що створює init-agents

.claude/agents/ і .mcp.json — командні налаштування: їх комітять разом із тестами. Описи агентів — звичайні markdown-файли з інструкціями, модель у них — sonnet.

.claude/agents/
├── playwright-test-planner.md
├── playwright-test-generator.md
└── playwright-test-healer.md
.mcp.json          # cmd /c npx playwright run-test-mcp-server (Windows)
specs/README.md    # сюди planner пише плани
e2e/seed.spec.ts   # уже є — з фіксованою датою «сьогодні»
Чому агент не заважає вашим тестам

У проєкті QA1 MCP-сервер агентів запускає власну копію застосунку на порту 4174 (playwright.config.ts). Тому npx playwright test у терміналі працює паралельно з агентом і не падає з «порт зайнятий».

Цикл і ваша перевірка

Planner → план: збігається зі сценаріями, межі є? Generator → тест: що перевіряє кожен expect і звідки очікуване? Healer → змінений тест: що він змінив і чому? Без цих трьох перевірок ви отримуєте зелені тести, а не перевірені.

3. L1 · тест зі сценарію

Щонайменше 2 сценарії зі scenarios.md вашого варіанту, один — з межею. Тести пише агент, запускаєте ви. Найважливіше — прочитати кожен expect самому.

Де / що: Агент у корені копії · generator · замініть NN-назва і номери сценаріїв

Прочитай materials/features/NN-назва/scenarios.md. Використай агента playwright-test-generator: напиши e2e-тести для сценаріїв S1 і S2 у файлі e2e/features/NN-назва.spec.ts — додай нові тести, наявний тест у файлі не чіпай. Для межі — точки під, на і над межею. Очікувані значення — зі сценаріїв. Потім запусти цей файл тестів і покажи результат.

Очікуваний результат: Нові тести в e2e/features/NN-назва.spec.ts і вивід запуску: усі зелені. Наявний тест — без змін.

Якщо не працює

Generator може не запустити тести сам — тоді попросіть головного агента запустити файл. Тест, якого не запускали, не здаємо.

Де / що: Корінь копії · ваш запуск · вивід — у звіт

npx playwright test e2e/features/NN-назва.spec.ts

Очікуваний результат: N passed. Скопіюйте вивід у звіт L1.

Якщо не працює

Тест упав одразу — спершу прочитайте помилку: локатор не знайдено чи інше значення? Друге — можливо, знахідка, а не помилка тесту.

Де / що: Читаєте самі · кожен expect · таблиця для звіту

тест → що перевіряє → звідки очікуване
S2 над межею → «До сплати: 80 грн» у result-lines → scenarios.md, S2

червоні прапорці:
toBeVisible() на блоці result (він є завжди)
лише заголовок картки, без числа
перевірка власного вводу (toHaveValue того, що заповнили)
число, якого немає в сценарії

Очікуваний результат: Кожен expect перевіряє результат правила — число, текст помилки, відсутність картки — і очікуване взято зі сценарію.

Якщо не працює

Щось виправили після агента — напишіть у звіт, що і чому. Це плюс, а не мінус.

Хороший тест: конвенції Playwright

Локатори за роллю, підписом і test id; одна дія — один крок; перевірка — конкретний результат.

test.describe('NN · Назва', () => {
  test.beforeEach(async ({ page }) => { /* як у наявному тесті */ });

  test('S2 · над межею …', async ({ page }) => {
    await page.getByLabel('Підпис поля').fill('…');
    await page.getByRole('button', { name: 'Назва кнопки' }).click();
    await expect(page.getByTestId('result-lines')).toContainText('…');
  });
});
Test id на сторінках функцій

result — блок, який є завжди (у нього вставляється і картка, і помилка). result-card — картка результату, result-title — її заголовок, result-lines — рядки з числами, result-error — текст помилки. «Картки немає» — expect(page.getByTestId('result-card')).toHaveCount(0).

4. L1 · навмисний дефект

Один дефект на правило вашого варіанту: межа, число, умова. Скрипт вносить його, проганяє e2e-тести і повертає код сам. Ваш тест має впасти.

Де / що: Файл defects/NN-коротка-назва.json · формат — defects/README.md

{
  "id": "NN-коротка-назва",
  "title": "Що зламано — мовою правила",
  "changes": [{
    "file": "src/features/NN-назва/rules.ts",
    "find": "рядок з коду — точно як у файлі",
    "replace": "той самий рядок з однією зміною"
  }]
}

Очікуваний результат: Рядок find зустрічається у файлі рівно один раз; replace — одна зміна, яку видно на сторінці: <= → <, 5 → 6, пропущена перевірка.

Якщо не працює

Скрипт пише, що рядок не знайдено чи знайдено кілька разів, — скопіюйте рядок з файлу ще раз, з усіма пробілами, або візьміть довший фрагмент.

Де / що: Корінь копії · лише ваш дефект

npm run defects:check -- --only NN-коротка-назва

Очікуваний результат: «спіймано 1 з 1» і назви тестів, що впали, у reports/defects/summary.md. Таблицю — у звіт L1.

Якщо не працює

«пропущено» — жоден тест не впав: або дефект не видно на сторінці, або тести не перевіряють цю межу. Додайте точку з того боку межі, куди зсунули.

Де / що: Агент у корені копії · пояснення результату · замініть NN

Прочитай reports/defects/summary.md і e2e/features/NN-назва.spec.ts. Поясни: які тести спіймали дефект NN-коротка-назва, а які пройшли з ним і чому. Код і тести не змінюй.

Очікуваний результат: Для кожного тесту — впав чи ні і чому: нижче межі, перевіряє лише видимість, помилка спрацьовує раніше тощо.

Якщо не працює

Агент пропонує змінити код функції чи тест — відмовтеся: тут лише пояснення.

Добрий дефект і поганий

Так: правило вашого варіанту; одна зміна, як помилка розробника; видно на сторінці; ви знаєте, який тест його ловить. Ні: ламає збірку чи всю сторінку (впаде будь-який тест — нічого не доводить); зміна, якої не видно (перейменована змінна, коментар); дефект під тест, який уже є; зміна чужої функції чи form-page.ts.

Межа — три точки

Дефект «зсув межі» ловить точка з того боку, куди зсунули. У демо межу 5 кг зсунули до 6: тест «на межі» 5 кг лишився зеленим, упав тест 5,2 кг. Тому для межі — під, на і над. Розбір — demo.html#demo3-defect.

5. L2 · набір і healer

Набір щонайменше з 3 тестів: серед них помилка і межа. Потім healer на двох змінах. Спершу закомітьте тести — щоб бачити diff healer і повертати все однією командою.

Де / що: Корінь копії · перед змінами

git add e2e
git commit -m "QA1: тести функції NN"

Очікуваний результат: Тести закомічено в гілку qa1. Тепер git diff покаже лише те, що змінить healer.

Якщо не працює

Git питає ім'я і пошту — розділ 1, git config без --global.

Де / що: Корінь копії · зміна інтерфейсу

npm run change -- materials/features/NN-назва/ui-change.json
npm run e2e

Очікуваний результат: Зміну внесено; тести вашої функції червоні.

Якщо не працює

Тести лишились зеленими — перевірте, що змінено вашу функцію (NN-назва), і перезапустіть npm run e2e.

Де / що: Агент у корені копії · healer · однаковий для обох змін

Після останньої зміни коду впали тести e2e/features/NN-назва.spec.ts. Використай агента playwright-test-healer, щоб їх полагодити. Наприкінці — що саме змінилося і що ти виправив.

Очікуваний результат: Зміна інтерфейсу: healer лагодить локатор чи крок, очікувані значення ті самі, тести зелені.

Якщо не працює

Healer змінив очікуване значення чи послабив перевірку (toBeVisible замість числа, test.fixme) — це не ремонт. Запишіть у звіт і поверніть код.

Де / що: Корінь копії · що змінив healer · потім повернути

git diff e2e
git checkout -- src e2e

Очікуваний результат: diff — лише локатори чи кроки. Після checkout код і тести — як до зміни.

Якщо не працює

Забули закомітити тести перед зміною — checkout поверне тести до останнього коміту. Тому спершу коміт.

Де / що: Корінь копії · зміна поведінки · без запобіжника

npm run change -- materials/features/NN-назва/behaviour-change.json
npm run e2e

Очікуваний результат: Червоні тести, де змінилося число правила. Далі — той самий промпт healer. Що він зробив — у звіт.

Якщо не працює

Після вправи — git checkout -- src e2e.

Класифікація перед лагодженням

Змінилась реалізація (підпис поля, текст кнопки, розмітка), поведінка за scenarios.md та сама — лагодь локатор чи крок, очікуване не чіпай. Змінилась очікувана поведінка (число, межа, текст правила) — стоп: «сценарій каже X, сторінка показує Y» → дефект чи нова вимога? Вирішує власник продукту чи аналітик, не тест і не агент.

Що в інструкції healer

Відкрийте .claude/agents/playwright-test-healer.md: виправляти локатори, перевірки й очікувані значення; питань не ставити — «зробити найрозумніше, щоб тест пройшов»; безнадійний тест — test.fixme(). Для зміни підпису кнопки це ідеально, для зміни поведінки — ризик закріпити дефект.

6. L2 · запобіжник

Правило-класифікація в правилах агента — і ще раз healer на зміні поведінки. У звіті — що змінилося. Якщо агент зупинився і без правила — це теж результат: напишіть, що його зупинило, і додайте правило однаково.

Де / що: Кінець AGENTS.md чи CLAUDE.md у корені копії — для всіх сесій

## Перед тим як лагодити тест

Тест упав — спершу класифікуй причину і напиши її користувачу:

- **Змінилася реалізація** (підпис, текст кнопки, розмітка), а поведінка за `scenarios.md` та сама — лагодь локатор чи крок.
- **Змінилася очікувана поведінка** (число, межа, текст правила) — **не змінюй очікуване значення в тесті**. Зупинись, покажи розбіжність «сценарій каже X, сторінка показує Y» і спитай: це дефект чи нова вимога? Тест змінюй лише після відповіді й оновленого `scenarios.md`.

Очікуваний результат: Правило в AGENTS.md чи CLAUDE.md. Нова сесія агента його читає.

Якщо не працює

Правило в .claude/agents/playwright-test-healer.md діє лише для healer, і його перезапише наступний init-agents.

Де / що: Корінь копії · зміна поведінки · з запобіжником

git checkout -- src e2e
npm run change -- materials/features/NN-назва/behaviour-change.json

Очікуваний результат: Та сама зміна. Нова сесія агента, той самий промпт healer. Очікувано: тести без змін, таблиця «сценарій каже / сторінка показує» і питання «дефект чи нова вимога?».

Якщо не працює

Агент пам'ятає попередню спробу — почніть нову сесію, щоб порівняння було чесним.

Де / що: Звіт L2.3 · що порівняти

без правила: що зробив healer · які тести змінив · очікуване — те саме?
з правилом: що зробив · які тести змінив · спитав?
різниця: …
якщо зупинився і без правила — що саме його зупинило (рядок відповіді агента)

Очікуваний результат: Два прогони поруч і висновок одним-двома реченнями.

Якщо не працює

Після вправи — git checkout -- src e2e.

Що було в записаних прогонах демо

Healer на зміні поведінки запускали тричі (Sonnet): з правилами проєкту, із запобіжником і без правил. Усі три рази він не змінив очікуване значення: показав 80 проти 82 і спитав. Інша модель, інший агент чи довга сесія можуть поводитися інакше — тому правило записують явно. Записи — demo.html#demo2-behaviour.

7. L2 · порожній тест

У вашому e2e/features/NN-назва.spec.ts уже є тест, який завжди зелений, але майже нічого не перевіряє. Знайти, довести дефектом, виправити.

Де / що: Агент у корені копії · знайти · замініть NN-назва

Прочитай e2e/features/NN-назва.spec.ts і materials/features/NN-назва/scenarios.md. Для кожного expect скажи: що має зламатися в продукті, щоб він упав? Знайди тест, який майже нічого не перевіряє. Нічого не змінюй.

Очікуваний результат: Тест з відповіддю «нічого» чи «сторінка не відкриється» — і чому.

Якщо не працює

Агент одразу переписує тест — зупиніть: спершу доказ дефектом.

Де / що: Корінь копії · доказ: ваш дефект з L1 проходить крізь тест

npm run defects:check -- --only NN-коротка-назва

Очікуваний результат: У reports/defects/summary.md порожнього тесту немає серед тих, що впали.

Якщо не працює

Порожній тест упав — значить, він щось перевіряє. Перечитайте його expect ще раз.

Де / що: Агент у корені копії · виправити

Виправ тест «назва тесту» у e2e/features/NN-назва.spec.ts так, щоб він перевіряв результат правила: число чи текст зі scenarios.md, а не видимість блоку. Інші тести не чіпай. Запусти файл і потім npm run defects:check -- --only NN-коротка-назва.

Очікуваний результат: Виправлений тест зелений на чистому коді і падає з дефектом.

Якщо не працює

Очікуване в новій перевірці — зі сценарію, не «що показала сторінка».

Чотири форми порожнього тесту

1 — toBeVisible() на блоці, який є завжди. 2 — заголовок картки замість числа. 3 — перевірка власного вводу. 4 — очікуване «що показала сторінка»: падає, коли дефект виправлять, і зелений, поки дефект живе.

8. L3 · юніт-тести і Stryker

Юніт-тести rules.ts і компонентні тести сторінки, бал до, щонайменше 3 живі мутанти з розбором, бал після ≥ 60%. Stryker проганяє лише Vitest — e2e на бал не впливають.

Де / що: Агент у корені копії · замініть NN-назва і NN

Напиши юніт-тести для src/features/NN-назва/rules.ts і компонентні тести для сторінки (page.ts через mountFeature у jsdom, як у src/app.test.ts) за сценаріями з materials/features/NN-назва/scenarios.md. Запусти npm test, потім npm run mutation:feature -- NN. Покажи мутаційний бал, розбери мутантів, що вижили: який сценарій чи межу вони показують. Підсиль тести і запусти мутаційне тестування ще раз. Наприкінці — бал до і після.

Очікуваний результат: src/features/NN-назва/rules.test.ts і page.test.ts; два прогони Stryker; таблиця «до / після» і розбір живих мутантів.

Якщо не працює

Агент хоче встановити пакет (наприклад, @testing-library) — не треба: компонентні тести пишуться на чистому DOM, як у src/app.test.ts.

Де / що: Корінь копії · лише ваша функція

npm test
npm run mutation:feature -- NN

Очікуваний результат: Тести зелені; mutation score функції і список живих мутантів. Бал до — з першої спроби. Звіт — reports/mutation/index.html.

Якщо не працює

«No tests were executed» — тестів функції ще немає. Бал нижче 60% — команда завершується помилкою; це очікувано до підсилення.

Де / що: Звіт L3 · розбір живого мутанта · щонайменше 3

рядок · що змінив Stryker → яке правило чи межу показує → який тест додали → вбито?
16 · > → >= → межа 30 кг: рівно 30 — ще приймаємо → тести 30 і 30,01 кг → вбито
…
еквівалентний: що змінено → чому ззовні не видно → не вбивається

Очікуваний результат: Кожен мутант — питання «а що, якби розробник помилився тут?» і відповідь тестом або поясненням.

Якщо не працює

Не підганяйте тест під розмітку: чесно пояснений еквівалентний мутант кращий за тест під реалізацію.

Бал піднімають тестами, а не порогом

Не зараховується: зниження порогу в stryker.config.mjs, // Stryker disable, .skip, тест, що повторює обчислення з коду, очікуване з виводу функції. Чесно: очікуване зі scenarios.md, кожна межа — під, на і над, точний текст помилки, живий мутант — тест або пояснення.

Мутант: три результати

killed — тест упав; survived — усі тести зелені; no coverage — жоден тест не виконує рядок. Mutation score = (вбиті + timeout) / (вбиті + timeout + живі + без покриття). Compile error у бал не входить. Повний npm run mutation не потрібен: функції інших варіантів без тестів.

9. Звіти і trace

Доказ, що тест падав і чому, — звіт Playwright і trace. Скріншоти — за бажанням у submissions/ваш-username/evidence/.

Де / що: Корінь копії · після npm run e2e

npm run e2e:report

Очікуваний результат: Звіт останнього прогону в браузері: які тести впали, очікуване й отримане. У тесту, що впав, — кнопка View Trace.

Якщо не працює

Trace зберігається лише для тестів, що впали (retain-on-failure). Зелений тест trace не має.

Де / що: Корінь копії · коли пишете тест разом з агентом

npm run e2e:ui

Очікуваний результат: Playwright UI: список тестів, запуск одного, кроки і знімки сторінки поруч.

Якщо не працює

Закрийте UI перед npm run e2e, якщо порт зайнятий.

10. Windows і корпоративний ноутбук

Типові перешкоди на робочих ноутбуках і що робити.

Де / що: PowerShell · «running scripts is disabled»

npm.cmd test
npx.cmd playwright test e2e/features/NN-назва.spec.ts

Очікуваний результат: Команди працюють без зміни політики виконання.

Якщо не працює

Або запускайте з cmd чи Git Bash.

Де / що: Chromium заблоковано · тести у встановленому Microsoft Edge

set PW_CHANNEL=msedge          :: cmd
$env:PW_CHANNEL="msedge"       # PowerShell
export PW_CHANNEL=msedge       # Git Bash

Очікуваний результат: Далі npm run e2e у тому самому вікні запускає тести в Edge.

Якщо не працює

Змінна діє лише в поточному вікні термінала.

Де / що: Чого не робити

npm audit fix
оновлювати пакети
вставляти токени й паролі в чат агента
змінювати src/features/** руками чи агентом

Очікуваний результат: Точні версії пакетів лишаються, токени — поза чатом, код функцій — без змін.

Якщо не працює

Щось не стає — питання в чат групи цього тижня, а не 17-го ввечері.

11. Здача

Один MR з гілки qa1 вашого форку в main проєкту курсу. Тести і дефект лишаються там, де їх бачать Playwright і Stryker; звіт — за шаблоном.

Де / що: Що в гілці qa1

e2e/features/NN-назва.spec.ts        # L1–L2
defects/NN-коротка-назва.json        # L1
src/features/NN-назва/*.test.ts      # L3
submissions/ваш-username/qa1.md      # звіт за templates/qa1-report.md
submissions/ваш-username/evidence/   # за бажанням
.claude/agents/, .mcp.json, specs/   # якщо використовували агентів Playwright

Очікуваний результат: Код функцій (src/features/NN-назва/rules.ts, page.ts) — без змін.

Якщо не працює

git status показує зміни в src/features/**/rules.ts чи page.ts — поверніть: git checkout -- src/features/NN-назва/rules.ts.

Де / що: Корінь копії · коміт і push

git add -A
git status
git commit -m "QA1 · ваш-username · варіант NN"
git push -u origin qa1

Очікуваний результат: Гілка qa1 у вашому форку на gitlab.com.

Якщо не працює

У git status є reports/ чи node_modules/ — не додавайте; вони мають бути в .gitignore.

Де / що: gitlab.com · ваш форк

Code → Merge requests → New merge request
source: ваш форк, гілка qa1 → target: koldovsky/ai-qa-ba-qa1, main
шаблон опису: QA1
назва: QA1 · ваш-username · варіант NN

Очікуваний результат: MR відкрито до вівторка, 17.11, 23:59. Виправлення після рев'ю — новий коміт у ту саму гілку.

Якщо не працює

У MR — лише навчальний код і тексти. Без робочих даних і токенів.

12. Словник

Терміни тестування, які звучать на занятті й у завданні, — з прикладами з функції 00 і трекера посилки. Докладніше — у конспекті, розділ 2 і розділ 4.

тест-кейс · test case

Одна перевірка: передумова, кроки, очікуваний результат. В автотесті — один test('…'), напр. «S2 · 5,2 кг по області — 80 грн».

тестовий сценарій · test scenario

Що перевіряємо — мовою користувача, без кліків. З одного сценарію — кілька тест-кейсів: S2 → 4,9 · 5 · 5,2 кг. У QA1 — S1–S5 у scenarios.md.

тестовий набір · test suite

Тести, які запускають разом: файл *.spec.ts, усі e2e через npm run e2e; група всередині файлу — test.describe.

перевірка, твердження · assertion (expect)

Рядок, що валить тест, коли факт не збігається з очікуваним: expect(…).toContainText('До сплати: 80 грн'). Тест без суттєвих перевірок не має діагностичної цінності.

тестовий оракул · test oracle

Джерело правильної відповіді. У QA1 — scenarios.md, а не те, що зараз показує сторінка: інакше тест закріплює дефект.

фікстура, тестові дані · fixture, test data

Фікстура — готове оточення до старту: { page } від Playwright (свої — через test.extend); підготовка — у beforeEach (hook); фіксована дата page.clock.setFixedTime — це stub. Тестові дані — посилки PARCELS для трекера.

локатор · locator

Спосіб знайти елемент. getByRole, getByLabel — як бачить користувач; getByTestId — окрема мітка data-testid для тестів (стабільна, але користувач її не бачить). Усі три стійкіші за CSS-селектори.

прогін · test run

Запуск набору і звіт: npx playwright test (або npm run e2e), звіт — npm run e2e:report, trace.

тестовий дублер · stub, fake, mock, spy

Підміна справжньої залежності. Stub (заглушка) — заготовлена відповідь (now: () => NOW, brokenApi, slowApi у src/app.test.ts). Fake — спрощена робоча версія (fakeApi шукає посилку в PARCELS). Mock — дублер, у якого перевіряють взаємодію: expect(fn).toHaveBeenCalledWith(…). Spy (шпигун) — записує виклики: vi.spyOn(obj, 'm') обгортає справжню функцію, vi.fn() — порожня функція-записувач. Mock і spy у QA1 не використовуються.

нестабільний тест · flaky test

То зелений, то червоний без змін у коді: залежить від часу, порядку тестів, мережі, waitForTimeout. Лікують причину, а не повторами: у QA1 дата фіксована, а локально retries: 0.

хибна тривога, пропущений дефект · false positive, false negative

Хибнопозитивний результат — тест червоний, а дефекту немає (зламаний локатор, flaky). Хибнонегативний — тест зелений, а дефект є (тест A з toBeVisible()). Не плутати з позитивним тестом — тестом на валідних даних.

піраміда тестування · test pyramid

Внизу багато швидких юніт- (модульних) і компонентних (UI) тестів, вище — менше інтеграційних і API, вгорі — мало e2e і ручних. Кожну перевірку роблять на найнижчому рівні, де вона можлива.

конус морозива · ice-cream cone

Антипатерн — перевернута піраміда: багато ручних і e2e, мало юніт. Регресія повільна й дорога, багато хибних тривог, червоний тест не каже, де дефект. Термін — Alister Scott (2012).

рівень тестування · test level

Масштаб того, що тестуємо: юніт (модульне), компонентний (UI-компонент або сторінка; не плутати з ISTQB component testing = юніт), інтеграційний (контрактний), системний (e2e), приймальний (UAT).

тип тестування · test type

Мета перевірки: функціональне, нефункціональне (швидкодія, доступність, безпека, зручність), пов'язане зі змінами (підтверджувальне, регресійне). Будь-який тип можна робити на будь-якому рівні.

чорна, біла, сіра скринька · black, white, grey box

Як спроєктовано тест, а не його рівень. Чорна — за поведінкою і scenarios.md (e2e, ручне, юніт-тест за сценарієм). Біла — за кодом (гілки rules.ts, живі мутанти Stryker). Сіра — знаєте код, тестуєте ззовні: форма робить Number(…) у form-page.ts, тож пробуєте 1e1 і 0x10 через сторінку.

димове, санітарне · smoke, sanity

Smoke — швидко, широко й неглибоко: застосунок узагалі працює (11 тестів «розрахунок працює» в e2e/features, по одному на функцію). Sanity — вузько й глибше: конкретна зміна чи виправлення після збірки. У глосарії ISTQB sanity — синонім smoke; у командах їх зазвичай розрізняють так.

підтверджувальне, регресійне · confirmation testing (re-test), regression

Разом — тестування, пов'язане зі змінами. Підтверджувальне — виправлений дефект справді виправлено. Регресія — зміна не зламала решту: npm test і npm run e2e після кожної зміни. На QA2 це робить CI автоматично.

класи еквівалентності · equivalence partitioning

Значення, які програма обробляє однаково, утворюють один клас; на клас — один представник. Для 00: вага ≤ 0, (0; 5], (5; 30], > 30, не число; маршрути місто, область, Україна. «Не число» відсікає форма (form-page.ts), тож цей клас — для компонентного чи e2e-тесту.

граничні значення · boundary value analysis

Точки на межі й поруч з обох боків: 4,99 · 5 · 5,01; 30 · 30,01; 0 · 0,01. Тут живуть дефекти «на одиницю»: < замість <=, 5 замість 6.

таблиця рішень, переходи станів · decision table, state transition

Таблиця рішень — коли результат залежить від комбінації умов (маршрут × вага → ціна). Переходи станів — коли поведінка залежить від стану (Створена → … → Отримана); рівні покриття — кожен стан, кожен допустимий перехід, недопустимі переходи.

покриття коду і mutation score · code coverage

Покриття (npm run coverage, лише тести Vitest) — які рядки виконались: юніт-тест deliveryCost(2, 'місто'), що перевіряє лише ok, виконує розрахунок і не помітить зміну ціни. Mutation score — частка виявлених мутантів: (вбиті + timeout) / (вбиті + timeout + живі + без покриття); compile error не рахується.

навмисний дефект · defect seeding

Вносимо відомий дефект у код (defects/*.json: знайти → замінити), проганяємо тести й повертаємо код. Тест, що лишився зеленим, цей дефект не бачить. У QA1 — npm run defects:check.