← Valtive QA Quiz quiz.valtive.io/notes/qabasics valtive.io
📖 Про цей гайд📖 About this guide
Для когоWho it's for
Для мануальних тестувальників і тих, хто тільки заходить у QA, а також для автоматизаторів, яким на співбесіді все одно ставлять питання з теорії. Гайд проходить шлях від принципів ISTQB і рівнів тестування до технік тест-дизайну, документації, життєвого циклу дефекту, Agile-процесу і senior-сценаріїв на кшталт «реліз завтра, а вимог немає». Терміни узгоджені з глосарієм ISTQB CTFL 4.0, а кожне питання квізу «Теорія тестування» покрите щонайменше однією карткою.
For manual testers and people just entering QA, and for automation engineers who still get theory questions in interviews. The guide goes from the ISTQB principles and test levels to test design techniques, documentation, the defect life cycle, the Agile process and senior scenarios such as "the release is tomorrow and there are no requirements". Terms follow the ISTQB CTFL 4.0 glossary, and every question of the Testing Theory quiz is covered by at least one card.
Як користуватисьHow to use it
Фільтруй питання за рівнем або розділом. Відкрий картку, прочитай відповідь, а потім розбери артефакт під нею: таблицю класів еквівалентності, діаграму станів, тест-кейс, матрицю ризиків чи SQL-запит. Спробуй скласти такий самий артефакт для фічі зі свого проєкту. Наостанок закрий текст і перекажи відповідь уголос за блоком 🗣 Як читати вголос — на співбесіді оцінюють, як ти пояснюєш, а не лише те, що ти знаєш.
Filter the questions by level or by section. Open a card, read the answer, then work through the artefact below it: an equivalence partition table, a state diagram, a test case, a risk matrix or an SQL query. Try to build the same artefact for a feature from your own project. Finally hide the text and retell the answer out loud using the 🗣 How to say it out loud block — an interview judges how you explain things, not only what you know.
Три якорі — з них випливає більшість відповідейThree anchors — most answers follow from them
ЯКІР 1 · ПринципиANCHOR 1 · Principles
Тестування дає інформацію про ризик, а не доказ відсутності багів. Повне тестування неможливе, тому завжди є вибір: що перевірити глибше, а що свідомо залишити.
Testing gives information about risk, not proof that there are no bugs. Exhaustive testing is impossible, so there is always a choice: what to check more deeply and what to leave out on purpose.
ЯКІР 2 · Тест-дизайнANCHOR 2 · Test design
Класи еквівалентності, межі, таблиці рішень і переходи станів перетворюють «потестуй форму» на скінченний набір перевірок, кожну з яких можна обґрунтувати.
Partitions, boundaries, decision tables and state transitions turn "go test the form" into a finite set of checks, each of which you can justify.
ЯКІР 3 · Дефекти й процесANCHOR 3 · Defects and process
Знайдений дефект має пройти відомий життєвий цикл, а QA працює в спринті від уточнення історії до Definition of Done, а не лише наприкінці перед релізом.
A defect you find goes through a known life cycle, and QA works across the sprint, from refining the story to the Definition of Done, not only at the end before a release.
69
питаньquestions
3
рівніlevels
—
voice-блокиvoice blocks
55/55
питань квізу покритоquiz questions covered
📚 7 РОЗДІЛІВ📚 7 SECTIONS
—
Junior
—
Middle
—
Senior
▶ 1 11
1 Що таке тестування програмного забезпечення і чим воно не є? What is software testing, and what is it not?
ПринципиPrinciples Junior ▶

Що це. Тестування — це набір дій, які дають команді інформацію про якість продукту: ми порівнюємо фактичну поведінку системи з очікуваною, шукаємо відмови й оцінюємо ризики, що лишились. ISTQB CTFL 4.0 включає сюди не лише запуск програми (динамічне тестування), а й аналіз вимог, рев'ю коду та документів (статичне тестування).

What it is. Testing is a set of activities that gives the team information about product quality: we compare the actual behaviour of the system with the expected one, look for failures and assess the risks that remain. ISTQB CTFL 4.0 counts not only running the software (dynamic testing) but also analysing requirements and reviewing code and documents (static testing).

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

Why it matters. The goals are to find defects before users do, confirm that requirements are met, give the business grounds for a go/no-go decision and reduce risk. The key point is that the output of testing is knowledge, not a green tick.

Приклад. Для відновлення пароля тестувальник перевіряє не лише щасливий шлях, а й прострочене посилання, повторне використання токена, чужий email. Кожна перевірка додає факт: «посилання після 24 годин не працює — як і вимагає специфікація».

Example. For password reset a tester checks not only the happy path but also an expired link, a reused token and someone else's email. Each check adds a fact: "after 24 hours the link stops working, as the specification requires".

Підводні камені. Тестування не доводить відсутність помилок, не є лише пошуком багів і не дорівнює налагодженню: debugging робить розробник, коли вже знає про відмову. Ще одна хибна думка — що тестування починається після написання коду.

Pitfalls. Testing does not prove the absence of bugs, it is not only bug hunting, and it is not debugging: debugging is what a developer does once a failure is known. Another misconception is that testing only starts after the code is written.

Вимога → перевірка → результат для скидання пароля
Requirement → check → result for password reset
Вимога                 | Перевірка              | Результат
-----------------------+------------------------+-----------
Лист приходить ≤ 1 хв  | Запит на існуючий email| PASS
Посилання живе 24 год  | Відкрити через 25 год  | PASS
Токен одноразовий      | Відкрити посилання двічі| FAIL
Не видає, чи є акаунт  | Запит на невідомий email| PASS
Requirement            | Check                  | Result
-----------------------+------------------------+-----------
Email arrives ≤ 1 min  | Request for known email| PASS
Link valid 24 h        | Open it after 25 h     | PASS
Token is single-use    | Open the link twice    | FAIL
No account enumeration | Request unknown email  | PASS
🔧 Як читати: кожен рядок пов'язує вимогу з конкретною дією та фактом. FAIL у третьому рядку — це інформація для рішення: реліз з токеном, який працює двічі, відкриває дірку в безпеці. Останній рядок — неявна вимога, яку тестувальник додав сам.
🔧 How to read it: each row links a requirement to a concrete action and a fact. The FAIL in the third row is input for a decision: releasing with a token that works twice opens a security hole. The last row is an implicit requirement the tester added on their own.
💡 Простими словами: тестування відповідає на питання «що ми знаємо про якість зараз», а не «чи немає там багів».
💡 In plain words: testing answers "what do we know about quality right now", not "are there no bugs left".
🗣 Як читати вголос Для мене тестування — це спосіб дати команді правдиву картину якості. Я звіряю, як система поводиться насправді, з тим, як вона має поводитись, і шукаю місця, де вона ламається. Сюди входить і читання вимог, і рев'ю, не тільки клікання по готовій збірці. Я ніколи не кажу, що після тестування багів немає, — я кажу, що перевірено, що знайдено і які ризики лишились. І я розрізняю тестування та налагодження: я знаходжу й описую відмову, а причину в коді шукає розробник.
🗣 How to say it out loud To me testing is how I give the team an honest picture of quality. I compare how the system really behaves with how it should behave and look for the places where it breaks. That includes reading requirements and taking part in reviews, not just clicking through a finished build. I never claim that a tested product has no bugs; I report what was covered, what I found and which risks remain. I also keep testing and debugging apart: I find and describe the failure, and the developer tracks down the cause in the code.
2 Чим верифікація відрізняється від валідації? How does verification differ from validation?
ПринципиPrinciples Junior ▶

Що це. Класичне формулювання Баррі Боема: верифікація — «Are we building the product right?» (чи правильно ми будуємо продукт, тобто чи відповідає він специфікації), валідація — «Are we building the right product?» (чи той продукт ми будуємо, тобто чи розв'язує він реальну потребу користувача).

What it is. Barry Boehm's classic wording: verification asks "Are we building the product right?" — does it conform to the specification; validation asks "Are we building the right product?" — does it solve the user's real need.

Навіщо. Продукт може ідеально відповідати специфікації й усе одно бути марним, якщо сама специфікація хибна. Верифікація ловить відхилення від документа (рев'ю, тест-кейси за вимогами, статичний аналіз), валідація — відхилення від потреби (UAT, демо стейкхолдерам, бета, юзабіліті-тести).

Why it matters. A product can match its specification perfectly and still be useless if the specification itself is wrong. Verification catches deviations from the document (reviews, requirement-based test cases, static analysis); validation catches deviations from the need (UAT, stakeholder demos, beta, usability tests).

Приклад. У специфікації сказано: «звіт експортується у PDF». Команда зробила PDF, усі тести зелені — верифікація пройдена. На демо бухгалтер питає, як тепер вставити цифри в Excel, бо щомісяця він робить саме це. Валідація провалена: правильно зроблено не те.

Example. The specification says "the report is exported to PDF". The team built PDF export and every test is green — verification passed. At the demo the accountant asks how to paste the numbers into Excel now, because that is exactly what he does every month. Validation failed: the wrong thing was built correctly.

Підводні камені. Часто кажуть, що верифікація — «статична», а валідація — «динамічна». Це спрощення: тест-кейс за вимогою, виконаний на збірці, — теж верифікація. Відрізняє їх не техніка, а еталон, з яким порівнюємо: документ чи потреба.

Pitfalls. People often say verification is "static" and validation is "dynamic". That is a simplification: a requirement-based test case run on a build is verification too. What separates them is not the technique but the reference we compare against: a document or a need.

Одна фіча — дві перевірки
One feature, two checks
Фіча: експорт місячного звіту

             | Верифікація            | Валідація
-------------+------------------------+-----------------------
Питання      | Зроблено за специфікою?| Це те, що потрібно?
Еталон       | Вимога REQ-41: PDF     | Робота бухгалтера
Як           | Тест-кейс, рев'ю       | Демо, UAT, інтерв'ю
Результат    | PDF коректний: PASS    | Потрібен XLSX: FAIL
Feature: monthly report export

             | Verification           | Validation
-------------+------------------------+-----------------------
Question     | Built to the spec?     | Is it what's needed?
Reference    | Requirement REQ-41: PDF| Accountant's workflow
How          | Test case, review      | Demo, UAT, interviews
Result       | PDF correct: PASS      | Needs XLSX: FAIL
🔧 Як читати: колонки показують ту саму фічу з двох боків. Рядок «Еталон» — головний: верифікація порівнює з REQ-41, валідація — з реальним процесом користувача. Зелена верифікація і червона валідація одночасно — типова ситуація, коли помилка сидить у вимозі.
🔧 How to read it: the columns show the same feature from two sides. The Reference row is the key one: verification compares with REQ-41, validation with the user's real workflow. Green verification next to red validation is the typical sign that the mistake lives in the requirement.
💡 Простими словами: верифікація — «зробили як написано», валідація — «написали те, що треба».
💡 In plain words: verification means "built as written"; validation means "what was written is what people need".
🗣 Як читати вголос Я пам'ятаю це через дві фрази Боема: чи правильно ми будуємо продукт і чи той продукт ми будуємо. Перше — верифікація, я звіряю результат зі специфікацією, наприклад тест-кейсами за вимогами. Друге — валідація, тут еталон — справжня потреба людини, і перевіряємо її на демо, в UAT чи на беті. Мій улюблений приклад — експорт у PDF, який зроблений бездоганно, але бухгалтеру потрібен був Excel. Тож для мене різниця не в тому, статична техніка чи динамічна, а в тому, з чим саме я порівнюю.
🗣 How to say it out loud I remember it through Boehm's two questions: are we building the product right, and are we building the right product. The first is verification, where I compare the result with the specification, for instance through requirement-based test cases. The second is validation, and there the reference is the person's actual need, checked in a demo, in UAT or in a beta. My favourite example is a flawless PDF export when the accountant really wanted Excel. So for me the difference is not static versus dynamic, it is what I am comparing against.
3 Як пов'язані помилка, дефект і відмова? How are an error, a defect and a failure related?
ПринципиPrinciples Junior ▶

Що це. За глосарієм ISTQB це ланцюжок. Помилка (error, mistake) — дія людини, що дає хибний результат: неуважно прочитана вимога, описка в умові. Дефект (defect, bug, fault) — вада в артефакті: у коді, вимозі, тест-кейсі. Відмова (failure) — момент, коли система під час роботи поводиться не так, як мала б.

What it is. In the ISTQB glossary this is a chain. An error (mistake) is a human action that produces a wrong result: a misread requirement, a typo in a condition. A defect (bug, fault) is an imperfection in a work product: code, a requirement, a test case. A failure is the moment the system behaves differently from what it should while running.

Навіщо. Розрізнення підказує, де шукати і що фіксувати. Тестувальник бачить відмову й описує її; розробник знаходить дефект; ретроспектива або RCA з'ясовує, яка помилка людини і чому до нього призвела.

Why it matters. The distinction tells you where to look and what to record. A tester observes the failure and describes it; a developer locates the defect; a retrospective or RCA finds out which human error led to it and why.

Приклад. Вимога: знижка 10% «для замовлень від 1000 грн», тобто включно з 1000. Розробник пише > замість >= — це помилка, а сам рядок коду — дефект. Клієнт з кошиком рівно на 1000 грн не отримує знижку — це відмова.

Example. The requirement: a 10% discount "for orders from 1000 UAH", i.e. including 1000. The developer writes > instead of >= — that is the error, and the line of code is the defect. A customer with a cart of exactly 1000 UAH gets no discount — that is the failure.

Підводні камені. Не кожен дефект стає відмовою: якщо ніхто не купує рівно на 1000 грн, вада мовчить роками. І не кожна відмова походить від дефекту в коді: причиною може бути середовище — повний диск, неправильний часовий пояс сервера, радіація в пам'яті. Тому в баг-репорті описують відмову, а не гадають про дефект.

Pitfalls. Not every defect becomes a failure: if nobody buys for exactly 1000 UAH, the flaw stays silent for years. And not every failure comes from a code defect: the cause can be the environment — a full disk, a wrong server time zone, radiation flipping a memory bit. That is why a bug report describes the failure instead of guessing the defect.

Ланцюжок на прикладі знижки
The chain on a discount example
// ПОМИЛКА: розробник вирішив, що «від 1000» означає «більше 1000»
function discount(total) {
  if (total > 1000) return total * 0.1;  // ДЕФЕКТ: має бути >=
  return 0;
}

// ВІДМОВА під час роботи:
discount(1000);  // фактично 0, очікувалось 100
discount(1500);  // 150 — тут дефект не проявляється
// ERROR: the developer read «from 1000» as «more than 1000»
function discount(total) {
  if (total > 1000) return total * 0.1;  // DEFECT: should be >=
  return 0;
}

// FAILURE at run time:
discount(1000);  // actual 0, expected 100
discount(1500);  // 150 — the defect stays hidden here
🔧 Як читати: коментарі позначають три ланки. Помилка живе в голові людини, дефект — у рядку з >, відмова — лише у виклику з 1000. Виклик з 1500 показує, чому дефект може роками не давати відмов: його «будить» тільки граничне значення.
🔧 How to read it: the comments mark the three links. The error lives in a person's head, the defect in the line with >, the failure only in the call with 1000. The call with 1500 shows why a defect can go years without a failure: only the boundary value wakes it up.
💡 Простими словами: людина помилилась → у коді з'явилась вада → користувач побачив збій.
💡 In plain words: a person slipped up → a flaw landed in the code → a user saw something go wrong.
🗣 Як читати вголос Я пояснюю це як ланцюжок причин. Спершу людина помиляється, скажімо, розуміє «від тисячі» як «більше тисячі». Через це в коді з'являється дефект — знак більше замість більше-або-дорівнює. А відмову я, тестувальник, бачу вже під час роботи: кошик рівно на тисячу без знижки. Цікаво, що з кошиком на півтори тисячі все працює, тобто дефект може довго мовчати. І ще я пам'ятаю, що збій не завжди від коду — буває, що винне середовище, тому в репорті я описую те, що бачу, а не вгадую причину.
🗣 How to say it out loud I explain it as a chain of causes. First a person makes a mistake, say they read "from a thousand" as "more than a thousand". Because of that a defect appears in the code, a greater-than sign where greater-or-equal belongs. The failure is what I, as a tester, see at run time: a cart of exactly one thousand with no discount. Funny enough, a cart of fifteen hundred works fine, so a defect can sit quietly for a long time. And a failure is not always caused by code; sometimes the environment is to blame, so in my report I describe what I observe rather than guess the cause.
4 Які сім принципів тестування ISTQB і що кожен означає на практиці? What are the seven ISTQB testing principles, and what does each mean in practice?
ПринципиPrinciples Junior ▶

Що це. У CTFL 4.0 принципи звучать так: 1) тестування показує наявність дефектів, а не їх відсутність; 2) вичерпне тестування неможливе; 3) раннє тестування заощаджує час і гроші; 4) дефекти скупчуються; 5) тести зношуються (раніше — «парадокс пестициду»); 6) тестування залежить від контексту; 7) хибне уявлення про відсутність дефектів.

What it is. In CTFL 4.0 the principles read: 1) testing shows the presence, not the absence of defects; 2) exhaustive testing is impossible; 3) early testing saves time and money; 4) defects cluster together; 5) tests wear out (formerly the "pesticide paradox"); 6) testing is context dependent; 7) the absence-of-defects fallacy.

Навіщо. Принципи — не цитати для співбесіди, а аргументи в щоденних рішеннях: чому ми не обіцяємо «нуль багів», чому потрібні техніки тест-дизайну, чому QA кличуть на рев'ю вимог і чому регресійний набір треба оновлювати.

Why it matters. The principles are not interview quotes but arguments in everyday decisions: why we never promise "zero bugs", why test design techniques are needed, why QA is invited to requirement reviews and why a regression suite has to be refreshed.

Приклад. Форма з п'ятьма полями по 100 можливих значень дає 1010 комбінацій — ось принцип 2 у цифрах; тому ми беремо класи еквівалентності й межі. Банківський застосунок і мобільна гра потребують зовсім різної глибини — принцип 6.

Example. A form with five fields of 100 possible values each gives 1010 combinations — that is principle 2 in numbers, which is why we pick equivalence classes and boundaries. A banking app and a mobile game need completely different depth — principle 6.

Підводні камені. Сьомий принцип часто плутають з першим. Перший про межі знання («не знайшли ≠ немає»), сьомий — про цінність: система без жодного відомого дефекту може бути непридатною, якщо вона не розв'язує задачу користувача або повільна.

Pitfalls. The seventh principle is often confused with the first. The first is about the limits of knowledge ("not found ≠ not there"), the seventh about value: a system with no known defect can still be unusable if it does not solve the user's problem or is too slow.

Принцип → наслідок у проєкті
Principle → consequence on a project
# | Принцип                  | Однорядковий приклад
1 | Показує наявність        | 300 зелених тестів ≠ «багів немає»
2 | Вичерпне неможливе       | 10^10 комбінацій форми → беремо EP/BVA
3 | Раннє тестування         | Суперечність у вимозі знайдена на рев'ю
4 | Скупчення дефектів       | 40% багів у модулі оплати → більше тестів там
5 | Тести зношуються         | Той самий регрес пів року нічого не ловить
6 | Залежить від контексту   | Банк: аудит і безпека; гра: ігровий досвід
7 | Хибна відсутність дефектів| Жодного бага, але користувачі не купують
# | Principle                | One-line example
1 | Shows presence           | 300 green tests ≠ "no bugs"
2 | Exhaustive is impossible | 10^10 form combos → use EP/BVA
3 | Early testing            | Contradiction in a spec caught in review
4 | Defects cluster          | 40% of bugs in payments → test more there
5 | Tests wear out           | Same regression suite finds nothing for 6 mo
6 | Context dependent        | Bank: audit and security; game: experience
7 | Absence-of-defects fallacy| Zero known bugs, yet users don't buy
🔧 Як читати: ліва колонка — формулювання CTFL 4.0, права — ситуація, у якій принцип змінює рішення команди. Числа в рядках 2 і 4 — ілюстрація, а не статистика: 40% — це приклад того, що бачать у баг-трекері конкретного проєкту.
🔧 How to read it: the left column is the CTFL 4.0 wording, the right one a situation where the principle changes a team decision. The numbers in rows 2 and 4 are illustrations, not statistics: 40% stands for what one project's bug tracker might show.
💡 Простими словами: не обіцяй «нуль багів», тестуй рано, тестуй там, де болить, оновлюй тести і пам'ятай, для кого продукт.
💡 In plain words: never promise zero bugs, test early, test where it hurts, refresh your tests and remember who the product is for.
🗣 Як читати вголос Я назву всі сім у редакції CTFL 4.0 і до кожного дам приклад. Тестування показує наявність дефектів, а не їх відсутність, — тому я не обіцяю нуль багів. Вичерпне тестування неможливе, звідси техніки на кшталт класів і меж. Раннє тестування дешевше — я ловлю суперечності ще на рев'ю вимог. Дефекти скупчуються, і я додаю тестів у проблемні модулі. Тести зношуються, тож регрес треба оновлювати. Контекст вирішує глибину: банк і гра — різні світи. І останнє: навіть без відомих багів продукт може бути нікому не потрібним.
🗣 How to say it out loud I'll name all seven in the CTFL 4.0 wording with an example each. Testing shows that defects are present, not that they are absent, so I never promise zero bugs. Exhaustive testing is impossible, hence techniques like partitions and boundaries. Early testing is cheaper; I catch contradictions while reviewing requirements. Defects cluster, so I add tests to the troubled modules. Tests wear out, so the regression suite needs refreshing. Context sets the depth: a bank and a game are different worlds. And finally, a product with no known bugs can still be something nobody needs.
5 Що таке парадокс пестициду і як не дати регресійним тестам «зноситись»? What is the pesticide paradox, and how do you keep regression tests from wearing out?
ПринципиPrinciples Middle ▶

Що це. Термін Бориса Бейзера: як комахи звикають до одного пестициду, так і код «звикає» до одного набору тестів. Якщо запускати ті самі кейси з тими самими даними, вони знаходять дедалі менше нових дефектів — не тому, що їх немає, а тому, що тести перевіряють уже виправлені місця. У CTFL 4.0 принцип перейменовано на «тести зношуються».

What it is. Boris Beizer's term: just as insects get used to one pesticide, code "gets used to" one set of tests. Running the same cases with the same data finds fewer and fewer new defects — not because there are none, but because the tests keep checking places that were already fixed. CTFL 4.0 renamed the principle "tests wear out".

Навіщо. Зелений регрес створює ілюзію якості. Тим часом продукт змінюється: нові інтеграції, нові ролі, нові дані. Щоб набір лишався корисним, його переглядають разом зі змінами продукту й аналізом знайдених у проді дефектів.

Why it matters. A green regression run creates an illusion of quality. Meanwhile the product keeps changing: new integrations, new roles, new data. To stay useful the suite is reviewed alongside product changes and the analysis of defects found in production.

Приклад. Пів року регрес кошика стабільно зелений, а в проді клієнти скаржаться на промокоди з кирилицею та на кошики з 50+ товарами. Команда додає нові дані (кирилиця, емодзі, великі кошики), рандомізує порядок товарів, переписує два застарілі кейси й запускає сесію дослідницького тестування — і за тиждень знаходить три нові баги.

Example. For six months the cart regression run has been green, while customers in production complain about promo codes with Cyrillic letters and carts with 50+ items. The team adds new data (Cyrillic, emoji, large carts), shuffles item order, rewrites two outdated cases and runs an exploratory session — and finds three new bugs within a week.

Підводні камені. Регресійні тести, які нічого не знаходять, не марні: вони підтверджують, що старе не зламалося. Проблема не в них, а в тому, що команда вважає їх єдиним джерелом інформації. Інша пастка — безкінечно дописувати кейси, нічого не видаляючи: набір росте, а цінність — ні.

Pitfalls. Regression tests that find nothing are not useless: they confirm the old behaviour still works. The problem is treating them as the only source of information. Another trap is endlessly adding cases and never removing any: the suite grows while its value does not.

Регрес кошика: до і після оновлення
Cart regression: before and after the refresh
БУЛО (6 місяців без жодного нового бага)
TC-101 Додати 1 товар          дані: «Чашка», 1 шт
TC-102 Промокод SALE10          дані: латиниця
TC-103 Видалити товар           дані: той самий

СТАЛО
TC-101 Додати товари            дані: 1, 49, 50, 51 шт
TC-102 Промокоди                дані: SALE10, ЗНИЖКА, 🎁GIFT
TC-103 Видалити товар           дані: перший/останній/єдиний
TC-104 НОВИЙ Кошик після логіну  з інциденту INC-212
видалено TC-099 Старий дизайн кнопки (фічі вже немає)
+ щоспринтова 60-хв сесія дослідницького тестування
BEFORE (6 months, not a single new bug)
TC-101 Add 1 item               data: "Mug", qty 1
TC-102 Promo code SALE10        data: Latin letters
TC-103 Remove item              data: the same one

AFTER
TC-101 Add items                data: qty 1, 49, 50, 51
TC-102 Promo codes              data: SALE10, a Cyrillic code, 🎁GIFT
TC-103 Remove item              data: first/last/only one
TC-104 NEW Cart after login      from incident INC-212
removed TC-099 Old button design (feature is gone)
+ a 60-min exploratory session every sprint
🔧 Як читати: зміни чотирьох типів — варіювання даних (TC-101, TC-102), нові варіанти вже відомого кроку (TC-103), кейс з реального інциденту (TC-104) і видалення застарілого. Останній рядок нагадує, що нові дефекти частіше знаходить людина, а не той самий скрипт.
🔧 How to read it: there are four kinds of change — varied data (TC-101, TC-102), new variants of a known step (TC-103), a case taken from a real incident (TC-104) and removal of an obsolete one. The last line is a reminder that new defects are more often found by a person than by the same script.
💡 Простими словами: ті самі тести з тими самими даними перевіряють те, що вже працює; щоб знайти нове, треба дивитись інакше.
💡 In plain words: the same tests with the same data check what already works; to find something new you have to look differently.
🗣 Як читати вголос Парадокс пестициду — це коли однаковий набір тестів з часом перестає знаходити нові баги, бо він крутиться навколо вже виправлених місць. У новій програмі ISTQB це звучить просто: тести зношуються. Я борюся з цим кількома способами. Регулярно переглядаю регрес, коли змінюється продукт, і додаю кейси з продакшн-інцидентів. Варіюю дані — кирилиця, великі кошики, крайні значення. Видаляю те, що вже не має сенсу. І обов'язково лишаю час на дослідницьке тестування, бо саме воно найчастіше приносить свіжі знахідки.
🗣 How to say it out loud The pesticide paradox is when an unchanged test set gradually stops finding new bugs, because it keeps circling places that were already fixed. The current ISTQB syllabus puts it simply: tests wear out. I fight it in a few ways. I review the regression suite whenever the product changes and add cases from production incidents. I vary the data: Cyrillic input, huge carts, edge values. I delete things that no longer make sense. And I always keep time for exploratory testing, because that is where fresh findings usually come from.
6 Що означає скупчення дефектів і як використати його в плануванні тестів? What does defect clustering mean, and how do you use it when planning tests?
ПринципиPrinciples Middle ▶

Що це. Спостереження, що більшість дефектів зосереджена в невеликій кількості модулів. Його часто описують правилом Парето «80/20», але це евристика, а не закон: пропорція на кожному проєкті своя. Скупчення виникає там, де складна логіка, часті зміни, слабке покриття, нова технологія або код без власника.

What it is. The observation that most defects concentrate in a small number of modules. It is often described with the Pareto "80/20" rule, but that is a heuristic, not a law: every project has its own ratio. Clusters appear where logic is complex, changes are frequent, coverage is weak, technology is new or the code has no owner.

Навіщо. Принцип допомагає розподілити обмежений час: більше тестів, рев'ю й дослідницьких сесій туди, де історично болить, і в ризиковий аналіз — як фактор імовірності. Це також сигнал для команди: модуль, що постійно «кровоточить», може потребувати рефакторингу, а не ще одного тест-кейсу.

Why it matters. The principle helps spend limited time: more tests, reviews and exploratory sessions where it has historically hurt, and it feeds risk analysis as a likelihood factor. It is also a signal to the team: a module that keeps bleeding may need refactoring rather than one more test case.

Приклад. За квартал у трекері 120 дефектів. Групуємо за компонентом і бачимо, що оплата й тарифи дають 70 з них. На наступний реліз QA планує для цих двох модулів парне тестування з розробником і додаткову серію граничних тестів, а для профілю користувача лишає короткий чек-лист.

Example. The tracker holds 120 defects for the quarter. Grouping by component shows that payments and tariffs account for 70 of them. For the next release QA plans pair testing with a developer and an extra set of boundary tests for these two modules, while the user profile gets a short checklist.

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

Pitfalls. A cluster in the tracker can be an artefact: where you test more, you find more. And a module with zero bugs may simply be untested. So look at density (defects per volume of change) and at production defects, not just the raw count. Another trap is abandoning the "quiet" modules entirely, which runs straight into the tests-wear-out principle.

Дефекти за квартал і рішення
Defects per quarter and the decision
Модуль        Дефекти  З проду  Змін (PR)  Рішення
Оплата          42        6       31     парне тест., BVA сум
Тарифи          28        4       18     таблиця рішень
Кошик           21        1       25     регрес як є
Пошук           17        0       12     регрес як є
Профіль         12        0        4     короткий чек-лист
------------------------------------------------------
Разом          120       11
Оплата+Тарифи = 70/120 ≈ 58% (не 80%, і це нормально)
Module        Defects  From prod  Changes (PR)  Decision
Payments        42        6          31     pair testing, BVA
Tariffs         28        4          18     decision table
Cart            21        1          25     regression as is
Search          17        0          12     regression as is
Profile         12        0           4     short checklist
---------------------------------------------------------
Total          120       11
Payments+Tariffs = 70/120 ≈ 58% (not 80%, and that's fine)
🔧 Як читати: колонка «З проду» важливіша за загальний лічильник — вона показує, що пропускає поточне тестування. «Змін» дає контекст: у кошику багато правок і мало втеч, тож він під контролем. Останній рядок підкреслює, що реальний розподіл рідко дорівнює книжковим 80/20.
🔧 How to read it: the From prod column matters more than the total — it shows what current testing lets through. Changes gives context: the cart has many edits and few escapes, so it is under control. The last line stresses that real distributions rarely match the textbook 80/20.
💡 Простими словами: баги ходять зграями — дивись, де зграя жила минулого разу, але не забувай перевіряти решту лісу.
💡 In plain words: bugs travel in packs — look where the pack lived last time, but keep checking the rest of the forest too.
🗣 Як читати вголос Скупчення дефектів — це спостереження, що баги зазвичай живуть у кількох модулях, а не рівномірно по системі. Про вісімдесят на двадцять я згадую обережно, бо це евристика, на моєму проєкті було радше шістдесят на сорок. На практиці я відкриваю трекер, групую дефекти за компонентами й окремо дивлюсь, що втекло в прод. Там, де болить найбільше, я додаю глибші техніки й парну роботу з розробником. Але я пам'ятаю, що модуль без багів може бути просто неперевіреним, тому зовсім його не кидаю.
🗣 How to say it out loud Defect clustering is the observation that bugs tend to live in a few modules rather than spread evenly across the system. I mention eighty-twenty carefully, because it is a heuristic; on my project it was closer to sixty-forty. In practice I open the tracker, group defects by component and look separately at what escaped to production. Where it hurts the most I add deeper techniques and pair work with a developer. But I keep in mind that a module without bugs may simply be untested, so I never drop it completely.
7 Чим відрізняються QA, QC і тестування? How do QA, QC and testing differ?
ПринципиPrinciples Junior ▶

Що це. Quality Assurance (забезпечення якості) спрямоване на процес: воно запобігає появі дефектів через стандарти, рев'ю, навчання, Definition of Done, ретроспективи. Quality Control (контроль якості) спрямований на продукт: він виявляє дефекти в конкретному артефакті. Тестування — головна, але не єдина діяльність QC; до контролю належать також рев'ю коду чи інспекції документів.

What it is. Quality Assurance is process-oriented: it prevents defects through standards, reviews, training, a Definition of Done and retrospectives. Quality Control is product-oriented: it detects defects in a specific work product. Testing is the main but not the only QC activity; code reviews and document inspections belong to control as well.

Навіщо. Розуміння різниці пояснює, чому посада «QA engineer» ширша за «людину, що тестує». Сильний QA не лише знаходить баги в збірці, а й питає, чому однаковий тип бага повертається щоспринту, і змінює процес: додає чек у пул-реквест, уточнює шаблон user story.

Why it matters. Knowing the difference explains why a "QA engineer" title is broader than "the person who tests". A strong QA does not only find bugs in a build but asks why the same kind of bug comes back every sprint, and changes the process: adds a check to the pull request template, sharpens the user story template.

Приклад. Тричі за місяць у прод потрапляють непереведені тексти. QC-реакція — тестувальник знаходить і заводить кожен рядок. QA-реакція — команда додає до DoD пункт «усі ключі мають переклад» і лінтер, що ламає збірку на відсутньому ключі. Відтоді таких багів немає, і тестувати їх вручну вже не треба.

Example. Three times in a month untranslated strings reach production. The QC response: a tester finds and files each string. The QA response: the team adds "every key has a translation" to the DoD and a linter that fails the build on a missing key. From then on those bugs stop appearing and nobody has to test for them by hand.

Підводні камені. Помилково думати, що QA — окремий відділ, який «відповідає за якість». Якість — відповідальність усієї команди, а QA-інженер допомагає її будувати. І не варто протиставляти QA і QC: без контролю немає даних, щоб покращувати процес.

Pitfalls. It is a mistake to think of QA as a separate department that "owns quality". Quality is the whole team's responsibility, and a QA engineer helps build it. Nor should QA and QC be set against each other: without control there is no data to improve the process with.

Порівняння трьох понять
The three terms side by side
           | QA                | QC               | Тестування
-----------+-------------------+------------------+----------------
Фокус      | процес            | продукт          | поведінка ПЗ
Мета       | запобігти         | виявити          | знайти відмови
Коли       | весь цикл         | після артефакту  | коли є що перевір.
Хто        | уся команда       | QA, рев'юери     | тестувальники, деви
Приклад    | DoD, лінтер i18n  | рев'ю, тест-звіт | прогін тест-кейсів
           | QA                | QC               | Testing
-----------+-------------------+------------------+----------------
Focus      | process           | product          | software behaviour
Goal       | prevent           | detect           | find failures
When       | whole lifecycle   | after an artefact| when there's a build
Who        | the whole team    | QA, reviewers    | testers, devs
Example    | DoD, i18n linter  | review, report   | running test cases
🔧 Як читати: колонки вкладені одна в одну: тестування — частина QC, а QC — одне з джерел даних для QA. Рядок «Приклад» — той самий кейс з перекладами, розкладений на три рівні.
🔧 How to read it: the columns nest inside one another: testing is part of QC, and QC is one of the data sources for QA. The Example row is the same translation story split across the three levels.
💡 Простими словами: QA питає «як не допустити», QC — «чи є проблема тут», тестування — «що станеться, якщо зробити так».
💡 In plain words: QA asks "how do we stop it happening", QC asks "is there a problem here", testing asks "what happens if I do this".
🗣 Як читати вголос Я бачу це як три вкладені кола. Тестування — це конкретна перевірка поведінки програми. Воно входить у контроль якості, куди ще належать рев'ю та інспекції, і весь контроль дивиться на продукт, щоб виявити дефекти. А забезпечення якості дивиться на процес і намагається зробити так, щоб дефектів менше з'являлось. Приклад з мого досвіду: коли непереклади раз у раз летіли в прод, ми перестали просто їх ловити і додали перевірку в збірку. От це вже QA, а не QC.
🗣 How to say it out loud I picture three nested circles. Testing is the concrete check of how the software behaves. It sits inside quality control, together with reviews and inspections, and control as a whole looks at the product to detect defects. Quality assurance looks at the process and tries to make fewer defects appear in the first place. An example from my work: when missing translations kept reaching production, we stopped merely catching them and added a check to the build. That was QA rather than QC.
8 Як співвідносяться SDLC і STLC і де в них місце QA? How do the SDLC and the STLC relate, and where does QA fit in them?
ПринципиPrinciples Junior ▶

Що це. SDLC (Software Development Life Cycle) — життєвий цикл розробки: вимоги, дизайн, реалізація, тестування, розгортання, супровід. STLC (Software Testing Life Cycle) — цикл саме тестування. У CTFL 4.0 це тестовий процес: планування; моніторинг і контроль; аналіз; проєктування; реалізація; виконання; завершення тестування.

What it is. The SDLC (Software Development Life Cycle) is the development lifecycle: requirements, design, implementation, testing, deployment, maintenance. The STLC (Software Testing Life Cycle) is the lifecycle of testing itself. CTFL 4.0 calls it the test process: planning; monitoring and control; analysis; design; implementation; execution; completion.

Навіщо. STLC не чекає на етап «тестування» в SDLC — він іде паралельно. Поки аналітик пише вимоги, QA вже робить тест-аналіз (що перевіряти); поки розробник пише код, QA проєктує кейси й готує дані. Це і є shift-left: робота з якістю починається там, де з'являється перший артефакт.

Why it matters. The STLC does not wait for the SDLC's "testing" stage — it runs alongside. While the analyst writes requirements, QA already does test analysis (what to test); while the developer writes code, QA designs cases and prepares data. That is shift-left: quality work starts where the first artefact appears.

Приклад. Спринт з фічею «оплата частинами»: на рефайнменті QA ставить питання про ліміти (аналіз), у перші дні пише таблицю рішень і чек-лист (проєктування), готує тестові картки банку (реалізація), тестує збірку на стейджі (виконання), а в кінці фіксує звіт і відкриті ризики (завершення).

Example. A sprint with a "pay in instalments" feature: at refinement QA asks about limits (analysis), in the first days writes a decision table and a checklist (design), prepares bank test cards (implementation), tests the build on staging (execution) and at the end records a summary and open risks (completion).

Підводні камені. Фази STLC — логічні, а не обов'язково послідовні чи окремі в часі: в Agile вони повторюються в кожному спринті й часто накладаються. Помилка — описувати STLC як водоспад із документом-підписом після кожної фази, коли команда працює двотижневими ітераціями.

Pitfalls. STLC phases are logical, not necessarily sequential or separated in time: in Agile they repeat every sprint and often overlap. It is a mistake to describe the STLC as a waterfall with a signed document after every phase when the team works in two-week iterations.

SDLC і паралельні активності QA
The SDLC and parallel QA activities
SDLC            STLC / що робить QA
Вимоги     ──►  Аналіз: рев'ю вимог, питання, ризики
   │
Дизайн     ──►  Планування + проєктування: кейси, таблиці
   │
Код        ──►  Реалізація: дані, середовище, чек-листи
   │
Тестування ──►  Виконання: прогін, баги, ретест, регрес
   │
Реліз      ──►  Завершення: звіт, залишкові ризики
   │
Супровід   ──►  Аналіз інцидентів, оновлення регресу
Моніторинг і контроль — наскрізно, на всіх етапах
SDLC            STLC / what QA does
Requirements ─► Analysis: spec review, questions, risks
   │
Design     ──►  Planning + design: cases, tables
   │
Code       ──►  Implementation: data, env, checklists
   │
Testing    ──►  Execution: runs, bugs, retest, regression
   │
Release    ──►  Completion: summary report, residual risks
   │
Maintenance ─►  Incident analysis, regression updates
Monitoring and control run across every stage
🔧 Як читати: ліва колонка — етапи розробки, стрілка показує, яка частина тестового процесу йде одночасно з ними. Навіть на етапі «Тестування» QA вже не проєктує, а лише виконує — проєктування відбулося раніше. Останній рядок нагадує про наскрізний контроль прогресу.
🔧 How to read it: the left column lists development stages; the arrow shows which part of the test process runs at the same time. By the Testing stage QA is no longer designing, only executing — the design happened earlier. The last line is a reminder that progress control runs throughout.
💡 Простими словами: SDLC — як будують продукт, STLC — як його перевіряють, і вони йдуть пліч-о-пліч, а не одне після одного.
💡 In plain words: the SDLC is how the product gets built, the STLC is how it gets checked, and they walk side by side rather than one after the other.
🗣 Як читати вголос SDLC — це весь шлях продукту від вимог до супроводу, а STLC — шлях тестування всередині нього: планування, аналіз, проєктування, реалізація, виконання і завершення, плюс моніторинг поверх усього. Я наголошую, що вони йдуть паралельно. Коли аналітик ще пише вимоги, я вже їх читаю і ставлю питання, а поки пишеться код, я готую кейси та дані. Тож коли приходить збірка, я просто виконую те, що вже спроєктував. В Agile цей цикл у мене прокручується щоспринту, а не один раз на проєкт.
🗣 How to say it out loud The SDLC is the product's whole journey from requirements to maintenance, and the STLC is the testing journey inside it: planning, analysis, design, implementation, execution and completion, with monitoring on top. I stress that the two run in parallel. While the analyst is still writing requirements, I am already reading them and asking questions; while code is being written, I prepare cases and data. So when a build arrives I simply execute what I designed earlier. In Agile I go through that cycle every sprint, not once per project.
9 Що таке статичне тестування і які бувають види рев'ю? What is static testing, and what kinds of review are there?
ПринципиPrinciples Middle ▶

Що це. Статичне тестування перевіряє артефакти без запуску програми: вимоги, user stories, макети, код, тест-кейси. Інструменти — рев'ю людьми і статичний аналіз (лінтери, аналізатори коду). Динамічне тестування, навпаки, виконує ПЗ і дивиться на відмови. Статичне знаходить сам дефект, динамічне — його прояв.

What it is. Static testing examines work products without running the software: requirements, user stories, mock-ups, code, test cases. The tools are human reviews and static analysis (linters, code analysers). Dynamic testing, by contrast, executes the software and observes failures. Static testing finds the defect itself; dynamic testing finds its symptom.

Навіщо. Частину дефектів динамічно знайти важко або неможливо: суперечливі вимоги, недосяжний код, відсутній сценарій. Рев'ю вимог до початку розробки — найдешевший спосіб прибрати таку ваду. CTFL 4.0 виділяє чотири типи рев'ю за формальністю: неформальне, walkthrough (прохід з автором-ведучим), технічне рев'ю (рішення приймають експерти) та інспекція (найформальніша, з ролями, чек-листами й метриками).

Why it matters. Some defects are hard or impossible to find dynamically: contradictory requirements, unreachable code, a missing scenario. Reviewing requirements before development starts is the cheapest way to remove such a flaw. CTFL 4.0 names four review types by formality: informal review, walkthrough (led by the author), technical review (experts reach a decision) and inspection (the most formal, with roles, checklists and metrics).

Приклад. Історія «Доставка безкоштовна для замовлень понад 1000 грн. Доставка коштує 50 грн». Під час рев'ю QA помічає: невідомо, що буде рівно з 1000 грн, як рахується сума після знижки, і чи стосується правило самовивозу. Три дефекти знайдені без рядка коду.

Example. The story reads "Delivery is free for orders over 1000 UAH. Delivery costs 50 UAH". During the review QA notices: it is unclear what happens at exactly 1000 UAH, whether the total is counted after discounts, and whether the rule covers pickup. Three defects found without a single line of code.

Підводні камені. Рев'ю не повинно перетворюватися на оцінку автора — критикують артефакт, а не людину. Без підготовки учасників рев'ю стає формальністю. І лінтер не замінює людське читання вимог: він ловить синтаксис, а не хибну бізнес-логіку.

Pitfalls. A review must not turn into judging the author — the work product is criticised, not the person. Without participants preparing beforehand a review becomes a formality. And a linter does not replace a human reading the requirements: it catches syntax, not wrong business logic.

Фрагмент вимоги і знахідки рев'ю
A requirement fragment and review findings
US-58 Як покупець, я хочу безкоштовну доставку,
щоб економити на великих замовленнях.
AC: доставка безкоштовна для замовлень понад 1000 грн.
    Інакше доставка коштує 50 грн.

Знахідки рев'ю (неформальне, QA + BA, 20 хв):
R1 [неоднозначність] «понад 1000» — 1000,00 включно?
R2 [пропуск] сума до чи після промокоду?
R3 [пропуск] самовивіз: 0 грн чи правило не діє?
R4 [суперечність] макет показує поріг 999 грн
Результат: BA оновив AC, R1–R4 закрито до спринту
US-58 As a shopper I want free delivery
so that I save on large orders.
AC: delivery is free for orders over 1000 UAH.
    Otherwise delivery costs 50 UAH.

Review findings (informal, QA + BA, 20 min):
R1 [ambiguity] "over 1000" — is 1000.00 included?
R2 [missing] total before or after the promo code?
R3 [missing] pickup: 0 UAH, or rule not applied?
R4 [contradiction] the mock-up shows a 999 UAH threshold
Outcome: BA updated the AC, R1–R4 closed before sprint
🔧 Як читати: угорі — артефакт, що рецензується, внизу — знахідки з типом у квадратних дужках. Типи (неоднозначність, пропуск, суперечність) допомагають автору швидко зрозуміти, що саме виправляти. Останній рядок — результат, заради якого рев'ю проводилось.
🔧 How to read it: the reviewed work product is at the top, the findings below with their type in square brackets. The types (ambiguity, missing, contradiction) help the author see quickly what to fix. The last line is the outcome the review was held for.
💡 Простими словами: статичне тестування — це читання з олівцем у руках до того, як щось запустили.
💡 In plain words: static testing is reading with a pencil in hand before anything has been run.
🗣 Як читати вголос Статичне тестування для мене — це перевірка без запуску: я читаю вимоги, макети, іноді код, а розробники ще й ганяють лінтери. Воно шукає сам дефект, тоді як динамічне бачить лише наслідок. Рев'ю бувають від неформального до інспекції, а посередині walkthrough і технічне рев'ю, і чим формальніше, тим більше ролей і правил. Найкорисніше, що я роблю, — читаю історії до спринту. Якось на двадцятихвилинному рев'ю ми знайшли чотири проблеми з порогом безкоштовної доставки, і жодну з них не довелося потім ловити на стейджі.
🗣 How to say it out loud To me static testing means checking without running anything: I read requirements, mock-ups, sometimes code, and developers add linters on top. It finds the defect itself, whereas dynamic testing only sees the consequence. Reviews range from informal to inspection, with walkthroughs and technical reviews in between, and the more formal they get, the more roles and rules there are. The most useful habit I have is reading stories before the sprint. Once, in a twenty-minute review, we found four problems with the free-delivery threshold, and none of them had to be caught on staging later.
10 Що таке мислення тестувальника і чим воно відрізняється від мислення розробника? What is the tester mindset, and how does it differ from a developer's?
ПринципиPrinciples Middle ▶

Що це. Розробник думає, як змусити систему працювати; тестувальник — як і за яких умов вона може не спрацювати. CTFL 4.0 описує мислення тестувальника як допитливість, професійний песимізм, критичний погляд, увагу до деталей і прагнення до добрих, позитивних стосунків з колегами. Це конструктивний скептицизм, а не протистояння з командою.

What it is. A developer thinks about how to make the system work; a tester thinks about how and under what conditions it might not. CTFL 4.0 describes the tester's mindset as curiosity, professional pessimism, a critical eye, attention to detail and a drive for good, positive communication with colleagues. It is constructive scepticism, not a fight with the team.

Навіщо. Автору важко побачити власні сліпі зони: він знає, як задумано, і мимоволі тестує задумане. Незалежний погляд помічає неявні припущення: що станеться при повторному кліку, без мережі, з іншою роллю, з даними, про які ніхто не подумав.

Why it matters. Authors struggle to see their own blind spots: they know how things were intended and unconsciously test the intention. An independent view spots hidden assumptions: what happens on a double click, offline, under another role, with data nobody thought about.

Приклад. Розробник показує чекбокс «Запам'ятати мене» і перевіряє, що після перезапуску браузера сесія жива. Тестувальник одразу питає: скільки днів вона живе, що буде після зміни пароля на іншому пристрої, чи працює це в режимі інкогніто, чи знімає «Вийти» запам'ятовування на всіх пристроях.

Example. A developer demos a "Remember me" checkbox and checks that the session survives a browser restart. The tester immediately asks: how many days does it last, what happens after a password change on another device, does it work in incognito mode, does "Log out" forget the session on every device.

Підводні камені. Песимізм без емпатії робить тестувальника «тим, хто все блокує». Формулюйте знахідки як факти й ризики для користувача, а не як «ти знову зламав». Інша крайність — надмірна довіра до розробника («він сказав, що працює»), яка вбиває незалежність. Мислення тестувальника корисне й розробникам, тому його варто поширювати, а не охороняти.

Pitfalls. Pessimism without empathy turns a tester into "the one who blocks everything". Phrase findings as facts and risks for the user, not as "you broke it again". The opposite extreme is over-trusting the developer ("he said it works"), which kills independence. The tester mindset helps developers too, so spread it rather than guard it.

Питання тестувальника до «Запам'ятати мене»
A tester's questions about «Remember me»
Перевірив розробник:
[✓] Сесія жива після перезапуску браузера

Питання тестувальника:
[?] Скільки живе токен? 30 днів — звідки число?
[?] Змінив пароль на телефоні — ноутбук досі залогінений?
[?] Інкогніто / заборонені cookies — що бачить користувач?
[?] «Вийти» — лише тут чи на всіх пристроях?
[?] Два акаунти в одному браузері по черзі?
[?] Спільний комп'ютер у бібліотеці — чи є попередження?
Checked by the developer:
[✓] Session survives a browser restart

Tester's questions:
[?] How long does the token live? Why 30 days?
[?] Changed password on phone — laptop still logged in?
[?] Incognito / cookies blocked — what does the user see?
[?] "Log out" — here only or on every device?
[?] Two accounts in one browser, one after another?
[?] Shared library computer — is there a warning?
🔧 Як читати: перший блок — підтвердження задуманого сценарію, другий — питання, що розширюють його в бік часу, інших пристроїв, обмежень середовища, кількох користувачів і безпеки. Кожне «?» — кандидат у тест-кейс або в уточнення вимоги.
🔧 How to read it: the first block confirms the intended scenario; the second holds questions that stretch it towards time, other devices, environment limits, multiple users and security. Every "?" is a candidate test case or a requirement clarification.
💡 Простими словами: розробник доводить, що працює; тестувальник шукає, коли не працюватиме, — і обидва на одному боці.
💡 In plain words: the developer shows that it works; the tester looks for when it won't — and both are on the same side.
🗣 Як читати вголос Мислення тестувальника я описую як доброзичливий скептицизм. Розробник думає, як зробити, щоб працювало, а я думаю, коли воно може не спрацювати. Взяти чекбокс «Запам'ятати мене»: розробник перевірив перезапуск браузера, а я одразу питаю про зміну пароля на іншому пристрої, про інкогніто, про вихід з усіх сесій. Але я дуже стежу за тоном: я приношу факти й ризики для користувача, а не звинувачення. Моя мета не довести, що хтось помилився, а щоб продукт вийшов кращим.
🗣 How to say it out loud I describe the tester mindset as friendly scepticism. A developer thinks about making it work, and I think about when it might not. Take a Remember me checkbox: the developer checked a browser restart, and I immediately ask about a password change on another device, about incognito, about logging out of every session. But I watch my tone closely: I bring facts and user risks, not accusations. My goal is not to prove someone was wrong, it is for the product to ship in better shape.
11 Що таке тестовий оракул і що робити, коли очікуваний результат невідомий? What is a test oracle, and what do you do when the expected result is unknown?
ПринципиPrinciples Senior ▶

Що це. Оракул — джерело, за яким ми визначаємо очікуваний результат і вирішуємо, пройшов тест чи ні. Це може бути специфікація, попередня версія системи, конкурентний продукт, незалежний розрахунок, правила узгодженості (сума рядків дорівнює підсумку), думка експерта. Проблема оракула — ситуація, коли надійного джерела немає або воно дороге.

What it is. An oracle is the source we use to determine the expected result and decide whether a test passed. It can be a specification, a previous version of the system, a competing product, an independent calculation, consistency rules (line items add up to the total) or an expert's judgement. The oracle problem is the situation where no reliable source exists or it is expensive.

Навіщо. Без оракула тест не має вердикту — є лише спостереження. Особливо гостро це відчувається з розрахунками, ML-моделями, великими звітами та легасі без документації. Senior-тестувальник свідомо обирає кілька оракулів і розуміє сильні й слабкі сторони кожного: попередня версія, наприклад, повторить і свої старі баги.

Why it matters. Without an oracle a test has no verdict, only an observation. It bites hardest with calculations, ML models, large reports and undocumented legacy. A senior tester deliberately picks several oracles and knows each one's strengths and weaknesses: a previous version, for example, will repeat its own old bugs.

Приклад. Фіча конвертації валют у гаманці. Специфікація каже лише «за курсом НБУ». QA бере курс з офіційного API як незалежний оракул, перевіряє зворотну конвертацію (UAH→USD→UAH ≈ вихідна сума з точністю до правила округлення), порівнює з банківським застосунком і уточнює в бухгалтера, як округлювати копійки.

Example. A currency conversion feature in a wallet. The specification only says "at the NBU rate". QA takes the rate from the official API as an independent oracle, checks the round trip (UAH→USD→UAH ≈ the original amount within the rounding rule), compares with a banking app and asks accounting how kopecks should be rounded.

Підводні камені. Найчастіша помилка — використовувати як оракул саму систему: «записав, що показало, і зробив очікуваним». Так тест фіксує баг як норму. Інша пастка — евристичні оракули (узгодженість, правдоподібність) дають лише ймовірний вердикт, тому їх результат варто підтверджувати з людиною, що знає домен.

Pitfalls. The most common mistake is using the system itself as the oracle: "wrote down what it showed and made it the expected result". That way the test enshrines a bug as normal. Another trap is that heuristic oracles (consistency, plausibility) only give a probable verdict, so their result is worth confirming with someone who knows the domain.

Оракули для конвертації валют
Oracles for currency conversion
Оракул              | Що перевіряє            | Слабке місце
-------------------+-------------------------+----------------
Специфікація       | «курс НБУ»              | мовчить про округл.
API НБУ (незалежн.)| 1000 UAH → x USD        | курс на яку дату?
Зворотна операція  | UAH→USD→UAH ≈ 1000      | втрати на округленні
Попередня версія   | те саме, що в v2.3      | повторює старі баги
Інший застосунок   | сума в банк. додатку    | інша комісія
Експерт-бухгалтер  | правило копійок         | дорого, повільно
Антиоракул: «що показала система — те й очікуване»
Oracle             | What it checks          | Weak spot
-------------------+-------------------------+----------------
Specification      | "NBU rate"              | silent on rounding
NBU API (independ.)| 1000 UAH → x USD        | rate for which date?
Inverse operation  | UAH→USD→UAH ≈ 1000      | rounding losses
Previous version   | same as in v2.3         | repeats old bugs
Another app        | amount in a bank app    | different fees
Accounting expert  | kopeck rounding rule    | costly, slow
Anti-oracle: "whatever the system shows is expected"
🔧 Як читати: кожен рядок — окреме джерело правди з його обмеженням. Жоден оракул не закриває все, тому їх комбінують: незалежний розрахунок дає число, зворотна операція — узгодженість, експерт — правило. Останній рядок — те, чого робити не можна.
🔧 How to read it: each row is a separate source of truth with its own limitation. No single oracle covers everything, so they are combined: an independent calculation gives the number, the inverse operation gives consistency, the expert gives the rule. The last line is what you must never do.
💡 Простими словами: оракул — це відповідь на питання «а звідки ти знаєш, що має бути саме так?».
💡 In plain words: an oracle is the answer to "and how do you know it should be exactly that?".
🗣 Як читати вголос Оракул — це те, звідки я беру очікуваний результат. Найпростіше — специфікація, але часто її недостатньо, і тоді я комбіную джерела. На проєкті з конвертацією валют у нас було тільки «за курсом НБУ», тож я брав курс з їхнього API, перевіряв зворотну операцію, звірявся з банківським додатком, а правило округлення уточнив у бухгалтерії. Головне, чого я уникаю, — робити очікуваним те, що показала сама система, бо тоді тест назавжди закріплює баг. І я пам'ятаю, що евристичний оракул дає лише підозру, а не остаточний вердикт.
🗣 How to say it out loud An oracle is where I get my expected result from. The simplest is the specification, but often it is not enough, and then I combine sources. On a currency conversion project all we had was "at the NBU rate", so I took the rate from their API, checked the reverse conversion, compared with a banking app and got the rounding rule from accounting. The one thing I avoid is treating whatever the system shows as expected, because then the test locks the bug in forever. And I remember that a heuristic oracle gives me a suspicion, not a final verdict.
▶ 2 17
12 Які рівні тестування виділяє ISTQB і чим вони відрізняються одне від одного? Which test levels does ISTQB define, and how do they differ from one another?
Рівні й типиLevels & types Junior ▶

Що це. Рівень тестування — це група активностей, організованих навколо одного об'єкта тестування на певному етапі розробки. CTFL 4.0 називає п'ять рівнів: компонентне тестування (component, воно ж unit), тестування інтеграції компонентів, системне тестування, тестування інтеграції систем і приймальне тестування. Класична схема «Unit → Integration → System → Acceptance» — спрощення, де обидва інтеграційні рівні злито в один.

What it is. A test level is a group of activities organised around one test object at a particular stage of development. CTFL 4.0 lists five levels: component testing (also called unit testing), component integration testing, system testing, system integration testing and acceptance testing. The classic "Unit → Integration → System → Acceptance" chain is a simplification that folds both integration levels into one.

Навіщо. Кожен рівень має власну тестову базу, свої типові дефекти, власне середовище й відповідальних. Помилку в округленні ціни дешево зловити на компонентному рівні, а неправильно замаплене поле між магазином і службою доставки видно лише на рівні інтеграції систем. Якщо команда пропускає рівень, його дефекти не зникають, а просто спливають пізніше й дорожче.

Why it matters. Each level has its own test basis, its own typical defects, its own environment and its own owners. A price-rounding mistake is cheap to catch at component level, while a wrongly mapped field between the shop and the delivery service only shows up during system integration testing. When a team skips a level, its defects do not vanish; they surface later, where they cost more.

Приклад. Інтернет-магазин: функцію calculateTotal розробник перевіряє юніт-тестами; зв'язку «кошик → сервіс знижок» перевіряють інтеграційні тести; весь флоу замовлення тестувальник проходить на стейджингу; обмін з Новою поштою та платіжним шлюзом — окремий рівень; нарешті, менеджер продажів приймає фічу на UAT.

Example. An online shop: the developer covers the calculateTotal function with unit tests; the cart-to-discount-service link is covered by integration tests; the tester walks the whole order flow on staging; the exchange with the courier service and the payment gateway is a level of its own; finally a sales manager accepts the feature in UAT.

Підводні камені. Рівні не дорівнюють типам: регресію чи продуктивність можна робити на будь-якому рівні. Також рівні не обов'язково йдуть строго послідовно — в Agile вони перетинаються в межах одного спринту.

Pitfalls. Levels are not types: regression or performance testing can happen at any level. Nor do levels have to run strictly one after another — in Agile they overlap within a single sprint.

Рівні тестування для інтернет-магазину
Test levels for an online shop
Рівень             | Об'єкт              | Хто    | Типовий дефект
-------------------+---------------------+--------+------------------
Компонентний       | calculateTotal()    | dev    | 0.1+0.2 у ціні
Інтеграція компон. | кошик ↔ знижки      | dev/QA | не той формат
Системний          | весь застосунок     | QA     | флоу не завершено
Інтеграція систем  | магазин ↔ доставка  | QA     | місто не мапиться
Приймальний        | бізнес-процес       | бізнес | не той сценарій
Level              | Test object         | Who    | Typical defect
-------------------+---------------------+--------+------------------
Component          | calculateTotal()    | dev    | 0.1+0.2 in price
Component integr.  | cart ↔ discounts    | dev/QA | wrong format
System             | whole application   | QA     | flow never ends
System integration | shop ↔ delivery     | QA     | city not mapped
Acceptance         | business process    | users  | wrong scenario
🔧 Як читати: кожен рядок — окремий рівень. Колонка «Об'єкт» показує, що саме тестується, «Хто» — типовий виконавець, а остання колонка — дефект, який найлегше знайти саме на цьому рівні. Зверніть увагу: об'єкт розширюється згори донизу від однієї функції до бізнес-процесу.
🔧 How to read it: each row is one level. The "Test object" column shows what is under test, "Who" is the usual performer, and the last column is the defect this level finds most easily. Notice how the object grows from top to bottom, from a single function to a business process.
💡 Простими словами: від цеглини до будинку і до мешканця, який у ньому живе: кожен рівень перевіряє більший шматок.
💡 In plain words: from a brick to the house to the person who lives in it — each level checks a bigger piece.
🗣 Як читати вголос Я відповідаю за силабусом CTFL 4.0: рівнів п'ять — компонентний, інтеграція компонентів, системний, інтеграція систем і приймальний. Для мене рівень — це насамперед об'єкт тестування і тестова база: на юніті це одна функція і код, на системному — весь застосунок і вимоги, на приймальному — бізнес-процес. Я завжди додаю, що рівень і тип — різні осі, бо регресію чи навантаження можна запускати на будь-якому рівні. І ще кажу, що пропущений рівень просто переносить свої баги далі по конвеєру.
🗣 How to say it out loud I answer from the CTFL 4.0 syllabus: there are five levels — component, component integration, system, system integration and acceptance. To me a level is first of all a test object plus a test basis: a single function and its code for unit, the whole application and its requirements for system, a business process for acceptance. I always add that level and type are separate axes, because regression or load runs can happen at any level. And I mention that a skipped level simply pushes its bugs further down the line.
13 Що перевіряє компонентне (unit) тестування і що з нього корисно знати мануальному QA? What does component (unit) testing check, and what should a manual QA take from it?
Рівні й типиLevels & types Junior ▶

Що це. Компонентне тестування перевіряє найменшу окрему частину коду — функцію, метод, клас — в ізоляції від решти системи. Залежності на кшталт бази даних, мережі чи годинника підміняють заглушками (stub) або моками (mock), щоб тест залежав лише від логіки самого компонента. Пишуть такі тести переважно розробники, часто в тому ж репозиторії і за підходом TDD.

What it is. Component testing checks the smallest separate piece of code — a function, a method, a class — in isolation from the rest of the system. Dependencies such as the database, the network or the clock are replaced by stubs or mocks so the test depends only on the component's own logic. Developers usually write these tests, often in the same repository and often test-first.

Навіщо. Юніт-тести виконуються за мілісекунди, тому ловлять помилки в розрахунках і умовах ще до того, як збірка потрапить до тестувальника. Вони ж точно вказують місце поломки: впав тест applyDiscount — значить, проблема саме в цій функції, а не «десь у кошику».

Why it matters. Unit tests run in milliseconds, so they catch mistakes in calculations and conditions before a build ever reaches a tester. They also pinpoint the failure: if the applyDiscount test is red, the problem is in that function, not "somewhere in the cart".

Приклад. Мануальний QA може прочитати назви юніт-тестів і побачити, які межі розробник уже покрив. Якщо для знижки перевірено 999 і 1000 грн, але не перевірено від'ємну суму чи порожній кошик — це готові ідеї для обговорення або для власних перевірок на системному рівні.

Example. A manual QA can read the unit test names and see which boundaries the developer already covered. If the discount is checked for 999 and 1000 UAH but not for a negative amount or an empty cart, those are ready-made ideas to raise with the developer or to test at system level.

Підводні камені. Зелені юніт-тести не гарантують, що компоненти правильно працюють разом: моки можуть повертати дані у форматі, якого справжній сервіс ніколи не надішле. Також висока кількість тестів ще нічого не каже про їхню якість — тест без жодної перевірки (assert) теж «проходить».

Pitfalls. Green unit tests do not prove that components work together: a mock may return data in a shape the real service never sends. A large number of tests says nothing about their quality either — a test with no assertion at all also "passes".

Юніт-тест функції знижки (JavaScript)
Unit test for a discount function (JavaScript)
// Знижка 10% від 1000 грн включно
function applyDiscount(total) {
  return total >= 1000 ? total * 0.9 : total;
}

test('999 грн — без знижки', () => {
  expect(applyDiscount(999)).toBe(999);
});
test('1000 грн — знижка 10%', () => {
  expect(applyDiscount(1000)).toBe(900);
});
// Не покрито: від'ємна сума, 0, нечислове значення
// 10% off from 1000 UAH inclusive
function applyDiscount(total) {
  return total >= 1000 ? total * 0.9 : total;
}

test('999 UAH: no discount', () => {
  expect(applyDiscount(999)).toBe(999);
});
test('1000 UAH: 10% discount', () => {
  expect(applyDiscount(1000)).toBe(900);
});
// Not covered: negative total, 0, non-numeric input
🔧 Як читати: test('назва', () => {...}) оголошує один тест у стилі Jest; expect(x).toBe(y) — перевірка, що результат дорівнює очікуваному. Функція не звертається ні до бази, ні до мережі, тому ізоляція тут природна. Останній коментар — те, що тестувальник виписав би як прогалину в покритті.
🔧 How to read it: test('name', () => {...}) declares one Jest-style test; expect(x).toBe(y) asserts the result equals the expected value. The function touches neither a database nor the network, so isolation comes for free. The last comment is what a tester would note down as a coverage gap.
💡 Простими словами: юніт-тест перевіряє одну деталь на верстаті, ще до того, як її вкрутили в машину.
💡 In plain words: a unit test checks one part on the workbench, before it is bolted into the car.
🗣 Як читати вголос Юніт-тестування — це перевірка однієї функції чи класу окремо від усього іншого, а зовнішні залежності підміняють моками. Зазвичай його пишуть розробники, і воно дає найшвидший зворотний зв'язок. Хоч я й мануальний тестувальник, я люблю зазирати в назви юніт-тестів: так я бачу, які межі вже перевірені, і не дублюю їх, а шукаю те, що пропущено — нулі, від'ємні значення, порожні дані. І я чесно кажу, що зелені юніти ще не означають, що модулі дружать між собою.
🗣 How to say it out loud Unit testing means checking one function or class apart from everything else, with outside dependencies swapped for mocks. Developers normally write it, and it gives the fastest feedback of any level. Even as a manual tester I like to skim the unit test names: that shows me which boundaries are already covered, so I skip them and hunt for what is missing — zeros, negatives, empty input. And I am honest that green unit tests do not yet mean the modules get along with each other.
14 Що саме шукає інтеграційне тестування і чим інтеграція компонентів відрізняється від інтеграції систем? What exactly does integration testing look for, and how does component integration differ from system integration?
Рівні й типиLevels & types Junior ▶

Що це. Інтеграційне тестування перевіряє взаємодію та інтерфейси між частинами, а не логіку всередині кожної. Тестування інтеграції компонентів зосереджене на зв'язках модулів однієї системи (сервіс замовлень викликає сервіс складу). Тестування інтеграції систем перевіряє обмін із зовнішніми системами: платіжним провайдером, службою доставки, CRM.

What it is. Integration testing checks the interactions and interfaces between parts rather than the logic inside each one. Component integration testing focuses on links between modules of one system (the order service calling the stock service). System integration testing checks the exchange with external systems: a payment provider, a delivery service, a CRM.

Навіщо. Найчастіші дефекти на стиках — розбіжність форматів (сума в копійках проти гривень), неправильні коди помилок, таймаути, різне розуміння обов'язковості полів, некоректна обробка повторної відповіді. Кожен компонент окремо може бути ідеальним, а разом вони дають неправильне замовлення.

Why it matters. The most common defects at the seams are mismatched formats (an amount in kopecks versus hryvnias), wrong error codes, timeouts, differing views on which fields are mandatory and mishandled duplicate responses. Each component can be flawless on its own and still produce a wrong order together.

Приклад. Сервіс замовлень передає платіжному провайдеру amount: 1250, маючи на увазі гривні, а провайдер читає копійки і списує 12,50 грн. Юніт-тести обох сторін зелені. Знайти це може лише тест, що проходить реальний (або контрактно точний) виклик і звіряє суму на обох кінцях.

Example. The order service sends the payment provider amount: 1250, meaning hryvnias, but the provider reads it as kopecks and charges 12.50 UAH. Both sides have green unit tests. Only a test that makes a real (or contract-accurate) call and compares the amount on both ends can find this.

Підводні камені. Підхід «big bang», коли все з'єднують одночасно, робить локалізацію дефекту болісною. Інкрементальна інтеграція (зверху вниз, знизу вгору) повільніша на старті, зате кожен збій вказує на конкретний стик. Ще одна пастка — зовнішня пісочниця провайдера поводиться не так, як продакшн, тож результати варто перевіряти хоча б на одному бойовому сценарії з мінімальною сумою.

Pitfalls. The big-bang approach, where everything is wired together at once, makes defect localisation painful. Incremental integration (top-down or bottom-up) is slower to start but every failure points at a specific seam. Another trap: a provider's sandbox does not behave exactly like production, so it is worth confirming at least one live scenario with a minimal amount.

Перевірки контракту «замовлення ↔ платіжний провайдер»
Contract checks: order service ↔ payment provider
# Що відправляємо
POST /payments
{ "orderId": "A-1042", "amount": 125000, "currency": "UAH" }

# Що перевіряємо на стику
1. amount у копійках: 125000 = 1250,00 грн в кабінеті провайдера
2. currency обов'язкове: без нього — 400, а не тихий дефолт
3. таймаут 30 с: замовлення лишається pending, не failed
4. повторний callback: статус не змінюється вдруге
5. код 402 провайдера → зрозуміле повідомлення покупцю
# What we send
POST /payments
{ "orderId": "A-1042", "amount": 125000, "currency": "UAH" }

# What we check at the seam
1. amount in kopecks: 125000 = 1250.00 UAH in provider panel
2. currency is mandatory: missing gives 400, no silent default
3. 30 s timeout: order stays pending, not failed
4. duplicate callback: status does not change twice
5. provider code 402 → clear message for the buyer
🔧 Як читати: верхній блок — тіло запиту, яке сервіс замовлень шле провайдеру. Нижній список — не перевірки логіки кожної сторони, а саме домовленості між ними: одиниці виміру, обов'язкові поля, поведінка при таймауті, повторах і помилках.
🔧 How to read it: the top block is the request body the order service sends to the provider. The list below does not check either side's internal logic; it checks the agreements between them: units, mandatory fields, and behaviour on timeouts, repeats and errors.
💡 Простими словами: інтеграційний тест перевіряє не деталі, а різьбу, якою вони скручуються.
💡 In plain words: an integration test checks not the parts but the thread that screws them together.
🗣 Як читати вголос Для мене інтеграційне тестування — це тестування стиків. Я розрізняю два рівні: коли спілкуються модулі нашої ж системи, і коли ми говоримо із зовнішнім світом, наприклад з платіжкою. Улюблений приклад — сума, яку одна сторона шле в гривнях, а інша читає в копійках: обидва юніт-набори зелені, а гроші списуються неправильні. Тому на стиках я перевіряю формати, обов'язкові поля, таймаути, повторні відповіді й коди помилок. І я за поступову інтеграцію, бо так одразу видно, який саме зв'язок зламався.
🗣 How to say it out loud To me integration testing is testing the seams. I separate two levels: when modules of our own system talk to each other, and when we talk to the outside world, say a payment provider. My favourite example is an amount one side sends in hryvnias and the other reads in kopecks: both unit suites are green and the wrong money gets charged. So at every seam I check formats, mandatory fields, timeouts, repeated responses and error codes. And I prefer incremental integration, because then it is obvious which link broke.
15 Що робить системне тестування і чому для нього потрібне середовище, схоже на продакшн? What does system testing do, and why does it need a production-like environment?
Рівні й типиLevels & types Junior ▶

Що це. Системне тестування перевіряє повністю зібраний застосунок як єдине ціле на відповідність вимогам — і функціональним, і нефункціональним. Об'єкт тут — вся система з її інтерфейсом, API, базою та конфігурацією. Зазвичай це робить незалежна команда тестування, дивлячись на систему очима користувача та бізнесу.

What it is. System testing checks the fully assembled application as a whole against its requirements, both functional and non-functional. The test object is the entire system with its UI, API, database and configuration. It is usually done by an independent test team looking at the system through the eyes of the user and the business.

Навіщо. Лише на цьому рівні видно наскрізні сценарії: зареєструвався, додав товар, оплатив, отримав лист, побачив замовлення в історії. Тут же проявляються дефекти конфігурації — не той SMTP-сервер, відсутній переклад, неправильний часовий пояс. Щоб результатам можна було вірити, середовище має бути максимально схожим на продакшн: ті самі версії, налаштування, обсяги даних.

Why it matters. Only at this level can you see end-to-end scenarios: sign up, add a product, pay, get the email, see the order in history. Configuration defects appear here too — the wrong SMTP server, a missing translation, the wrong time zone. For the results to be trustworthy, the environment has to be as close to production as possible: same versions, settings and data volumes.

Приклад. На локальній машині розробника чекаут працює, бо часовий пояс там Київ. На стейджингу, де сервер стоїть у UTC, замовлення, оформлене о 00:30, потрапляє у звіт за попередню добу. Системний тест «замовлення після півночі» ловить це до релізу.

Example. Checkout works on the developer's laptop because its time zone is Kyiv. On staging, where the server runs in UTC, an order placed at 00:30 lands in the previous day's report. A system test for "an order after midnight" catches this before release.

Підводні камені. Системне тестування не замінює нижчих рівнів: шукати помилку округлення через UI довго й дорого. Інша пастка — «стейджинг» із трьома товарами в базі, на якому не видно проблем пагінації, пошуку чи продуктивності.

Pitfalls. System testing does not replace the lower levels: hunting a rounding bug through the UI is slow and expensive. Another trap is a staging with three products in the database, where pagination, search and performance problems simply cannot show up.

Системний сценарій: оформлення замовлення
System scenario: placing an order
ST-CHK-07 Замовлення після півночі
Середовище: staging, сервер UTC, браузер Europe/Kyiv
Кроки:
  1. Увійти як buyer_01, 00:30 за Києвом
  2. Додати «Кава 1 кг» у кошик, оформити, оплатити карткою
  3. Відкрити листа-підтвердження
  4. Адмінка → Звіт за сьогодні
Очікувано:
  - статус замовлення paid
  - у листі й історії дата за Києвом
  - замовлення у звіті за поточну дату, а не вчорашню
ST-CHK-07 Order after midnight
Environment: staging, server UTC, browser Europe/Kyiv
Steps:
  1. Log in as buyer_01 at 00:30 Kyiv time
  2. Add "Coffee 1 kg" to the cart, check out, pay by card
  3. Open the confirmation email
  4. Admin → Today's report
Expected:
  - order status is paid
  - email and history show the Kyiv date
  - order appears in today's report, not yesterday's
🔧 Як читати: це наскрізний сценарій, що зачіпає UI, оплату, пошту й звітність одночасно. Рядок «Середовище» тут ключовий: без різниці часових поясів між сервером і клієнтом дефект не відтвориться. Очікувані результати перевіряють кілька частин системи, а не одне поле.
🔧 How to read it: this is an end-to-end scenario touching the UI, payment, email and reporting at once. The "Environment" line is the key one: without the time-zone gap between server and client the defect will not reproduce. The expected results check several parts of the system, not a single field.
💡 Простими словами: системний тест — це тест-драйв зібраного авто на справжній дорозі, а не перевірка двигуна на стенді.
💡 In plain words: a system test is a test drive of the assembled car on a real road, not an engine check on a bench.
🗣 Як читати вголос Системне тестування — це коли я беру всю зібрану систему і перевіряю її проти вимог, від реєстрації до листа з підтвердженням. Тут я дивлюсь і на функціональність, і на нефункціональні речі. Мені важливо, щоб стенд був схожий на прод: однакові версії, конфіги, нормальний обсяг даних. Бо інакше пропускаєш баги на кшталт часового поясу — у розробника все працює, а на сервері в UTC нічне замовлення падає у вчорашній звіт. Водночас я не намагаюсь ловити через UI те, що дешевше перевірити юніт-тестом.
🗣 How to say it out loud System testing is when I take the whole assembled system and check it against the requirements, from sign-up to the confirmation email. I look at both functional and non-functional aspects here. It matters to me that the environment resembles production: same versions, configs and a realistic amount of data. Otherwise you miss bugs like the time-zone one — it all works on the developer's machine, but on a UTC server a late-night order drops into yesterday's report. At the same time I do not try to catch through the UI what a unit test finds more cheaply.
16 Хто проводить UAT, на що він спирається і чим відрізняється від системного тестування? Who performs UAT, what is it based on, and how is it different from system testing?
Рівні й типиLevels & types Junior ▶

Що це. User Acceptance Testing — приймальне тестування, під час якого бізнес-користувачі або замовник підтверджують, що система дає їм змогу виконувати реальну роботу. Тестова база тут — бізнес-процеси, user stories і договірні вимоги, а не технічна специфікація. CTFL 4.0 виділяє кілька форм приймання: користувацьке, операційне (резервні копії, моніторинг, відновлення), договірне й регуляторне, а також альфа- та бета-тестування.

What it is. User Acceptance Testing is acceptance testing in which business users or the customer confirm that the system lets them do their real work. The test basis is business processes, user stories and contractual requirements rather than the technical specification. CTFL 4.0 lists several forms of acceptance: user, operational (backups, monitoring, recovery), contractual and regulatory, plus alpha and beta testing.

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

Why it matters. A system test answers "does it work as described", while UAT answers "can we use this in our process". The goal of UAT is confidence and an acceptance decision, not finding as many defects as possible. If accounting cannot close the month with the new report, the feature is not accepted, even if it matches the specification perfectly.

Приклад. Бухгалтерка проходить сценарій «повернення товару за частковою оплатою» на даних, схожих на свої. Вона помічає, що звіт показує повернення окремим рядком, а їй для звірки потрібен підсумок по замовленню. Технічно це не баг, але приймальний критерій не виконано — це стає зміною для команди.

Example. An accountant walks through a "refund on a partially paid order" scenario using data close to her own. She notices the report shows the refund as a separate line, while reconciliation needs a total per order. Technically it is not a bug, but the acceptance criterion is not met, so it becomes a change request for the team.

Підводні камені. UAT не є «ще одним колом системного тестування силами бізнесу»: якщо користувачі знаходять там збої на кшталт помилки 500, значить, попередні рівні щось пропустили. Роль QA на UAT — підготувати середовище, дані, сценарії та допомогти оформити зауваження, а не проходити тести замість користувачів.

Pitfalls. UAT is not "one more round of system testing done by the business": if users hit failures like a 500 error there, the earlier levels missed something. The QA role in UAT is to prepare the environment, data and scenarios and to help log feedback, not to run the tests instead of the users.

Рядок UAT-сценарію очима бізнес-користувача
A UAT script row from a business user's view
UAT-FIN-03  Повернення за частковою оплатою
Роль:        бухгалтер
Бізнес-крок: оформити повернення 2 з 5 позицій замовлення
Дані:        замовлення 5 400 грн, сплачено 3 000 грн
Очікую:      у звіті «Звірка» один підсумок по замовленню
Результат:   повернення окремим рядком, підсумку немає
Рішення:     не прийнято → change request CR-118
Підпис:      О. Коваль, 12.03
UAT-FIN-03  Refund on a partially paid order
Role:        accountant
Business step: refund 2 of 5 order items
Data:        order 5,400 UAH, paid 3,000 UAH
I expect:    one total per order in "Reconciliation"
Result:      refund shown as a separate line, no total
Decision:    not accepted → change request CR-118
Signed:      O. Koval, 12 March
🔧 Як читати: сценарій сформульовано мовою бізнес-процесу — ролі, кроку й очікування користувача, без технічних кроків на кшталт «натиснути кнопку». Рядки «Рішення» і «Підпис» показують головне: UAT закінчується формальним рішенням про приймання конкретною людиною.
🔧 How to read it: the script is written in the language of the business process — role, business step and the user's expectation — with no technical steps like "click the button". The "Decision" and "Signed" lines show the essence: UAT ends with a formal acceptance decision by a named person.
💡 Простими словами: системний тест перевіряє, чи ключ підходить до замка; UAT — чи власник справді може зайти в свій дім.
💡 In plain words: a system test checks the key fits the lock; UAT checks the owner can actually get into their home.
🗣 Як читати вголос UAT — це приймальне тестування, яке роблять самі бізнес-користувачі або замовник. Вони спираються не на технічну специфікацію, а на свої процеси: чи може бухгалтер закрити місяць, чи може оператор оформити повернення. Головне, що я підкреслюю, — мета тут не шукати баги, а отримати рішення «приймаємо чи ні». Моя роль як QA — підготувати стенд, реалістичні дані й сценарії, а потім допомогти оформити зауваження. Якщо ж на UAT вилазять падіння сервера, для мене це сигнал, що ми недотестували раніше.
🗣 How to say it out loud UAT is acceptance testing carried out by the business users or the customer themselves. They rely not on the technical spec but on their own processes: can the accountant close the month, can the operator process a refund. The key point I stress is that the goal is not bug hunting but a decision — do we accept this or not. My job as QA is to prepare the environment, realistic data and scenarios, then help record the feedback. If server crashes show up during UAT, that tells me we under-tested earlier.
17 Чим альфа-тестування відрізняється від бета-тестування і що має дати бета-програма? How does alpha testing differ from beta testing, and what should a beta programme deliver?
Рівні й типиLevels & types Junior ▶

Що це. Обидва — форми приймального тестування. Альфа-тестування проходить на майданчику розробника: продукт перевіряють потенційні користувачі або внутрішні співробітники не з команди розробки, часто в присутності команди. Бета-тестування проходить у реальному середовищі користувачів: обрана група клієнтів користується майже готовою версією на своїх пристроях і зі своїми даними.

What it is. Both are forms of acceptance testing. Alpha testing happens at the developer's site: potential users or internal staff outside the development team try the product, often with the team nearby. Beta testing happens in the users' own environment: a selected group of customers use a nearly finished version on their own devices and with their own data.

Навіщо. Альфа ловить грубі проблеми використання, поки їх ще дешево виправити і поки команда може спостерігати. Бета показує те, чого не відтворити в лабораторії: різноманіття пристроїв, мережі, реальні звички, неочікувані сценарії. Для мобільних застосунків бета зазвичай іде через TestFlight або закриті треки Google Play.

Why it matters. Alpha catches rough usability problems while they are still cheap to fix and while the team can watch. Beta reveals what a lab cannot reproduce: the variety of devices, networks, real habits and unexpected scenarios. For mobile apps a beta usually runs through TestFlight or closed tracks on Google Play.

Приклад. Банк випускає новий застосунок. Альфа: 30 співробітників з інших відділів два тижні користуються ним у офісі. Бета: 2 000 клієнтів отримують запрошення. Уже на третій день бета-телеметрія показує, що на певній моделі Android з увімкненим режимом економії енергії не приходять push-коди підтвердження — у лабораторії такого сполучення не було.

Example. A bank ships a new app. Alpha: 30 employees from other departments use it in the office for two weeks. Beta: 2,000 customers receive an invitation. By day three the beta telemetry shows that on one Android model with battery saver on, push confirmation codes never arrive — a combination the lab never had.

Підводні камені. Бета без каналу зворотного зв'язку і без збору крешів — просто ранній реліз. Варто заздалегідь вирішити, які метрики і які відгуки вважаються сигналом зупинити розгортання, і не забути про згоду користувачів на збір даних.

Pitfalls. A beta with no feedback channel and no crash reporting is just an early release. Decide in advance which metrics and which feedback count as a signal to halt the rollout, and do not forget user consent for data collection.

Альфа проти бети + форма відгуку бета-тестера
Alpha versus beta + a beta feedback form
             | Альфа                  | Бета
-------------+------------------------+----------------------
Де           | у розробника           | у користувачів
Хто          | внутрішні, не з команди| обрані клієнти
Стабільність | може падати            | майже реліз
Спостереження| пряме, поруч           | телеметрія, відгуки

Форма відгуку (бета)
- Що ви намагались зробити?
- Що сталося замість очікуваного?
- Пристрій, ОС, версія застосунку (заповн. автоматично)
- Наскільки це заважає: 1 — ледь помітно ... 5 — не можу
- Дозволити приєднати лог? [так/ні]
             | Alpha                  | Beta
-------------+------------------------+----------------------
Where        | developer's site       | users' environment
Who          | internal, not the team | selected customers
Stability    | may crash              | release candidate
Observation  | direct, in the room    | telemetry, feedback

Feedback form (beta)
- What were you trying to do?
- What happened instead of what you expected?
- Device, OS, app version (filled in automatically)
- How much does it block you: 1 barely ... 5 I cannot continue
- Allow attaching the log? [yes/no]
🔧 Як читати: таблиця порівнює дві форми за місцем, учасниками, зрілістю збірки та способом спостереження. Форма нижче — мінімум, щоб відгук бета-тестера можна було відтворити: намір, фактичний результат, середовище, вплив і лог за згодою.
🔧 How to read it: the table compares the two forms by place, participants, build maturity and how the team observes. The form below is the minimum that makes a beta tester's feedback reproducible: intent, actual result, environment, impact and a log with consent.
💡 Простими словами: альфа — генеральна репетиція в залі без глядачів з вулиці, бета — прем'єра для запрошених гостей.
💡 In plain words: alpha is a dress rehearsal in your own hall; beta is a preview night for invited guests.
🗣 Як читати вголос Я пояснюю різницю через місце і людей. Альфа — у нас, продуктом користуються внутрішні люди поза командою розробки, і ми бачимо все на власні очі. Бета — вже в реальному світі, на пристроях і даних обраних клієнтів. Альфа дає дешеві ранні відгуки, а бета — несподівані комбінації, які в лабораторії не повториш, як-от режим економії батареї на конкретному телефоні. Для мене бета без збору крешів і простої форми відгуку нічого не варта, тому я наполягаю, щоб це було налаштовано до старту.
🗣 How to say it out loud I explain the difference through place and people. Alpha happens with us: internal people outside the dev team use the product and we see everything first-hand. Beta is out in the real world, on selected customers' devices and data. Alpha gives cheap early feedback, beta gives the surprising combinations you cannot repeat in a lab, like battery saver on one particular phone. For me a beta without crash reporting and a simple feedback form is worth nothing, so I push for both to be set up before it starts.
18 Чим функціональне тестування відрізняється від нефункціонального і які типи тестування за метою варто назвати? How does functional testing differ from non-functional testing, and which test types by purpose should you name?
Рівні й типиLevels & types Junior ▶

Що це. Функціональне тестування перевіряє, що система робить: чи правильні результати, чи виконуються бізнес-правила. Нефункціональне — наскільки добре вона це робить: швидкість, надійність, безпеку, зручність, сумісність, доступність. CTFL 4.0 спирається на модель якості ISO/IEC 25010, де характеристики — функціональна придатність, ефективність продуктивності, сумісність, взаємодія з користувачем (usability), надійність, безпека, супровідність і переносимість.

What it is. Functional testing checks what the system does: whether results are correct and business rules hold. Non-functional testing checks how well it does it: speed, reliability, security, usability, compatibility, accessibility. CTFL 4.0 leans on the ISO/IEC 25010 quality model, whose characteristics include functional suitability, performance efficiency, compatibility, usability (interaction capability), reliability, security, maintainability and portability.

Навіщо. Користувач кидає продукт не лише через неправильний результат, а й через повільну сторінку чи форму, яку неможливо заповнити з клавіатури. Якщо в плані тестування є лише функціональні перевірки, половина ризиків лишається непокритою. До речі, чорна й біла скринька — це не окремі типи за метою, а підходи до проєктування тестів.

Why it matters. Users abandon a product not only over a wrong result but also over a slow page or a form that cannot be filled in from the keyboard. If a test plan contains only functional checks, half the risks stay uncovered. Note that black-box and white-box are not types by purpose; they are approaches to designing tests.

Приклад. Для однієї фічі «вхід у систему» можна скласти перевірки кожного типу: правильний пароль пускає, неправильний — ні (функціональне); сторінка відповідає за 1 с при 500 одночасних входах (продуктивність); після 5 невдалих спроб — блокування (безпека); поля мають підписи для скрінрідера (доступність); вхід працює в Safari на iOS (сумісність).

Example. For a single "log in" feature you can write checks of every type: a correct password gets you in, a wrong one does not (functional); the page responds within 1 s with 500 concurrent logins (performance); after 5 failed attempts the account locks (security); fields have labels for screen readers (accessibility); login works in Safari on iOS (compatibility).

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

Pitfalls. The line is not always sharp: locking after five attempts is a functional rule implementing a security requirement. Do not argue about classification in the interview; show that you cover both sides.

Одна фіча — різні типи тестування
One feature, several test types
Фіча: Вхід у систему
Тип              | Перевірка
-----------------+---------------------------------------
Функціональне    | вірний пароль → кабінет, невірний → помилка
Продуктивність   | p95 відповіді ≤ 1 с при 500 входах/хв
Безпека          | 5 невдалих спроб → блок на 15 хв
Зручність        | фокус одразу в полі e-mail
Доступність      | поля мають label, помилки озвучуються
Сумісність       | Chrome, Safari iOS 17, Firefox
Надійність       | падіння сервісу сесій → зрозуміле повідомлення
Feature: Log in
Type             | Check
-----------------+---------------------------------------
Functional       | right password → account, wrong → error
Performance      | p95 response ≤ 1 s at 500 logins/min
Security         | 5 failed attempts → 15 min lock
Usability        | focus lands in the e-mail field
Accessibility    | fields have labels, errors announced
Compatibility    | Chrome, Safari iOS 17, Firefox
Reliability      | session service down → clear message
🔧 Як читати: перший рядок таблиці — функціональна перевірка, решта — нефункціональні, згруповані за характеристиками якості. Числа на кшталт «1 с» чи «15 хв» — приклад вимог, які команда фіксує для свого продукту, а не загальний стандарт.
🔧 How to read it: the first row is a functional check; the rest are non-functional, grouped by quality characteristic. Figures like "1 s" or "15 min" are sample requirements a team would set for its own product, not a universal standard.
💡 Простими словами: функціональне — «чи відкривається двері ключем», нефункціональне — «як швидко, як надійно і чи зможе це зробити людина з милицею».
💡 In plain words: functional asks "does the key open the door"; non-functional asks how fast, how reliably, and whether someone on crutches can do it too.
🗣 Як читати вголос Я розводжу так: функціональне тестування відповідає на питання «що робить система», а нефункціональне — «наскільки добре». Щоб не перелічувати типи навмання, я опираюсь на ISO 25010: продуктивність, безпека, зручність, сумісність, надійність і так далі. А потім показую на одній фічі, наприклад на логіні, як для неї з'являється перевірка кожного типу. Ще я уточнюю, що чорна і біла скринька — це не типи за метою, а способи придумувати тести, їх часто плутають.
🗣 How to say it out loud I split it like this: functional testing answers "what does the system do" and non-functional answers "how well does it do it". So I do not list types at random, I lean on ISO 25010 — performance, security, usability, compatibility, reliability and so on. Then I take one feature, say login, and show how a check of each type appears for it. I also point out that black box and white box are not purpose types but ways of coming up with tests; people mix them up a lot.
19 Як перетворити розмиту нефункціональну вимогу на таку, яку можна перевірити? How do you turn a vague non-functional requirement into one you can actually test?
Рівні й типиLevels & types Middle ▶

Що це. Нефункціональне тестування перевіряє характеристики якості — продуктивність, надійність, безпеку, зручність, масштабованість. Проблема в тому, що вимоги до них часто звучать як «система має бути швидкою» чи «зручною». Таку фразу неможливо ні підтвердити, ні спростувати, отже, і протестувати. Робота QA — разом з аналітиком і бізнесом перетворити її на вимірювану умову: метрика, поріг, навантаження, середовище.

What it is. Non-functional testing checks quality characteristics — performance, reliability, security, usability, scalability. The trouble is that their requirements often read like "the system must be fast" or "user-friendly". A sentence like that can be neither confirmed nor refuted, so it cannot be tested. The QA's job is to work with the analyst and the business to turn it into a measurable condition: metric, threshold, load and environment.

Навіщо. Без числа кожен вирішує сам: розробник вважає 3 секунди нормою, продакт — катастрофою. Вимірювана вимога дає однозначний критерій проходження, дозволяє автоматизувати перевірку в пайплайні і стежити за деградацією від релізу до релізу.

Why it matters. Without a number everyone decides for themselves: the developer thinks 3 seconds is fine, the product owner thinks it is a disaster. A measurable requirement gives an unambiguous pass criterion, lets you automate the check in the pipeline and track degradation from release to release.

Приклад. «Пошук має працювати швидко» після розмови з бізнесом стає: «95-й перцентиль часу відповіді API пошуку не більше 800 мс при 200 запитах на секунду протягом 30 хвилин на стенді з каталогом 100 000 товарів; частка помилок нижче 0,5%». Тепер зрозуміло, що вимірювати, яким інструментом, з якими даними і коли тест провалено.

Example. After a talk with the business, "search must be fast" becomes: "the 95th percentile of search API response time is at most 800 ms at 200 requests per second for 30 minutes, on an environment with a 100,000-product catalogue; error rate below 0.5%". Now it is clear what to measure, with which tool, on what data, and when the test fails.

Підводні камені. Середнє значення маскує хвости — половина користувачів може чекати довше, ніж показує середнє, тому беруть перцентилі. Числа має погодити бізнес, а не придумати тестувальник: вони залежать від продукту, і будь-який поріг у цій картці — лише ілюстрація. І не забувайте про умови: вимога без навантаження та обсягу даних ні про що не говорить.

Pitfalls. An average hides the tail — half of the users can wait longer than the mean suggests, which is why percentiles are used. The business must agree the numbers, not the tester invent them: they depend on the product, and every threshold in this card is only an illustration. And do not forget conditions: a requirement without load and data volume says nothing.

Розмита вимога → вимірювана
Vague requirement → measurable one
Було                    | Стало (приклад, узгоджено з бізнесом)
------------------------+------------------------------------
Пошук швидкий           | p95 ≤ 800 мс, 200 RPS, 30 хв,
                        | каталог 100 000, помилок < 0,5%
Система надійна         | доступність 99,9% за місяць;
                        | після рестарту БД — робота ≤ 2 хв
Дані захищені           | паролі bcrypt; сесія 30 хв;
                        | OWASP Top 10 без критичних знахідок
Зручна реєстрація       | 4 з 5 нових користувачів проходять
                        | без підказок до 2 хв
Масштабується           | при 2× навантаженні p95 росте ≤ 20%
Before                  | After (example, agreed with business)
------------------------+------------------------------------
Search is fast          | p95 ≤ 800 ms, 200 RPS, 30 min,
                        | 100,000 products, errors < 0.5%
System is reliable      | 99.9% monthly availability;
                        | after DB restart, back in ≤ 2 min
Data is protected       | passwords bcrypt; 30 min session;
                        | OWASP Top 10 with no critical findings
Sign-up is easy         | 4 of 5 new users finish unaided
                        | in under 2 min
It scales               | at 2× load p95 grows ≤ 20%
🔧 Як читати: ліва колонка — формулювання, яке неможливо перевірити; права — та сама думка з метрикою, порогом і умовами. p95 означає, що 95% запитів вклались у вказаний час. RPS — запитів на секунду. Кожне число тут — зразок, який команда фіксує у вимогах або тест-плані.
🔧 How to read it: the left column is wording that cannot be tested; the right column is the same idea with a metric, a threshold and conditions. p95 means 95% of requests finished within the given time. RPS is requests per second. Every figure is a sample the team would record in its requirements or test plan.
💡 Простими словами: якщо у вимозі немає числа й умов, її не можна «провалити» — а значить, і перевірити.
💡 In plain words: if a requirement has no number and no conditions, it cannot fail — so it cannot be tested either.
🗣 Як читати вголос Коли я бачу вимогу «має бути швидко», я не починаю тестувати, а йду з питаннями. Швидко — це скільки мілісекунд? Для якого перцентиля, при якому навантаженні, на яких обсягах даних? Разом з аналітиком і продактом ми отримуємо конкретний поріг, і тоді я можу написати тест, який однозначно проходить або падає. Я свідомо дивлюсь на перцентилі, а не на середнє, бо середнє ховає повільних користувачів. І я наголошую: числа має підтвердити бізнес, не я їх придумую.
🗣 How to say it out loud When I see a requirement saying "it must be fast", I do not start testing — I go and ask questions. Fast means how many milliseconds? For which percentile, under what load, with how much data? Together with the analyst and the product owner we land on a concrete threshold, and then I can write a test that clearly passes or fails. I deliberately use percentiles rather than the average, because the average hides the slow users. And I make the point that the business confirms the numbers; I do not make them up.
20 Чим відрізняються чорна, біла і сіра скринька, якщо протестувати одне й те саме правило? How do black-box, white-box and grey-box testing differ when applied to the same rule?
Рівні й типиLevels & types Junior ▶

Що це. Це підходи до проєктування тестів залежно від того, що тестувальник знає про систему. Чорна скринька спирається лише на специфікацію та поведінку: вхід → очікуваний вихід, без погляду на код. Біла скринька — на внутрішню структуру: гілки, умови, шляхи виконання; тут міряють покриття операторів і гілок. Сіра скринька поєднує обидва: тестуємо ззовні, але знаємо дещо про нутрощі — схему бази, API, логи, архітектуру.

What it is. These are approaches to test design depending on what the tester knows about the system. Black box relies only on the specification and behaviour: input → expected output, without looking at the code. White box relies on internal structure: branches, conditions, execution paths; here statement and branch coverage are measured. Grey box combines both: we test from the outside but know something about the internals — the database schema, the API, the logs, the architecture.

Навіщо. Кожен підхід ловить свої дефекти. Чорна скринька знаходить невідповідність вимогам, але не бачить «мертвих» гілок коду. Біла показує, яку логіку жоден тест не виконав, але не помітить, що вимоги реалізовано не ті. Сіра дає мануальному QA змогу цілитися точніше: перевірити запис у базі чи запит у Network, не читаючи весь код.

Why it matters. Each approach catches its own defects. Black box finds mismatches with requirements but cannot see dead branches in the code. White box shows which logic no test has executed but will not notice that the wrong requirement was implemented. Grey box lets a manual QA aim more precisely: check the database row or the request in Network without reading all the code.

Приклад. Правило: «безкоштовна доставка від 1000 грн». Чорна скринька: суми 999,99, 1000 і 1000,01 грн. Біла скринька: у коді умова написана як total > 1000, і тест на 1000 проходить гілку «платна доставка» — розбіжність зі специфікацією видно одразу. Сіра скринька: знаючи, що знижка застосовується до перевірки порогу, тестувальник перевіряє кошик 1100 грн із промокодом на 200 грн.

Example. The rule: "free delivery from 1000 UAH". Black box: totals of 999.99, 1000 and 1000.01 UAH. White box: the code says total > 1000, and the 1000 test goes through the "paid delivery" branch — the mismatch with the spec is obvious at once. Grey box: knowing the discount is applied before the threshold check, the tester tries a 1100 UAH cart with a 200 UAH promo code.

Підводні камені. 100% покриття гілок не означає відсутності дефектів: код може бути ідеально покритий і водночас реалізувати неправильне правило. А знання про нутрощі в сірій скриньці не повинно підміняти погляд користувача.

Pitfalls. 100% branch coverage does not mean there are no defects: code can be fully covered and still implement the wrong rule. And inside knowledge in grey-box testing must not replace the user's point of view.

Правило «безкоштовна доставка від 1000 грн» трьома способами
The "free delivery from 1000 UAH" rule, three ways
// Код, який бачить лише біла скринька
const subtotal = cart.total - promo;       // знижка ДО порогу
if (subtotal > 1000) delivery = 0;       // дефект: має бути >=
else delivery = 80;

Чорна скринька (лише специфікація)
  999,99 → 80 грн | 1000 → 0 грн (факт: 80!) | 1000,01 → 0 грн
Біла скринька (покрити обидві гілки)
  subtotal=1500 → гілка if | subtotal=500 → гілка else
Сіра скринька (знаємо про порядок розрахунку)
  кошик 1100, промо 200 → subtotal 900 → доставка 80?
  уточнити у PO: поріг від суми до чи після знижки
// Code that only the white box sees
const subtotal = cart.total - promo;       // discount BEFORE threshold
if (subtotal > 1000) delivery = 0;       // defect: should be >=
else delivery = 80;

Black box (specification only)
  999.99 → 80 UAH | 1000 → 0 UAH (actual: 80!) | 1000.01 → 0 UAH
White box (cover both branches)
  subtotal=1500 → if branch | subtotal=500 → else branch
Grey box (we know the calculation order)
  cart 1100, promo 200 → subtotal 900 → delivery 80?
  ask the PO: threshold before or after the discount
🔧 Як читати: угорі — фрагмент коду, де поріг перевіряється строгою умовою і вже після знижки. Далі три набори тестів. Зверніть увагу: білоскринькові тести з 1500 і 500 дають 100% покриття гілок і все одно не ловлять дефект на межі 1000, а чорна скринька ловить. Сіра скринька відкриває питання до вимог, яке інакше ніхто б не поставив.
🔧 How to read it: at the top is a code fragment where the threshold uses a strict comparison and runs after the discount. Below are three sets of tests. Note that the white-box tests with 1500 and 500 reach 100% branch coverage and still miss the defect at the 1000 boundary, while the black-box set catches it. The grey-box test opens a requirements question nobody would otherwise ask.
💡 Простими словами: чорна — дивишся на машину ззовні, біла — під капот, сіра — ззовні, але з кресленням у руках.
💡 In plain words: black box looks at the car from outside, white box under the bonnet, grey box from outside with the blueprint in hand.
🗣 Як читати вголос Я пояснюю це на одному правилі — безкоштовна доставка від тисячі гривень. Як чорна скринька я беру лише специфікацію і перевіряю межу: 999,99, рівно тисячу і трохи більше. Як біла скринька я дивлюсь у код і стежу, щоб обидві гілки умови виконались. А сіра скринька — це мій щоденний режим: я тестую через інтерфейс, але знаю, що знижка віднімається до перевірки порогу, і тому ставлю незручне питання продакту. Найцікавіше, що повне покриття гілок тут не рятує від бага на межі.
🗣 How to say it out loud I explain it with a single rule — free delivery from a thousand hryvnias. As a black-box tester I take only the spec and probe the boundary: 999.99, exactly a thousand and a bit over. As a white-box tester I look at the code and make sure both branches of the condition get executed. Grey box is my everyday mode: I test through the UI, but I know the discount is subtracted before the threshold check, so I ask the product owner an awkward question. The fun part is that full branch coverage does not save you from the boundary bug here.
21 Чим smoke-тест відрізняється від sanity-тесту і коли запускати кожен? How does a smoke test differ from a sanity test, and when do you run each one?
Рівні й типиLevels & types Junior ▶

Що це. Smoke-тест — короткий широкий прогін найважливіших функцій на свіжому білді: застосунок відкривається, логін працює, головний бізнес-потік проходить. Його ще називають build verification test. Sanity-тест — вузька, але глибша перевірка конкретної області після невеликої зміни чи фіксу: чи логіка, яку щойно чіпали, поводиться розумно, перш ніж витрачати час на повний регрес.

What it is. A smoke test is a short, wide run over the most important functions of a fresh build: the app starts, login works, the main business flow goes through. It is also called a build verification test. A sanity test is a narrow but deeper check of one specific area after a small change or fix: does the logic that was just touched behave reasonably before you spend time on full regression.

Навіщо і коли. Smoke запускають одразу після кожного деплою на тестове чи продакшн-середовище, і він відповідає на питання «чи можна взагалі тестувати цей білд». Якщо smoke впав, білд повертають, а не розбирають двадцять дрібних багів. Sanity запускають після фіксу або гарячого патча, коли часу мало і треба швидко переконатися, що зміна раціональна.

Why and when. Smoke runs right after every deployment to a test or production environment and answers one question: can this build be tested at all. If smoke fails, the build goes back instead of being picked apart into twenty small bugs. Sanity runs after a fix or a hotfix, when time is short and you need quick confidence that the change makes sense.

Приклад. Інтернет-магазин отримав новий білд 2.14.0. Smoke: головна відкривається, пошук повертає товари, товар додається в кошик, тестова оплата проходить. Окремо розробник виправив округлення знижки для промокоду SALE10 — sanity перевіряє саме знижку на кількох сумах і те, що підсумок у кошику збігається з підсумком у чеку.

Example. An online shop gets build 2.14.0. Smoke: the home page opens, search returns products, a product goes into the cart, a test payment succeeds. Separately, a developer fixed rounding of the SALE10 promo discount — sanity checks exactly that discount on a few amounts and that the cart total matches the receipt total.

Підводні камені. Термінологія плаває: у деяких командах sanity називають будь-яку швидку перевірку, тому на співбесіді варто коротко пояснити своє розуміння. Друга помилка — роздутий smoke на годину: він перестає бути швидким фільтром і його починають пропускати.

Pitfalls. The terms drift between teams: some call any quick check a sanity test, so in an interview it is worth stating your definition briefly. The second mistake is a smoke suite bloated to an hour: it stops being a quick gate and people start skipping it.

Smoke після деплою і sanity після фіксу
Smoke after deploy and sanity after a fix
# SMOKE · білд 2.14.0 · stage · ~10 хв
[ ] Головна сторінка відкривається, без 5xx
[ ] Логін існуючим користувачем
[ ] Пошук «кава» повертає товари
[ ] Додати товар у кошик, кількість = 1
[ ] Тестова оплата картою 4242... успішна
[ ] Замовлення видно в «Мої замовлення»
Впав хоч один пункт → білд повертаємо

# SANITY · фікс BUG-812 округлення SALE10
[ ] 99.99 грн  − 10% = 89.99 (не 89.98)
[ ] 1000.00 грн − 10% = 900.00
[ ] Підсумок у кошику = підсумок у чеку
[ ] Промокод без знижки не змінює суму
# SMOKE · build 2.14.0 · stage · ~10 min
[ ] Home page opens, no 5xx
[ ] Log in as an existing user
[ ] Search "coffee" returns products
[ ] Add a product to the cart, qty = 1
[ ] Test card payment 4242... succeeds
[ ] Order visible in "My orders"
Any item fails → the build goes back

# SANITY · fix BUG-812 SALE10 rounding
[ ] 99.99 UAH  − 10% = 89.99 (not 89.98)
[ ] 1000.00 UAH − 10% = 900.00
[ ] Cart total = receipt total
[ ] A promo without discount leaves sum as is
🔧 Як читати: верхній чекліст іде вшир — по одному кроку з кожної критичної зони, без глибини. Нижній іде вглиб однієї зміни: кілька сум, у тому числі та, на якій баг відтворювався, плюс перевірка сусіднього місця (чек). Рядок з правилом повернення білду — це і є сенс smoke як вхідного фільтра.
🔧 How to read it: the upper checklist goes wide — one step from each critical area, no depth. The lower one goes deep into one change: several amounts, including the one that reproduced the bug, plus a check of the neighbouring place (the receipt). The line about sending the build back is the whole point of smoke as an entry gate.
💡 Простими словами: smoke — «чи дихає пацієнт», sanity — «чи зажила саме та рана, яку зашили».
💡 In plain words: smoke asks whether the patient is breathing; sanity asks whether the one wound that was stitched has healed.
🗣 Як читати вголос Для мене smoke — це перші десять хвилин після деплою. Я пробігаю вхід, пошук, кошик і оплату, і якщо щось із цього лежить, я не заводжу купу окремих багів, а повертаю білд цілком. Sanity я роблю тоді, коли прийшов конкретний фікс: беру саме ту суму чи той сценарій, на якому баг відтворювався, плюс пару сусідніх значень. Я також знаю, що в різних командах ці слова вживають по-різному, тому завжди уточнюю, що саме команда має на увазі.
🗣 How to say it out loud For me smoke is the first ten minutes after a deploy. I run through login, search, cart and payment, and if any of those is down I don't file a pile of separate bugs, I send the whole build back. Sanity is what I do when a specific fix arrives: I take exactly the amount or scenario that reproduced the bug, plus a couple of neighbouring values. I also know teams use these words differently, so I always check what this team means by them.
22 Чим регресійне тестування відрізняється від повторного (re-testing) і як обрати обсяг регресу? How does regression testing differ from re-testing, and how do you choose the regression scope?
Рівні й типиLevels & types Junior ▶

Що це. Повторне тестування (у глосарії ISTQB — confirmation testing) — це запуск тих самих кроків, які раніше виявили дефект, щоб підтвердити, що фікс його прибрав. Регресійне тестування перевіряє інше: чи зміна в коді, конфігурації чи середовищі не зламала те, що вже працювало, у тому числі в місцях, які ніхто не чіпав.

What it is. Re-testing (confirmation testing in the ISTQB glossary) means running the same steps that exposed a defect earlier, to confirm the fix removed it. Regression testing checks something else: that a change in code, configuration or environment did not break what already worked, including areas nobody touched.

Навіщо і коли. Повторний тест завжди прив'язаний до конкретного бага і має очікуваний результат з його опису. Регрес потрібен після кожної зміни, бо в системі є залежності, яких не видно з тікета. Прогнати весь регрес на кожен фікс зазвичай неможливо, тому обсяг вибирають через аналіз впливу: що змінилося, що з цим пов'язано і що найбільше болить бізнесу.

Why and when. A re-test is always tied to one bug and takes its expected result from that report. Regression is needed after every change, because the system has dependencies you cannot see from the ticket. Running the whole regression suite for every fix is usually impossible, so the scope is chosen through impact analysis: what changed, what is connected to it and what hurts the business most.

Приклад. Баг: промокод WELCOME15 не застосовувався до товарів зі знижкою. Розробник змінив функцію розрахунку ціни. Re-test — повторити кроки з бага. Регрес — усе, що використовує ту саму функцію: інші промокоди, кошик, повернення коштів, експорт замовлень у бухгалтерію, плюс короткий smoke оплати.

Example. Bug: the WELCOME15 promo code did not apply to discounted items. The developer changed the price calculation function. Re-test — repeat the steps from the bug. Regression — everything that uses the same function: other promo codes, the cart, refunds, order export to accounting, plus a short payment smoke.

Підводні камені. Закрити баг лише після re-test без регресу — класичний шлях до «виправили одне, зламали друге». Протилежна крайність — вимагати повний ручний регрес на кожен однорядковий фікс. Зазвичай регрес — найкращий кандидат на автоматизацію, бо він повторюється.

Pitfalls. Closing a bug after a re-test alone, with no regression, is the classic road to "fixed one thing, broke another". The opposite extreme is demanding a full manual regression for every one-line fix. Regression is usually the best candidate for automation precisely because it repeats.

Аналіз впливу для фіксу промокоду
Impact analysis for a promo code fix
Зміна: calculatePrice() — BUG-431 WELCOME15

RE-TEST (кроки з бага)
  Товар зі знижкою 20% + WELCOME15 → −15% застосовано

РЕГРЕС (хто ще викликає calculatePrice)
  Зона               Ризик    Глибина
  Інші промокоди     високий  всі типи кодів
  Підсумок кошика    високий  1, 3, 10 товарів
  Повернення коштів  середній часткове повернення
  Експорт у бухгалт.  середній одна вибірка
  Оплата (smoke)     високий  одна успішна оплата
  Профіль, пошук     низький  не тестуємо
Change: calculatePrice() — BUG-431 WELCOME15

RE-TEST (steps from the bug)
  Item with 20% off + WELCOME15 → −15% applied

REGRESSION (who else calls calculatePrice)
  Area               Risk     Depth
  Other promo codes  high     every code type
  Cart total         high     1, 3, 10 items
  Refunds            medium   partial refund
  Accounting export  medium   one sample
  Payment (smoke)    high     one successful payment
  Profile, search    low      not tested
🔧 Як читати: верхній блок — один сценарій з бага, це re-test. Нижня таблиця — регрес: зони знайдені через спільну функцію, а глибина залежить від ризику. Рядок «не тестуємо» теж важливий — це свідоме рішення, яке можна пояснити команді.
🔧 How to read it: the top block is the one scenario from the bug — that is the re-test. The table below is regression: areas are found through the shared function, and depth depends on risk. The "not tested" row matters too — it is a deliberate decision you can explain to the team.
💡 Простими словами: re-test питає «чи зник цей баг», регрес питає «чи не з'явились нові поруч».
💡 In plain words: a re-test asks whether this bug is gone; regression asks whether new ones appeared next to it.
🗣 Як читати вголос Я чітко розділяю ці дві речі. Re-test, або confirmation testing, — це коли я беру кроки саме з того бага і дивлюсь, чи він зник. Регрес — коли я шукаю, що могло зламатися поруч. Щоб не ганяти все підряд, я питаю розробника, яку функцію він міняв, і дивлюсь, хто ще її використовує. Так для фіксу промокоду я перевіряю інші коди, кошик і повернення, а профіль користувача свідомо не чіпаю і пишу про це в тікеті.
🗣 How to say it out loud I keep these two apart. A re-test, or confirmation testing, is when I take the steps from that exact bug and see whether it is gone. Regression is when I look for what might have broken around it. To avoid running everything, I ask the developer which function they changed and check who else calls it. So for a promo code fix I cover the other codes, the cart and refunds, and I deliberately leave the user profile alone and say so in the ticket.
23 Як провести юзабіліті-тестування і чим воно відрізняється від думки тестера «мені незручно»? How do you run usability testing, and how is it different from a tester saying "this feels awkward to me"?
Рівні й типиLevels & types Middle ▶

Що це. Юзабіліті-тестування оцінює, наскільки реальні користувачі з цільової аудиторії можуть досягти своїх цілей ефективно, результативно і із задоволенням. Учасникам дають реалістичні задачі без підказок і спостерігають, де вони губляться. Буває модероване (ведучий поруч або на відеодзвінку) і немодероване (учасник проходить задачі сам, інструмент записує екран).

What it is. Usability testing assesses how effectively, efficiently and satisfyingly real users from the target audience can reach their goals. Participants get realistic tasks with no hints, and you watch where they get lost. It can be moderated (a facilitator sits next to them or on a video call) or unmoderated (the participant works alone and a tool records the screen).

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

Why it matters. A functionally correct form can be so confusing that people abandon checkout. A tester's opinion is a useful heuristic, but a tester knows the product by heart and is not a typical user. A usability test gives facts: how many participants completed the task, how long it took, how many errors they made and what they said out loud.

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

Example. A team redesigns the delivery step. Five participants get the task "order coffee for delivery to a post office branch in another city". Three look for the branch picker in the address field and two give up — a far stronger argument than "I think the field is unclear". Jakob Nielsen's five-user rule is a heuristic for iterative rounds, not a statistical guarantee.

Підводні камені. Навідні задачі («натисніть кнопку Обрати відділення») ламають тест. Колеги з команди — погані учасники. І юзабіліті не те саме, що доступність: перше про зручність для цільової аудиторії, друге — про можливість користуватися продуктом людям з інвалідністю.

Pitfalls. Leading tasks ("click the Choose branch button") ruin the test. Teammates are poor participants. And usability is not accessibility: the first is about ease of use for the target audience, the second about people with disabilities being able to use the product at all.

Сценарій модерованої сесії
Moderated session script
Ціль: знайти, де ламається вибір доставки
Учасники: 5, купували онлайн за останній місяць
Формат: відеодзвінок, 30 хв, думати вголос

Задача 1  «Замовте пачку кави з доставкою
          на відділення пошти у Львові.»
  Успіх:  дійшли до екрана оплати з відділенням
  Метрики: успіх так/ні, час, кількість помилок

Задача 2  «Змініть адресу доставки на домашню.»

Ведучому: не підказувати, питати «Що ви
очікували побачити?», фіксувати цитати.

Результат: 3/5 шукали відділення в полі адреси
Goal: find where delivery choice breaks down
Participants: 5, bought online in the last month
Format: video call, 30 min, think aloud

Task 1  "Order a pack of coffee for delivery
        to a post office branch in Lviv."
  Success: reached payment with a branch set
  Metrics: success yes/no, time, error count

Task 2  "Change the delivery address to home."

Facilitator: no hints, ask "What did you
expect to see?", capture quotes.

Result: 3/5 looked for the branch in address
🔧 Як читати: задача сформульована мовою цілі користувача, а не інтерфейсу — у ній немає назв кнопок. Критерій успіху і метрики визначені заздалегідь, щоб після сесій не сперечатися про враження. Останній рядок — знахідка у вигляді числа, яку можна показати дизайнеру.
🔧 How to read it: the task is phrased in terms of the user's goal, not the interface — it names no buttons. The success criterion and metrics are set in advance, so nobody argues about impressions after the sessions. The last line is a finding expressed as a number you can show a designer.
💡 Простими словами: не питай людей, чи їм зручно, — дай їм задачу і мовчки дивись, де вони спіткнуться.
💡 In plain words: don't ask people whether it is easy — give them a task and quietly watch where they stumble.
🗣 Як читати вголос Коли мені щось здається незручним, я фіксую це як спостереження, але розумію, що я не типовий користувач — я бачив цей екран сотню разів. Справжнє юзабіліті-тестування — це кілька людей з цільової аудиторії, реалістична задача без назв кнопок і тиша з боку ведучого. Я записую, чи людина дійшла до мети, скільки часу пішло і де вона завагалась. Тоді дизайнер отримує не мої смаки, а фразу «троє з п'яти не знайшли вибір відділення».
🗣 How to say it out loud When something feels awkward to me, I log it as an observation, but I know I'm not a typical user — I've seen that screen a hundred times. Real usability testing means a few people from the target audience, a realistic task that names no buttons, and a facilitator who stays quiet. I note whether the person reached the goal, how long it took and where they hesitated. Then the designer gets "three out of five couldn't find the branch picker" instead of my personal taste.
24 Яку версію WCAG беруть за основу і що мануальний тестер перевіряє на доступність сам? Which WCAG version is the baseline, and what can a manual tester check for accessibility on their own?
Рівні й типиLevels & types Middle ▶

Що це. WCAG (Web Content Accessibility Guidelines) — стандарт W3C з доступності вебконтенту. Актуальна рекомендація — WCAG 2.2 (жовтень 2023), вона додала критерії на кшталт мінімального розміру цілі для натискання і видимого фокусу, який не перекривається. WCAG 2.1 рівня AA досі найчастіше фігурує в законодавстві, наприклад через європейський стандарт EN 301 549. Критерії згруповані за принципами POUR: сприйнятність, керованість, зрозумілість, надійність, і мають рівні A, AA, AAA; ціль зазвичай AA.

What it is. WCAG (Web Content Accessibility Guidelines) is the W3C standard for web content accessibility. The current recommendation is WCAG 2.2 (October 2023), which added criteria such as a minimum target size for pointer input and a focus that is not obscured. WCAG 2.1 level AA is still what legislation most often references, for example through the European standard EN 301 549. Criteria are grouped under the POUR principles — perceivable, operable, understandable, robust — and have levels A, AA and AAA; the usual target is AA.

Навіщо. Автоматичні сканери на кшталт axe чи Lighthouse ловлять лише частину проблем: вони бачать відсутній alt, але не скажуть, чи alt має сенс. Решту закриває ручна перевірка: клавіатура, скрінрідер, масштаб, контраст.

Why it matters. Automated scanners such as axe or Lighthouse catch only part of the problems: they see a missing alt but cannot tell whether the alt makes sense. The rest is covered by hand: keyboard, screen reader, zoom, contrast.

Приклад. Форма реєстрації: пройти її лише клавішею Tab, перевірити, що фокус видно, що помилка «невірний email» озвучується скрінрідером NVDA і прив'язана до поля, що кнопка «Далі» не менша за 24 на 24 CSS-пікселі, а сірий текст підказки має контраст щонайменше 4.5:1.

Example. A sign-up form: complete it using only Tab, check that focus is visible, that the "invalid email" error is announced by the NVDA screen reader and tied to the field, that the Next button is at least 24 by 24 CSS pixels, and that grey hint text has a contrast of at least 4.5:1.

Підводні камені. Колір як єдиний сигнал помилки (червона рамка без тексту) — порушення 1.4.1. Ще одна пастка — додавати ARIA там, де вистачить нативного button чи label: неправильний ARIA гірший за його відсутність.

Pitfalls. Colour as the only error signal (a red border with no text) breaks 1.4.1. Another trap is adding ARIA where a native button or label would do: wrong ARIA is worse than none.

Ручний чекліст доступності для форми
Manual accessibility checklist for a form
SC       Рівень  Що перевіряю руками
1.1.1    A       Картинки мають змістовний alt
1.3.1    A       Кожне поле має підпис (label)
1.4.1    A       Помилка не лише червоним кольором
1.4.3    AA      Контраст тексту ≥ 4.5:1
1.4.10   AA      Ширина 320 px без гориз. скролу
2.1.1    A       Усе робиться з клавіатури
2.4.3    A       Порядок Tab логічний
2.4.7    AA      Фокус видно
2.4.11   AA      Фокус не ховає липкий хедер (2.2)
2.5.8    AA      Ціль ≥ 24×24 CSS px (2.2)
3.3.1    A       Помилка описана текстом
4.1.2    A       Скрінрідер озвучує роль і назву
SC       Level   What I check by hand
1.1.1    A       Images have a meaningful alt
1.3.1    A       Every field has a label
1.4.1    A       Errors are not colour-only
1.4.3    AA      Text contrast ≥ 4.5:1
1.4.10   AA      320 px width, no horizontal scroll
2.1.1    A       Everything works from the keyboard
2.4.3    A       Tab order is logical
2.4.7    AA      Focus is visible
2.4.11   AA      Sticky header hides no focus (2.2)
2.5.8    AA      Target ≥ 24×24 CSS px (2.2)
3.3.1    A       Error is described in text
4.1.2    A       Screen reader says role and name
🔧 Як читати: перша колонка — номер критерію успіху (success criterion) з WCAG, за ним легко знайти пояснення на w3.org і послатися в баг-репорті. Позначка 2.2 означає, що критерій з'явився лише у версії 2.2. Контраст 4.5:1 стосується звичайного тексту; для великого тексту вимога 3:1.
🔧 How to read it: the first column is the WCAG success criterion number, which makes it easy to find the explanation on w3.org and cite it in a bug report. The 2.2 mark means the criterion exists only since version 2.2. The 4.5:1 contrast applies to normal text; large text needs 3:1.
💡 Простими словами: відклади мишку, увімкни скрінрідер і спробуй зареєструватися — половину проблем знайдеш за десять хвилин.
💡 In plain words: put the mouse away, turn on a screen reader and try to sign up — you will find half the problems in ten minutes.
🗣 Як читати вголос Я орієнтуюсь на WCAG 2.2 рівня AA, але пам'ятаю, що в законах і контрактах часто досі прописана 2.1 AA, тому уточнюю вимогу в проєкті. Сканер типу axe запускаю першим, бо він дешевий, але він не бачить, чи зрозумілий alt або чи логічний порядок фокусу. Тому я проходжу форму тільки клавіатурою, слухаю її в NVDA, збільшую масштаб до 400 відсотків і міряю контраст. У баг-репорті посилаюсь на номер критерію, так розробнику легше погодитись, що це не мій смак.
🗣 How to say it out loud I aim for WCAG 2.2 level AA, but I remember that laws and contracts often still name 2.1 AA, so I check what the project actually requires. I run a scanner like axe first because it is cheap, but it cannot tell whether an alt text makes sense or whether the focus order is logical. So I go through the form with the keyboard only, listen to it in NVDA, zoom to 400 percent and measure contrast. In the bug report I cite the criterion number, which makes it easier for a developer to accept it isn't just my taste.
25 Як скласти матрицю сумісності, якщо перевірити всі браузери й пристрої неможливо? How do you build a compatibility matrix when testing every browser and device is impossible?
Рівні й типиLevels & types Middle ▶

Що це. Тестування сумісності перевіряє, що продукт працює однаково коректно в різних браузерах, операційних системах, на різних пристроях, роздільностях і версіях залежностей — наприклад, з різними версіями Android чи сторонніх бібліотек. Для вебу головні осі — рушій браузера (Chromium, WebKit, Gecko), ОС, розмір екрана і тип вводу (миша чи дотик).

What it is. Compatibility testing checks that the product works equally well across browsers, operating systems, devices, screen sizes and dependency versions — for example different Android versions or third-party libraries. For the web the main axes are the browser engine (Chromium, WebKit, Gecko), the OS, the screen size and the input type (mouse or touch).

Навіщо і як обрати. Комбінацій тисячі, тому матрицю будують з даних, а не з уявлень: беруть аналітику відвідувань за останні місяці, сортують за часткою трафіку і доходу, закривають 90–95 відсотків аудиторії, а решту фіксують як прийнятий ризик. Повний прогін роблять на першому рядку, на решті — smoke і місця, де рушії відрізняються найчастіше: форми, дати, скрол, відео.

Why and how to choose. There are thousands of combinations, so the matrix is built from data, not guesses: take visit analytics for recent months, sort by share of traffic and revenue, cover 90–95 percent of the audience and record the rest as an accepted risk. The full run goes on the top row; the others get smoke plus the places where engines differ most often: forms, date pickers, scrolling, video.

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

Example. The shop's analytics show that 38 percent of purchases come from Safari on iPhone. If the team only tested in Chrome on a laptop, a "date field won't open on iOS" bug reaches users. So Safari on iOS gets a full run, even though the developers barely use it.

Підводні камені. Емулятор у DevTools міняє розмір вікна і user agent, але не рушій: Safari він не відтворює. Реальні пристрої або хмарні ферми потрібні хоча б для верхніх рядків матриці. І матрицю треба переглядати — частки браузерів змінюються.

Pitfalls. The DevTools device emulator changes the viewport and user agent but not the engine: it does not reproduce Safari. Real devices or a cloud device farm are needed at least for the top rows. And the matrix has to be reviewed — browser shares change.

Матриця сумісності з аналітики
Compatibility matrix from analytics
Платформа              Частка  Покриття
Safari 17+ / iOS        38%    повний прогін
Chrome / Android        31%    повний прогін
Chrome / Windows        17%    повний прогін
Edge / Windows           5%    smoke + форми
Safari / macOS           4%    smoke + форми
Firefox / Windows        2%    smoke
Інше (Samsung, Opera)    3%    прийнятий ризик
                      -----
Покрито                 97%

Екрани: 360, 390, 768, 1366, 1920 px
Platform               Share   Coverage
Safari 17+ / iOS        38%    full run
Chrome / Android        31%    full run
Chrome / Windows        17%    full run
Edge / Windows           5%    smoke + forms
Safari / macOS           4%    smoke + forms
Firefox / Windows        2%    smoke
Other (Samsung, Opera)   3%    accepted risk
                      -----
Covered                 97%

Screens: 360, 390, 768, 1366, 1920 px
🔧 Як читати: рядки відсортовані за часткою реальних покупок, а глибина тестування падає разом із часткою. Останній рядок не забутий, а свідомо позначений як ризик — це рішення погоджують з продакт-менеджером. Ширини екранів беруть із тієї ж аналітики, а не з макета дизайнера.
🔧 How to read it: rows are sorted by the share of real purchases, and testing depth drops with the share. The last row is not forgotten but deliberately marked as a risk — that decision is agreed with the product manager. Screen widths come from the same analytics, not from the designer's mock-up.
💡 Простими словами: тестуй там, де твої користувачі, а не там, де зручно тобі.
💡 In plain words: test where your users are, not where it is convenient for you.
🗣 Як читати вголос Я ніколи не складаю матрицю з голови. Прошу доступ до аналітики, дивлюсь, з яких браузерів і пристроїв люди реально купують, і будую таблицю від найбільшої частки до найменшої. Верхні рядки отримують повний прогін, середні — smoke плюс форми, а хвіст я показую продакту як прийнятий ризик. Для Safari обов'язково беру справжній айфон або хмарну ферму, бо емуляція в Chrome — це все одно Chrome.
🗣 How to say it out loud I never build the matrix from memory. I ask for analytics access, see which browsers and devices people actually buy from, and build the table from the biggest share down. The top rows get a full run, the middle ones smoke plus forms, and I show the tail to the product owner as an accepted risk. For Safari I always use a real iPhone or a cloud farm, because emulation inside Chrome is still Chrome.
26 Чим тестування інтернаціоналізації (i18n) відрізняється від тестування локалізації (l10n)? How does internationalisation (i18n) testing differ from localisation (l10n) testing?
Рівні й типиLevels & types Middle ▶

Що це. Інтернаціоналізація (i18n) — це підготовка продукту до будь-якої мови й регіону ще на рівні архітектури: тексти винесені з коду, підтримується Unicode, формати дат, чисел і валют залежать від локалі, верстка витримує довші рядки і письмо справа наліво. Локалізація (l10n) — це адаптація під конкретний ринок: переклад, місцеві формати, юридичні тексти, культурні деталі.

What it is. Internationalisation (i18n) is preparing the product for any language and region at the architecture level: texts moved out of code, Unicode supported, date, number and currency formats driven by the locale, a layout that survives longer strings and right-to-left scripts. Localisation (l10n) is adapting to a specific market: translation, local formats, legal texts, cultural details.

Навіщо розділяти. Дефекти i18n однакові для всіх мов і дешевше знайти їх один раз, ще до перекладу, — наприклад, псевдолокалізацією, коли рядки штучно подовжують і обгортають спецсимволами. Дефекти l10n специфічні для ринку і їх часто ловить лише носій мови.

Why separate them. i18n defects are the same for every language and are cheaper to find once, before translation — for example with pseudo-localisation, where strings are artificially lengthened and wrapped in special characters. l10n defects are market-specific and often only a native speaker catches them.

Приклад. Кнопка «Buy» у німецькій стає «Jetzt kaufen» і вилазить за межі; дата 03/04/2025 для американця — 4 березня, для українця — 3 квітня; «1 товар, 2 товари, 5 товарів» — в українській три форми множини, і рядок «5 товар(ів)» видає відсутність правил плюралізації. Це i18n. А от переклад «Checkout» як «Перевірити» замість «Оформити замовлення» — дефект l10n.

Example. A "Buy" button becomes "Jetzt kaufen" in German and overflows; 03/04/2025 means March 4 to an American and April 3 to a Ukrainian; Ukrainian has three plural forms for "1 item, 2 items, 5 items", and a string like "5 item(s)" reveals missing plural rules. Those are i18n. Translating "Checkout" as the Ukrainian for "Verify" instead of "Place order" is an l10n defect.

Підводні камені. Склеювання речень з частин у коді («Ви маєте» + N + «повідомлень») робить правильний переклад неможливим. Ще часто забувають про сортування: алфавітний порядок з літерами «є», «і», «ї» відрізняється від простого порівняння кодів символів.

Pitfalls. Gluing sentences together in code ("You have" + N + "messages") makes a correct translation impossible. Sorting is also often forgotten: alphabetical order with Ukrainian letters like є, і, ї differs from a plain comparison of character codes.

Чекліст i18n і l10n для локалі uk-UA
i18n and l10n checklist for the uk-UA locale
# i18n — один раз для всіх мов
Псевдолокаль: «[Ŝàvé ćhàñĝéš ~~~~~~]»
  → текст не обрізаний, немає «голих» рядків
Ім'я «Ґалаґан Їжакевич» зберігається і
  шукається без «????»
Дата з локалі: 03.04.2025 (uk), 4/3/2025 (en-US)
Множина: 1 товар · 2 товари · 5 товарів
Арабська локаль: верстка дзеркалиться (RTL)

# l10n — для ринку України
Ціна: 1 299,00 ₴ (пробіл, кома, знак після)
Термінологія за глосарієм перекладу
Юридичний текст — чинна оферта для UA
Телефон у форматі +380
# i18n — once for every language
Pseudo-locale: "[Ŝàvé ćhàñĝéš ~~~~~~]"
  → no truncation, no untranslated strings
Name "Zoë Łukasik-Ångström" is stored and
  found without "????"
Date from locale: 03.04.2025 (uk), 4/3/2025 (en-US)
Plurals (uk): 1 tovar · 2 tovary · 5 tovariv
Arabic locale: layout mirrors (RTL)

# l10n — for the Ukrainian market
Price: 1 299,00 ₴ (space, comma, sign after)
Terms follow the translation glossary
Legal text — current offer valid for UA
Phone in +380 format
🔧 Як читати: верхній блок перевіряє механізми — псевдолокаль, кодування, форматування за локаллю, правила множини, напрям письма. Нижній перевіряє зміст для конкретного ринку. Рядок з кириличним ім'ям ловить класичний баг кодування, коли база чи API зберігає текст не в UTF-8.
🔧 How to read it: the upper block checks mechanisms — pseudo-locale, encoding, locale-aware formatting, plural rules, text direction. The lower one checks content for one market. The line with a non-ASCII name catches the classic encoding bug where a database or API stores text in something other than UTF-8.
💡 Простими словами: i18n — чи вміє продукт говорити різними мовами; l10n — чи правильно він говорить конкретною.
💡 In plain words: i18n is whether the product can speak different languages; l10n is whether it speaks one particular language correctly.
🗣 Як читати вголос Я пояснюю це так: інтернаціоналізація — про механізми, локалізація — про конкретний ринок. Механізми я ламаю ще до перекладу, вмикаю псевдолокаль і дивлюсь, чи не з'їхала верстка і чи не лишились тексти, зашиті в код. Потім перевіряю дати, числа, множину — в українській три форми, і на цьому багато хто падає. А коли приходить переклад, я вже дивлюсь на терміни, валюту, юридичні тексти, і тут дуже допомагає носій мови.
🗣 How to say it out loud I put it this way: internationalisation is about mechanisms, localisation is about a specific market. I break the mechanisms before any translation exists — I switch on a pseudo-locale and look for broken layout and text hard-coded in the source. Then I check dates, numbers and plurals; Ukrainian has three plural forms and plenty of apps get that wrong. Once the translation arrives, I look at terminology, currency and legal texts, and a native speaker helps a lot there.
27 Що перевіряє тестування відновлення і як його спланувати для платежу? What does recovery testing check, and how would you plan it for a payment flow?
Рівні й типиLevels & types Middle ▶

Що це. Тестування відновлюваності — вид нефункціонального тестування надійності: систему свідомо ламають (зупиняють базу, обривають мережу, вбивають процес, вимикають вузол) і перевіряють, чи вона повертається до робочого стану, за який час і чи не втрачає та не дублює дані. Дві ключові цифри задає бізнес: RTO — за скільки сервіс має піднятися, RPO — скільки даних максимально можна втратити.

What it is. Recovery testing is a kind of non-functional reliability testing: you deliberately break the system (stop the database, cut the network, kill a process, switch off a node) and check whether it returns to a working state, how fast, and whether it loses or duplicates data. Two key numbers come from the business: RTO — how quickly the service must be back, and RPO — how much data can be lost at most.

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

Why it matters. Production failures are inevitable, and the costliest outcome is not downtime itself but inconsistent data: money taken with no order, or two charges for one purchase. Functional tests on a stable environment never show that.

Приклад. Під час оплати перезапускають базу замовлень. Очікування: клієнт бачить зрозуміле повідомлення, повторний запит з тим самим ключем ідемпотентності не створює другого списання, після підйому бази замовлення має статус paid або платіж скасовано, а черга повідомлень довантажила пропущені події.

Example. The order database is restarted during a payment. Expectation: the customer sees a clear message, a retry with the same idempotency key does not create a second charge, after the database is back the order is either paid or the payment is voided, and the message queue has delivered the missed events.

Підводні камені. Робити таке без погодження на спільному стенді — зіпсувати день іншим командам. Потрібні окреме середовище, моніторинг і план повернення. Інша помилка — перевірити лише «сайт знову відкривається» і не звірити дані в базі та в платіжного провайдера.

Pitfalls. Doing this unannounced on a shared environment ruins the day for other teams. You need a dedicated environment, monitoring and a rollback plan. Another mistake is checking only that "the site opens again" without reconciling data in the database and at the payment provider.

Сценарій відновлення: база падає під час оплати
Recovery scenario: database goes down during payment
RT-07 · Стенд perf-2 · погоджено з DevOps
Ціль: RTO ≤ 2 хв, RPO = 0 для оплачених замовлень

1. Запустити 20 оплат/хв тестовими картками
2. На 3-й хвилині: зупинити БД замовлень
3. Через 60 с: запустити БД знову
4. Зачекати 5 хв, зупинити навантаження

Очікуємо
- користувач бачить «Спробуйте ще раз», не 500
- сервіс приймає оплати ≤ 2 хв після старту БД
- к-сть списань у провайдера = к-сть paid
- жодного подвійного списання (idempotency key)
- у черзі 0 «застряглих» подій
RT-07 · perf-2 environment · agreed with DevOps
Goal: RTO ≤ 2 min, RPO = 0 for paid orders

1. Run 20 payments/min with test cards
2. At minute 3: stop the orders DB
3. After 60 s: start the DB again
4. Wait 5 min, stop the load

Expect
- user sees "Please try again", not a 500
- payments accepted ≤ 2 min after DB start
- charges at provider = number of paid orders
- no double charge (idempotency key)
- 0 stuck events in the queue
🔧 Як читати: ціль сформульована через RTO і RPO, тож результат можна виміряти, а не оцінити на око. Кроки описують контрольований збій з точним часом. Очікування розділені на досвід користувача, швидкість відновлення і цілісність даних — остання група найважливіша і перевіряється звіркою з провайдером.
🔧 How to read it: the goal is stated through RTO and RPO, so the result can be measured rather than eyeballed. The steps describe a controlled failure with exact timing. Expectations are split into user experience, recovery speed and data integrity — the last group matters most and is verified by reconciling with the provider.
💡 Простими словами: впасти може будь-що; питання в тому, чи встане система сама і чи не загубить при цьому гроші клієнта.
💡 In plain words: anything can fall over; the question is whether the system gets back up on its own without losing the customer's money.
🗣 Як читати вголос Для мене тест відновлення починається з двох цифр від бізнесу — за скільки ми маємо піднятись і скільки даних можемо втратити. Далі я разом з DevOps на окремому стенді влаштовую контрольований збій, наприклад гашу базу посеред потоку оплат. Мене мало цікавить, що сайт знову відкрився, мене цікавить, чи збігаються гроші: скільки списав провайдер і скільки замовлень у нас оплачено, і чи немає подвійних списань після повторів.
🗣 How to say it out loud For me a recovery test starts with two numbers from the business — how fast we must be back and how much data we can afford to lose. Then, together with DevOps and on a separate environment, I stage a controlled failure, say switching off the database in the middle of a payment stream. I care less that the site opens again and more that the money adds up: what the provider charged versus how many orders we marked paid, and no double charges after retries.
28 Як організувати тестування зворотної сумісності, коли API оновлюється, а старі мобільні клієнти ще живі? How do you organise backward compatibility testing when the API changes but old mobile clients are still in use?
Рівні й типиLevels & types Senior ▶

Що це. Тестування зворотної сумісності перевіряє, що нова версія системи продовжує коректно працювати з тим, що створене чи розгорнуте для попередніх: старими версіями мобільних застосунків, інтеграціями партнерів, збереженими даними, файлами експорту, закешованими фронтендами. Мобільні клієнти тут найгостріші, бо оновлення в сторах користувачі ставлять тижнями, а частина не ставить ніколи.

What it is. Backward compatibility testing checks that a new version of a system keeps working correctly with things created or deployed for earlier ones: old mobile app versions, partner integrations, stored data, export files, cached front ends. Mobile clients are the sharpest case, because users install store updates over weeks and some never do.

Як будувати. Спершу з'ясувати, які версії клієнтів ще активні і з якою часткою, — це дає аналітика або логи API з заголовком версії застосунку. Потім класифікувати зміни в контракті: додане необов'язкове поле зазвичай безпечне, а перейменування, зміна типу, новий обов'язковий параметр чи нове значення enum ламають старих. Для кожної активної версії тримати набір контрактних перевірок і прогнати його проти нового бекенду. Окремо тестують міграції даних: записи, створені старою версією, мають читатися новою, і навпаки під час поступового розгортання.

How to build it. First find out which client versions are still active and in what share — analytics or API logs with an app version header tell you. Then classify contract changes: an added optional field is usually safe, while a rename, a type change, a new required parameter or a new enum value breaks old clients. Keep a set of contract checks per active version and run it against the new back end. Data migrations are tested separately: records created by the old version must be readable by the new one, and vice versa during a gradual rollout.

Приклад. Бекенд додає статус замовлення on_hold. Застосунок 3.2, який ще стоїть у 12 відсотків користувачів, на невідомий статус падає. Рішення — віддавати старим клієнтам processing, а новий статус лише версіям від 4.0, і перевірити обидві гілки.

Example. The back end adds an on_hold order status. App 3.2, still installed for 12 percent of users, crashes on an unknown status. The fix is to send processing to old clients and the new status only to 4.0 and up, then test both branches.

Підводні камені. Тестувати лише найновіший клієнт, бо «старі скоро оновляться». І не мати політики підтримки версій: без неї кожен реліз перетворюється на суперечку, скільки старих версій ще треба перевіряти.

Pitfalls. Testing only the newest client because "the old ones will update soon". And having no version support policy: without one, every release turns into an argument about how many old versions still need checking.

Той самий запит від старого і нового клієнта
The same request from an old and a new client
# Старий застосунок 3.2 не знає статусу on_hold
curl -s https://api.shop.test/v1/orders/1042 \
  -H "X-App-Version: 3.2.0"
# очікуємо: {"id":1042,"status":"processing"}

# Новий застосунок 4.0 отримує новий статус
curl -s https://api.shop.test/v1/orders/1042 \
  -H "X-App-Version: 4.0.0"
# очікуємо: {"id":1042,"status":"on_hold"}

# Чекліст релізу
# [ ] активні версії: 3.2 (12%), 3.5 (21%), 4.0
# [ ] жодне поле не видалене й не перейменоване
# [ ] нові обов'язкові параметри мають дефолт
# [ ] замовлення зі старої БД відкриваються в 4.0
# Old app 3.2 does not know the on_hold status
curl -s https://api.shop.test/v1/orders/1042 \
  -H "X-App-Version: 3.2.0"
# expect: {"id":1042,"status":"processing"}

# New app 4.0 gets the new status
curl -s https://api.shop.test/v1/orders/1042 \
  -H "X-App-Version: 4.0.0"
# expect: {"id":1042,"status":"on_hold"}

# Release checklist
# [ ] active versions: 3.2 (12%), 3.5 (21%), 4.0
# [ ] no field removed or renamed
# [ ] new required parameters have a default
# [ ] orders from the old DB open in 4.0
🔧 Як читати: curl -s робить GET-запит без індикатора прогресу, -H додає заголовок, яким клієнт повідомляє свою версію, а зворотна коса риска переносить команду на новий рядок. Один і той самий ресурс перевіряється двічі з різними версіями, і очікування різні — саме так видно, що бекенд підлаштовується під старого клієнта. Чекліст внизу — мінімум, який варто пройти перед кожним релізом API.
🔧 How to read it: curl -s makes a GET request without the progress meter, -H adds the header through which the client reports its version, and the trailing backslash continues the command on the next line. The same resource is checked twice with different versions and different expectations — that is how you see the back end adapting to the old client. The checklist at the bottom is the minimum worth going through before every API release.
💡 Простими словами: новий реліз не повинен ламати тих, хто не оновився, — а таких завжди більше, ніж здається.
💡 In plain words: a new release must not break people who haven't updated — and there are always more of them than you think.
🗣 Як читати вголос Першим ділом я питаю, які версії застосунку реально живі і в якої частки користувачів, бо без цього неможливо визначити обсяг. Потім проходжу диф контракту: видалене чи перейменоване поле, новий обов'язковий параметр або нове значення енаму — це червоні прапорці. Для кожної живої версії в мене є набір запитів, і я ганяю їх проти нового бекенду, підставляючи заголовок версії. І ще я наполягаю на політиці підтримки: скажімо, три останні мінорні версії, щоб не сперечатися про це на кожному релізі.
🗣 How to say it out loud The first thing I ask is which app versions are really alive and for what share of users, because without that the scope can't be set. Then I go through the contract diff: a removed or renamed field, a new required parameter or a new enum value are red flags. For each live version I keep a set of requests and run them against the new back end, swapping the version header. I also push for a support policy — say the last three minor versions — so we don't argue about it every release.
▶ 3 9
29 Як розбити поле «Вік» (18–65) на класи еквівалентності і не забути про невалідні? How do you split an age field (18–65) into equivalence partitions without forgetting the invalid ones?
Тест-дизайнTest design Junior ▶

Що це. Еквівалентне розбиття (equivalence partitioning, EP) ділить усі можливі вхідні значення на класи (партиції), всередині яких система, за нашим припущенням, поводиться однаково. З кожного класу достатньо одного представника: якщо 30 років приймається, то й 42 прийметься, бо обидва значення проходять через ту саму гілку логіки.

What it is. Equivalence partitioning (EP) splits every possible input value into partitions inside which, by our assumption, the system behaves the same way. One representative per partition is enough: if age 30 is accepted, 42 will be accepted too, because both values go through the same branch of logic.

Навіщо. Поле віку технічно приймає тисячі рядків. EP перетворює цей нескінченний простір на п'ять-сім перевірок і водночас гарантує, що жоден тип поведінки не залишився без тесту. Це прямий наслідок принципу «вичерпне тестування неможливе».

Why it matters. An age field technically accepts thousands of strings. EP turns that endless space into five to seven checks while making sure no kind of behaviour goes untested. It is a direct consequence of the principle that exhaustive testing is impossible.

Приклад. Вимога: «Вік — ціле число від 18 до 65 включно». Валідний клас один: 18–65. Невалідних більше: менше 18, більше 65, дробове число (18.5), літери («abc»), порожнє поле, самі пробіли. Кожен невалідний клас перевіряю окремим тестом, щоб одна помилка валідації не маскувала іншу.

Example. Requirement: "Age is an integer from 18 to 65 inclusive". There is one valid partition: 18–65. There are more invalid ones: below 18, above 65, a decimal (18.5), letters ("abc"), an empty field, only spaces. I test each invalid partition separately so that one validation error cannot mask another.

Підводні камені. Найчастіше забувають класи за типом і порожнє значення, бо думають лише про числову вісь. Друга помилка — об'єднати кілька невалідних значень в одному тесті: форма покаже першу помилку, а решту ти так і не перевіриш. І EP спирається на припущення про однакову поведінку, тож межі класів потім обов'язково добиваю аналізом граничних значень.

Pitfalls. People most often forget the type-based partitions and the empty value because they only think about the number line. The second mistake is combining several invalid values in one test: the form shows the first error and you never check the rest. And EP relies on an assumption of identical behaviour, so I always follow up the partition edges with boundary value analysis.

Класи еквівалентності для поля «Вік»
Equivalence partitions for the Age field
# Вимога: ціле число 18..65 включно
Клас          Тип        Представник  Очікування
EP1 18..65    валідний   30           прийнято
EP2 < 18      невалідний 10           «Мінімум 18»
EP3 > 65      невалідний 70           «Максимум 65»
EP4 дробове   невалідний 18.5         «Лише ціле число»
EP5 літери    невалідний abc          «Лише цифри»
EP6 порожнє   невалідний (пусто)      «Обов'язкове поле»
EP7 пробіли   невалідний (3 пробіли)  «Обов'язкове поле»
# Requirement: integer 18..65 inclusive
Partition     Type       Value        Expected
EP1 18..65    valid      30           accepted
EP2 < 18      invalid    10           "Minimum is 18"
EP3 > 65      invalid    70           "Maximum is 65"
EP4 decimal   invalid    18.5         "Whole number only"
EP5 letters   invalid    abc          "Digits only"
EP6 empty     invalid    (empty)      "Required field"
EP7 spaces    invalid    (3 spaces)   "Required field"
🔧 Як читати: кожен рядок — окремий клас і один тест. EP1 — єдиний валідний клас, EP2 і EP3 лежать на числовій осі по обидва боки, EP4–EP7 — класи за типом і відсутністю значення. Тексти помилок у стовпці «Очікування» беруться з вимог або макета; якщо їх там немає, це питання до аналітика ще до виконання.
🔧 How to read it: each row is a separate partition and one test. EP1 is the only valid partition, EP2 and EP3 sit on either side of the number line, and EP4–EP7 are partitions by type and by missing value. The error texts in the Expected column come from the requirements or the mock-up; if they are not there, that is a question for the analyst before execution.
💡 Простими словами: одне значення з кожної «кімнати» поведінки, і окрема кімната для всього, що взагалі не число.
💡 In plain words: one value from each "room" of behaviour, plus separate rooms for everything that is not a number at all.
🗣 Як читати вголос Я беру вимогу, скажімо вік від вісімнадцяти до шістдесяти п'яти, і питаю себе: скільки тут різних реакцій системи? Прийняла — це один клас. Відмовила, бо замало, бо забагато, бо не ціле, бо літери, бо порожньо — це вже кілька різних невалідних класів. З кожного беру одне значення, а невалідні ніколи не змішую в одному тесті, інакше побачу лише першу помилку. Після цього обов'язково дивлюсь на межі, бо сама EP їх не ловить.
🗣 How to say it out loud I take the requirement, say age eighteen to sixty-five, and ask myself how many different reactions the system has. Accepted is one partition. Rejected because too young, too old, not whole, letters, or empty — those are several distinct invalid partitions. I pick one value from each, and I never mix invalid values in one test, otherwise I only see the first error. After that I always look at the edges, because partitioning alone does not catch them.
30 Чим аналіз граничних значень на 2 значення відрізняється від варіанта на 3 значення для поля 1..100? How does two-value boundary value analysis differ from three-value BVA for a field that accepts 1..100?
Тест-дизайнTest design Junior ▶

Що це. Аналіз граничних значень (boundary value analysis, BVA) перевіряє значення на краях упорядкованих класів еквівалентності, бо саме там розробники помиляються з операторами порівняння. ISTQB CTFL 4.0 описує два варіанти. У 2-значному для кожної межі беремо саму межу і найближчого сусіда з іншого класу. У 3-значному — межу і обох сусідів.

What it is. Boundary value analysis (BVA) tests values at the edges of ordered equivalence partitions, because that is where developers get comparison operators wrong. ISTQB CTFL 4.0 describes two variants. In two-value BVA, for each boundary you take the boundary itself and its closest neighbour from the other partition. In three-value BVA you take the boundary and both neighbours.

Навіщо і коли. Для поля 1..100 двозначний варіант дає 0, 1, 100, 101 — чотири тести. Тризначний дає 0, 1, 2, 99, 100, 101 — шість. Додаткові значення 2 і 99 ловлять помилку, коли замість x >= 1 написано x == 1 або межу зсунуто всередину класу. Тризначний варіант беру для грошей, лімітів і всього ризикового, двозначний — для рядових полів.

Why and when. For a 1..100 field the two-value variant gives 0, 1, 100, 101 — four tests. The three-value variant gives 0, 1, 2, 99, 100, 101 — six. The extra values 2 and 99 catch a bug where x == 1 was written instead of x >= 1, or where the boundary was shifted inside the partition. I use three-value for money, limits and anything risky, two-value for ordinary fields.

Приклад. Кількість товару в кошику: 1..100. Розробник написав qty > 1 && qty <= 100. Тест зі значенням 1 падає — одиниця не приймається, хоча має. Значення 50 з класу EP цей баг ніколи б не знайшло.

Example. Cart quantity: 1..100. The developer wrote qty > 1 && qty <= 100. The test with value 1 fails — one item is rejected although it should be allowed. The value 50 from the EP partition would never have found this bug.

Підводні камені. Популярна схема «Min, Min+1, Nominal, Max-1, Max» — це не BVA з CTFL: вона не містить значень за межами (0 і 101), а «номінальне» значення насправді належить до EP. Друга пастка — забути крок: для ціни з копійками сусід межі 1.00 — це 0.99, а не 0.

Pitfalls. The popular scheme "Min, Min+1, Nominal, Max-1, Max" is not the CTFL BVA: it leaves out the values outside the range (0 and 101), and the "nominal" value really belongs to EP. Another trap is forgetting the step: for a price with cents the neighbour of the 1.00 boundary is 0.99, not 0.

BVA для поля 1..100: два варіанти
BVA for a 1..100 field: two variants
Значення  Клас         2-значний  3-значний  Очікування
0         < 1          так        так        відхилено
1         межа min     так        так        прийнято
2         всередині    —          так        прийнято
99        всередині    —          так        прийнято
100       межа max     так        так        прийнято
101       > 100        так        так        відхилено
Разом тестів:           4          6
Value     Partition    2-value    3-value    Expected
0         < 1          yes        yes        rejected
1         min edge     yes        yes        accepted
2         inside       —          yes        accepted
99        inside       —          yes        accepted
100       max edge     yes        yes        accepted
101       > 100        yes        yes        rejected
Total tests:            4          6
🔧 Як читати: стовпці «2-значний» і «3-значний» показують, чи входить значення в набір відповідного варіанта. Межі 1 і 100 та зовнішні сусіди 0 і 101 є в обох; внутрішні сусіди 2 і 99 додає лише тризначний. Номінальне значення на кшталт 50 тут не потрібне — його вже дав клас еквівалентності.
🔧 How to read it: the "2-value" and "3-value" columns show whether a value belongs to that variant's set. The boundaries 1 and 100 and the outer neighbours 0 and 101 are in both; only the three-value variant adds the inner neighbours 2 and 99. A nominal value like 50 is not needed here — equivalence partitioning has already supplied it.
💡 Простими словами: баги живуть на краях. Два значення — межа і крок за нею; три — ще й крок усередину.
💡 In plain words: bugs live on the edges. Two values means the edge and one step outside; three adds one step inside.
🗣 Як читати вголос Для поля від одного до ста я завжди спершу називаю дві межі, один і сто. У двозначному варіанті беру межу та сусіда ззовні — виходить нуль, один, сто, сто один. У тризначному додаю ще сусідів зсередини, тобто два і дев'яносто дев'ять, це шість тестів. Тризначний я обираю там, де помилка коштує грошей, бо він ловить випадок, коли в коді рівність замість «більше або дорівнює». І одразу уточнюю крок: для цін із копійками сусідом одиниці буде нуль дев'яносто дев'ять.
🗣 How to say it out loud For a field from one to a hundred I always name the two boundaries first, one and a hundred. In the two-value variant I take each boundary and its outside neighbour, so zero, one, a hundred, a hundred and one. In three-value I also add the inside neighbours, two and ninety-nine, which makes six tests. I pick three-value where a mistake costs money, because it catches code that uses equality instead of greater-or-equal. And I check the step right away: with prices in cents, the neighbour of one is zero point ninety-nine.
31 Як поєднати EP і BVA на прикладі пароля 6–20 символів з обов'язковою цифрою? How do you combine EP and BVA for a 6–20 character password that must contain a digit?
Тест-дизайнTest design Middle ▶

Що це. На практиці техніки не живуть окремо. Для пароля з правилом «6–20 символів, щонайменше одна літера й одна цифра» довжина — це впорядкований діапазон (там працює BVA), а склад символів — неупорядковані класи (там працює EP). Разом вони дають компактний набір, де кожен рядок перевіряє одну причину відмови.

What it is. In practice the techniques do not live apart. For a password with the rule "6–20 characters, at least one letter and one digit", length is an ordered range (BVA applies there), while the character mix forms unordered partitions (EP applies there). Together they give a compact set where each row checks one reason for rejection.

Навіщо. Якщо тестувати лише довжину, пропустиш пароль «password» без цифри. Якщо лише склад — пропустиш помилку length > 6, через яку шестисимвольний пароль відхиляється. Комбінація закриває обидва ризики і дає інтерв'юеру побачити, що ти мислиш моделлю, а не набором випадкових значень.

Why it matters. If you only test length, you miss "password" with no digit. If you only test the character mix, you miss a length > 6 bug that rejects a six-character password. The combination covers both risks and shows the interviewer that you think in a model rather than in random values.

Приклад. Значення довжини для BVA: 5, 6, 20, 21. Кожне валідне за довжиною значення будую так, щоб воно було валідним і за складом, — тоді відмова може статися лише через довжину. Для класів складу беру довжину з середини діапазону (8), щоб межі не втручались.

Example. Length values for BVA: 5, 6, 20, 21. I build every length-valid value so that it is also valid by character mix — then a rejection can only come from length. For the character partitions I use a length from the middle of the range (8) so the boundaries do not interfere.

Підводні камені. Вимога мовчить про пробіли, кирилицю, емодзі й те, як рахується довжина (символи чи байти). Це не «тестую на свій розсуд», а питання до аналітика, які я записую до виконання. Також перевіряю, що фронтенд і бекенд валідують однаково: відправка запиту в обхід форми часто показує, що сервер приймає 3 символи.

Pitfalls. The requirement says nothing about spaces, Cyrillic, emoji or how length is counted (characters or bytes). That is not "I test as I see fit" but a question for the analyst that I write down before execution. I also check that the front end and the back end validate the same way: sending the request around the form often shows the server happily accepts 3 characters.

Набір тестових даних для пароля
Test data set for the password
# Правило: 6..20 символів, ≥1 літера, ≥1 цифра
#  Значення                   Довж.  Техніка    Очікування
1  abcd1                      5      BVA        «Мінімум 6»
2  abcde1                     6      BVA        прийнято
3  abcdefghij1234567890       20     BVA        прийнято
4  abcdefghij1234567890k      21     BVA        «Максимум 20»
5  password                   8      EP         «Потрібна цифра»
6  12345678                   8      EP         «Потрібна літера»
7  (порожньо)                 0      EP         «Обов'язкове поле»
# Відкриті питання: пробіли? кирилиця? емодзі?
# Rule: 6..20 chars, ≥1 letter, ≥1 digit
#  Value                      Len    Technique  Expected
1  abcd1                      5      BVA        "Minimum 6"
2  abcde1                     6      BVA        accepted
3  abcdefghij1234567890       20     BVA        accepted
4  abcdefghij1234567890k      21     BVA        "Maximum 20"
5  password                   8      EP         "Digit required"
6  12345678                   8      EP         "Letter required"
7  (empty)                    0      EP         "Required field"
# Open questions: spaces? Cyrillic? emoji?
🔧 Як читати: рядки 1–4 — двозначний BVA по довжині (5 і 21 за межами, 6 і 20 — самі межі), і кожен із них містить і літери, і цифру, тож відмова пояснюється тільки довжиною. Рядки 5–6 — класи складу при безпечній довжині 8. Рядок 7 — порожнє значення, окремий клас. Останній коментар фіксує прогалини у вимозі.
🔧 How to read it: rows 1–4 are two-value BVA on length (5 and 21 outside, 6 and 20 are the boundaries), and each of them contains both letters and a digit, so a rejection can only be explained by length. Rows 5–6 are the character-mix partitions at a safe length of 8. Row 7 is the empty value, a separate partition. The last comment records the gaps in the requirement.
💡 Простими словами: одне правило — один рядок відмови. Решта значення має бути «чистою», щоб причина падіння була однозначною.
💡 In plain words: one rule, one rejection row. The rest of the value must be "clean" so the reason for failure is unambiguous.
🗣 Як читати вголос Пароль я розбираю на дві осі. Довжина впорядкована, тому там граничні значення: п'ять, шість, двадцять, двадцять один. Склад символів — це класи: немає цифри, немає літери, порожньо. Головне правило в мене таке: у кожному тесті ламається рівно одна умова, а все інше валідне, інакше не зрозуміло, чому саме відмовили. І перед виконанням я виписую питання, про які вимога мовчить, — пробіли, кирилиця, емодзі — та ще окремо перевіряю бекенд в обхід форми.
🗣 How to say it out loud I split a password into two axes. Length is ordered, so that is where boundary values go: five, six, twenty, twenty-one. The character mix is partitions: no digit, no letter, empty. My main rule is that exactly one condition breaks in each test and everything else stays valid, otherwise you cannot tell why it was rejected. Before running anything I list what the requirement is silent about — spaces, Cyrillic, emoji — and I also hit the back end directly, bypassing the form.
32 Як побудувати таблицю рішень для знижки з трьома умовами і скоротити її без втрати покриття? How do you build a decision table for a discount with three conditions and collapse it without losing coverage?
Тест-дизайнTest design Middle ▶

Що це. Таблиця рішень описує бізнес-правило, де результат залежить від комбінації умов. Рядки зверху — умови (так/ні), рядки знизу — дії, а кожен стовпець — одне правило, тобто один тест. Для n бінарних умов повна таблиця має 2ⁿ стовпців: три умови дають вісім правил.

What it is. A decision table describes a business rule whose outcome depends on a combination of conditions. The top rows are conditions (yes/no), the bottom rows are actions, and each column is one rule, meaning one test. For n binary conditions the full table has 2ⁿ columns: three conditions give eight rules.

Навіщо. Текстові вимоги про знижки майже завжди неповні: «зареєстрованим 5% від 1000 грн, промокод дає 15%». А що, якщо є і те, і те? Таблиця змушує заповнити кожну клітинку, тому прогалини у вимогах видно ще до написання коду, — це й статичне тестування, і дизайн тестів водночас.

Why it matters. Written discount requirements are almost always incomplete: "registered users get 5% from 1000 UAH, a promo code gives 15%". What if both apply? The table forces you to fill every cell, so gaps in the requirements show up before any code is written — it is static testing and test design at the same time.

Приклад. Умови: C1 — користувач зареєстрований, C2 — сума від 1000 грн, C3 — промокод валідний. Правило бізнесу, яке ми уточнили з PO: знижки не сумуються, промокод 15% завжди перемагає, лояльність 5% діє лише для C1 і C2 без промокоду. Повна таблиця — 8 стовпців. Далі скорочую: коли C3 = так, результат не залежить від C1 і C2, тож чотири стовпці зливаються в один із «—» (байдуже).

Example. Conditions: C1 — the user is registered, C2 — the total is 1000 UAH or more, C3 — the promo code is valid. The business rule we clarified with the PO: discounts do not stack, the 15% promo always wins, and the 5% loyalty discount applies only for C1 and C2 without a promo code. The full table has 8 columns. Then I collapse it: when C3 = yes the outcome does not depend on C1 and C2, so four columns merge into one with "—" (don't care).

Підводні камені. Скорочувати можна лише тоді, коли ти довів, що умова справді не впливає; інакше втратиш тест, який ловив баг. Ризикові правила (гроші) я часто залишаю повною таблицею. І не забуваю про неможливі комбінації — їх позначаю, а не мовчки викидаю.

Pitfalls. You may only collapse when you have shown that a condition really has no effect; otherwise you drop the very test that would catch the bug. For risky rules involving money I often keep the full table. And I do not forget impossible combinations — I mark them rather than silently drop them.

Повна і скорочена таблиця рішень
Full and collapsed decision table
# Повна таблиця: 2^3 = 8 правил
                        R1 R2 R3 R4 R5 R6 R7 R8
C1 зареєстрований        Т  Т  Т  Т  Н  Н  Н  Н
C2 сума >= 1000          Т  Т  Н  Н  Т  Т  Н  Н
C3 промокод валідний     Т  Н  Т  Н  Т  Н  Т  Н
A1 знижка 15% (промо)    X  .  X  .  X  .  X  .
A2 знижка 5% (лояльн.)   .  X  .  .  .  .  .  .
A3 без знижки            .  .  .  X  .  X  .  X

# Скорочена: 4 правила, покриття те саме
                        S1 S2 S3 S4
C1 зареєстрований        —  Т  Т  Н
C2 сума >= 1000          —  Т  Н  —
C3 промокод валідний     Т  Н  Н  Н
Дія                     15% 5% 0% 0%
# Full table: 2^3 = 8 rules
                        R1 R2 R3 R4 R5 R6 R7 R8
C1 registered            Y  Y  Y  Y  N  N  N  N
C2 total >= 1000         Y  Y  N  N  Y  Y  N  N
C3 promo code valid      Y  N  Y  N  Y  N  Y  N
A1 15% discount (promo)  X  .  X  .  X  .  X  .
A2 5% discount (loyalty) .  X  .  .  .  .  .  .
A3 no discount           .  .  .  X  .  X  .  X

# Collapsed: 4 rules, same coverage
                        S1 S2 S3 S4
C1 registered            —  Y  Y  N
C2 total >= 1000         —  Y  N  —
C3 promo code valid      Y  N  N  N
Action                  15% 5% 0% 0%
🔧 Як читати: Т/Н — умова виконана чи ні, X — дія спрацьовує, крапка — ні. У скороченій таблиці «—» означає «байдуже»: S1 поглинає R1, R3, R5, R7, бо з валідним промокодом решта умов не важить. S2 = R2, S3 = R4, а S4 поглинає R6 і R8 (незареєстрованому лояльність не світить за будь-якої суми).
🔧 How to read it: Y/N — the condition holds or not, X — the action fires, a dot — it does not. In the collapsed table "—" means "don't care": S1 absorbs R1, R3, R5 and R7, because with a valid promo code the other conditions do not matter. S2 = R2, S3 = R4, and S4 absorbs R6 and R8 (an unregistered user never gets loyalty, whatever the total).
💡 Простими словами: спершу виписую всі комбінації, щоб нічого не загубити, і лише потім зливаю ті, де результат однаковий.
💡 In plain words: first write out every combination so nothing is lost, and only then merge the ones with the same outcome.
🗣 Як читати вголос Коли бачу вимогу з кількома «якщо», я малюю таблицю рішень. Три умови — зареєстрований, сума від тисячі, валідний промокод — дають вісім стовпців, і кожен стовпець у мене стає тестом. Найцінніше відбувається ще до тестування: заповнюючи таблицю, я натрапляю на питання «а якщо і промокод, і лояльність», і йду з ним до продакт-оунера. Потім скорочую, але тільки там, де умова доведено нічого не змінює. Для грошових правил часто лишаю всі вісім.
🗣 How to say it out loud Whenever a requirement has several "ifs", I draw a decision table. Three conditions — registered, total over a thousand, valid promo code — give eight columns, and each column becomes a test. The most valuable part happens before testing: while filling the table I run into the question of what happens with both a promo code and loyalty, and I take it to the product owner. Then I collapse it, but only where a condition provably changes nothing. For money rules I often keep all eight.
33 Які переходи статусів замовлення перевіряти технікою переходів станів і як знайти невалідні? Which order status transitions do you check with state transition testing, and how do you find the invalid ones?
Тест-дизайнTest design Middle ▶

Що це. Тестування переходів станів моделює об'єкт як скінченний автомат: стани, події, що їх змінюють, і дозволені переходи. Воно підходить усюди, де поведінка залежить від історії: замовлення, заявка, підписка, обліковий запис після трьох невдалих входів.

What it is. State transition testing models an object as a finite state machine: states, the events that change them, and the allowed transitions. It fits anywhere behaviour depends on history: an order, a request, a subscription, an account after three failed logins.

Навіщо. Діаграма дає два набори тестів. Перший — валідні переходи: покриття всіх переходів (0-switch coverage у CTFL) вимагає пройти кожну стрілку хоча б раз. Другий — невалідні переходи: пари станів без стрілки, які система має відхилити. Саме тут ховаються дорогі баги на кшталт скасування вже доставленого замовлення з поверненням грошей.

Why it matters. The diagram yields two sets of tests. The first is valid transitions: all-transitions coverage (0-switch coverage in CTFL) requires exercising every arrow at least once. The second is invalid transitions: state pairs with no arrow, which the system must reject. That is where costly bugs hide, such as cancelling an already delivered order and refunding the money.

Приклад. Замовлення має стани pending, paid, shipped, delivered, cancelled. Скасувати можна лише з pending (без оплати) або з paid (з поверненням коштів). Після відправлення скасування немає, а доставлене замовлення повертається окремим процесом «повернення», а не переходом у cancelled. П'ять станів дають 5 × 4 = 20 впорядкованих пар; валідних переходів п'ять, отже невалідних п'ятнадцять.

Example. An order has the states pending, paid, shipped, delivered, cancelled. It can be cancelled only from pending (no payment yet) or from paid (with a refund). There is no cancellation after shipping, and a delivered order goes back through a separate "return" flow, not a transition to cancelled. Five states give 5 × 4 = 20 ordered pairs; five transitions are valid, so fifteen are invalid.

Підводні камені. Невалідні переходи перевіряють не лише через UI, де кнопки просто сховані, а й через API: PATCH /orders/42 зі статусом cancelled для доставленого замовлення має отримати 409 або 422. Також не плутай стан зі сторінкою інтерфейсу — один екран може показувати кілька станів.

Pitfalls. Invalid transitions are checked not only through the UI, where the buttons are simply hidden, but also through the API: PATCH /orders/42 with status cancelled for a delivered order must get a 409 or 422. Also, do not confuse a state with a UI page — one screen may display several states.

Діаграма станів і невалідні переходи
State diagram and invalid transitions
            оплата            відправка          доставка
[pending] ---------> [paid] ----------> [shipped] ---------> [delivered]
    |                  |
    | скасування       | скасування + повернення коштів
    v                  v
  [cancelled] <--------+

# Валідні (5): pending→paid, paid→shipped, shipped→delivered,
#              pending→cancelled, paid→cancelled

# Невалідні для тестів (вибірка з 15), очікування: відмова
Звідки      Куди        Чому ризиково
delivered   cancelled   гроші повертаються за отриманий товар
shipped     cancelled   товар у дорозі, склад не знає
pending     shipped     відправка без оплати
cancelled   paid        оплата скасованого замовлення
cancelled   shipped     відправка скасованого
delivered   pending     «відкат» закритого замовлення
            payment           dispatch           delivery
[pending] ---------> [paid] ----------> [shipped] ---------> [delivered]
    |                  |
    | cancel           | cancel + refund
    v                  v
  [cancelled] <--------+

# Valid (5): pending→paid, paid→shipped, shipped→delivered,
#            pending→cancelled, paid→cancelled

# Invalid ones to test (sample of 15), expected: rejected
From        To          Why it is risky
delivered   cancelled   money refunded for goods received
shipped     cancelled   goods in transit, warehouse unaware
pending     shipped     dispatch without payment
cancelled   paid        payment for a cancelled order
cancelled   shipped     shipping a cancelled order
delivered   pending     "rollback" of a closed order
🔧 Як читати: квадратні дужки — стани, стрілки з підписом — події, що викликають перехід. Від delivered і shipped стрілок до cancelled немає, тому це невалідні переходи. Таблиця знизу — найризиковіші з п'ятнадцяти невалідних пар; решту (наприклад, paid→pending) додаю, якщо дозволяє час.
🔧 How to read it: square brackets are states, labelled arrows are the events that cause a transition. There are no arrows from delivered or shipped to cancelled, so those are invalid transitions. The table at the bottom lists the riskiest of the fifteen invalid pairs; I add the rest (for instance paid→pending) when time allows.
💡 Простими словами: кожна стрілка — тест «має спрацювати», кожна відсутня стрілка — тест «має відмовити».
💡 In plain words: every arrow is a "must work" test, every missing arrow is a "must refuse" test.
🗣 Як читати вголос Коли в об'єкта є статуси, я малюю діаграму станів. Для замовлення це pending, paid, shipped, delivered і cancelled, причому скасувати можна лише неоплачене або оплачене, але ще не відправлене. Спершу проходжу кожну стрілку — це покриття переходів. Потім беру пари, між якими стрілки немає, і перевіряю, що система їх відхиляє, причому не лише в інтерфейсі, а й прямим запитом до API. Найбільше мене турбує скасування доставленого замовлення, бо це прямі втрати грошей.
🗣 How to say it out loud When an object has statuses, I draw a state diagram. For an order that is pending, paid, shipped, delivered and cancelled, and you can cancel only an unpaid order or a paid one that has not shipped. First I walk every arrow — that is transition coverage. Then I take the pairs with no arrow between them and check that the system refuses them, not only in the UI but also with a direct API call. What worries me most is cancelling a delivered order, because that is money lost directly.
34 Як попарне тестування скорочує 36 комбінацій конфігурацій до 9 і де воно не допоможе? How does pairwise testing cut 36 configuration combinations down to 9, and where does it not help?
Тест-дизайнTest design Middle ▶

Що це. Попарне (pairwise, all-pairs) тестування — комбінаторна техніка, яка гарантує, що кожна пара значень будь-яких двох параметрів трапиться хоча б в одному тесті. Повний перебір не потрібен, бо на практиці більшість дефектів конфігурацій виникає від взаємодії одного-двох параметрів, а не всіх одразу.

What it is. Pairwise (all-pairs) testing is a combinatorial technique that guarantees every pair of values of any two parameters appears in at least one test. You do not need the full product, because in practice most configuration defects are triggered by one or two interacting parameters rather than all of them at once.

Навіщо. Чекаут перевіряємо на 3 браузерах, 3 ОС, 2 мовах інтерфейсу і 2 способах оплати. Повний перебір — 3 × 3 × 2 × 2 = 36 прогонів. Мінімум для попарного покриття визначає добуток двох найбільших параметрів: 3 × 3 = 9. Тобто вчетверо менше роботи при збереженні всіх пар.

Why it matters. We check a checkout on 3 browsers, 3 operating systems, 2 UI languages and 2 payment methods. The full product is 3 × 3 × 2 × 2 = 36 runs. The minimum for pairwise coverage is set by the product of the two largest parameters: 3 × 3 = 9. That is a quarter of the work while keeping every pair.

Приклад. Таблицю нижче я склав вручну і перевірив: кожна пара браузер–ОС трапляється рівно раз, а пари з мовою та оплатою — щонайменше раз. На реальних проєктах таблицю генерують інструментом, наприклад Microsoft PICT, куди ще й додають обмеження на кшталт «Edge лише з Windows».

Example. I built the table below by hand and verified it: every browser–OS pair appears exactly once, and the pairs involving language and payment appear at least once. On real projects the table is generated by a tool such as Microsoft PICT, where you can also add constraints like "Edge only with Windows".

Підводні камені. Pairwise не знайде дефект, що проявляється лише на трійці значень, тож для критичних комбінацій (найпопулярніша платформа за аналітикою) додаю тести явно. Друга пастка — нереальні комбінації (Safari на Linux): без обмежень генератор їх видасть. І техніка працює для незалежних параметрів, а не для бізнес-правил, де краще таблиця рішень.

Pitfalls. Pairwise will not find a defect that only shows up for a specific triple of values, so for critical combinations (the most popular platform in analytics) I add tests explicitly. The second trap is unrealistic combinations (Safari on Linux): without constraints the generator will produce them. And the technique is for independent parameters, not for business rules, where a decision table is better.

Попарна таблиця: 9 прогонів замість 36
Pairwise table: 9 runs instead of 36
# Браузер(3) × ОС(3) × Мова(2) × Оплата(2) = 36
#  Браузер  ОС       Мова  Оплата
1  Chrome   Windows  uk    картка
2  Chrome   macOS    en    PayPal
3  Chrome   Ubuntu   uk    PayPal
4  Firefox  Windows  en    PayPal
5  Firefox  macOS    uk    картка
6  Firefox  Ubuntu   en    картка
7  Edge     Windows  uk    PayPal
8  Edge     macOS    en    картка
9  Edge     Ubuntu   en    PayPal
# Перевірка: мова×оплата — uk/картка(1,5) uk/PayPal(3,7)
#            en/картка(6,8) en/PayPal(2,4,9)
# Browser(3) × OS(3) × Language(2) × Payment(2) = 36
#  Browser  OS       Lang  Payment
1  Chrome   Windows  uk    card
2  Chrome   macOS    en    PayPal
3  Chrome   Ubuntu   uk    PayPal
4  Firefox  Windows  en    PayPal
5  Firefox  macOS    uk    card
6  Firefox  Ubuntu   en    card
7  Edge     Windows  uk    PayPal
8  Edge     macOS    en    card
9  Edge     Ubuntu   en    PayPal
# Check: lang×payment — uk/card(1,5) uk/PayPal(3,7)
#        en/card(6,8) en/PayPal(2,4,9)
🔧 Як читати: кожен рядок — один прогін. Візьми будь-які два стовпці: усі можливі пари їхніх значень знайдуться хоча б в одному рядку. Наприклад, Firefox + PayPal є в рядку 4, Ubuntu + картка — у рядку 6. Коментар унизу показує ручну перевірку найменш очевидної пари параметрів — мова з оплатою.
🔧 How to read it: each row is one run. Take any two columns: every possible pair of their values appears in at least one row. For example, Firefox + PayPal is in row 4, Ubuntu + card is in row 6. The comment at the bottom shows the manual check of the least obvious parameter pair — language with payment.
💡 Простими словами: не всі комбінації, а всі пари. Трійки й важливі платформи додаю руками.
💡 In plain words: not every combination, but every pair. Triples and key platforms I add by hand.
🗣 Як читати вголос Коли параметрів конфігурації багато, повний перебір швидко вибухає: три браузери, три системи, дві мови і дві оплати — вже тридцять шість прогонів. Я використовую pairwise: беру набір, у якому кожна пара значень зустрічається хоча б раз, і тут це дев'ять прогонів. Генерую його інструментом на кшталт PICT і одразу задаю обмеження, щоб не отримати Safari на Linux. Але я чесно кажу, що трійкові дефекти ця техніка може пропустити, тому найпопулярнішу за аналітикою конфігурацію додаю окремо.
🗣 How to say it out loud With many configuration parameters the full product blows up fast: three browsers, three systems, two languages and two payments are already thirty-six runs. I use pairwise: a set where every pair of values appears at least once, which here is nine runs. I generate it with a tool like PICT and set constraints straight away so I do not get Safari on Linux. But I am honest that this technique can miss three-way defects, so I add the most popular configuration from analytics separately.
35 Як вивести тести з юз-кейсу «Відновлення пароля», щоб покрити основний, альтернативні й виняткові потоки? How do you derive tests from a "Reset password" use case to cover the main, alternative and exception flows?
Тест-дизайнTest design Middle ▶

Що це. Юз-кейс описує взаємодію актора з системою заради конкретної мети: передумови, основний (успішний) потік, альтернативні потоки, що теж ведуть до мети іншим шляхом, і виняткові потоки, де мета не досягається. Тестування на основі юз-кейсів перетворює кожен потік на щонайменше один наскрізний тест.

What it is. A use case describes an actor's interaction with the system to reach a specific goal: preconditions, the main (happy) flow, alternative flows that also reach the goal by another route, and exception flows where the goal is not reached. Use case testing turns every flow into at least one end-to-end test.

Навіщо. Техніки на кшталт EP дивляться на одне поле, а юз-кейс — на весь сценарій очима користувача. Так знаходяться дефекти інтеграції кроків: посилання приходить, але веде на 404; пароль змінено, але старі сесії залишились активними. Такі тести також добре лягають у системне тестування та UAT.

Why it matters. Techniques like EP look at one field, whereas a use case looks at the whole scenario through the user's eyes. That is how you find defects in the way steps fit together: the link arrives but leads to a 404; the password is changed but old sessions stay active. Such tests also fit naturally into system testing and UAT.

Приклад. Основний потік: користувач натискає «Забули пароль», вводить email, отримує лист, відкриває посилання, задає новий пароль, система підтверджує і завершує інші сесії. Альтернатива 2a: email не зареєстрований — система показує той самий нейтральний текст, щоб не розкрити, які адреси існують. Винятки: 4a посилання прострочене (у нашій вимозі 30 хв), 4b посилання вже використане, 5a новий пароль не проходить політику.

Example. Main flow: the user clicks "Forgot password", enters an email, receives a message, opens the link, sets a new password, and the system confirms and ends other sessions. Alternative 2a: the email is not registered — the system shows the same neutral text so it does not reveal which addresses exist. Exceptions: 4a the link has expired (30 min in our requirement), 4b the link has already been used, 5a the new password fails the policy.

Підводні камені. Покриття лише основного потоку — найчастіша помилка: найцікавіші дефекти сидять у винятках. Також юз-кейси часто мовчать про паралельні дії (два запити на відновлення поспіль — чи діє перше посилання?). Такі питання я додаю в тест як окремий рядок і уточнюю очікування.

Pitfalls. Covering only the main flow is the most common mistake: the most interesting defects sit in the exceptions. Use cases are also often silent about concurrent actions (two reset requests in a row — does the first link still work?). I add such questions as a separate row and clarify the expected result.

Юз-кейс і похідні тести
Use case and derived tests
UC-07 Відновлення пароля  Актор: зареєстрований користувач
Основний потік
  1 «Забули пароль»  2 ввести email  3 лист із посиланням
  4 відкрити посилання  5 новий пароль  6 успіх, інші сесії завершено
Альтернатива 2a  email не існує → той самий нейтральний текст
Винятки  4a посилання > 30 хв   4b посилання вже використане
         5a пароль не проходить політику

Тест    Потік  Очікування
TC-01   1–6    вхід новим паролем, старий не діє
TC-02   2a     текст як у TC-01, лист не надсилається
TC-03   4a     «Посилання застаріло», кнопка «Надіслати знову»
TC-04   4b     «Посилання вже використано»
TC-05   5a     помилка політики, пароль не змінено
TC-06   ?      два запити поспіль: чи діє перше посилання?
UC-07 Reset password   Actor: registered user
Main flow
  1 "Forgot password"  2 enter email  3 email with link
  4 open link  5 new password  6 success, other sessions ended
Alternative 2a  email unknown → same neutral text
Exceptions  4a link older than 30 min   4b link already used
            5a password fails the policy

Test    Flow   Expected
TC-01   1–6    login with new password, old one rejected
TC-02   2a     same text as TC-01, no email sent
TC-03   4a     "Link expired", "Send again" button
TC-04   4b     "Link already used"
TC-05   5a     policy error, password unchanged
TC-06   ?      two requests in a row: is the first link valid?
🔧 Як читати: верхня частина — сам юз-кейс із пронумерованими кроками; номер альтернативи чи винятку (2a, 4a) показує, на якому кроці потік відгалужується. Нижня частина — тести, де стовпець «Потік» дає трасування до юз-кейсу. TC-06 позначено «?», бо очікування ще треба узгодити.
🔧 How to read it: the top part is the use case itself with numbered steps; the number of an alternative or exception (2a, 4a) shows at which step the flow branches off. The bottom part lists the tests, and the Flow column traces each one back to the use case. TC-06 is marked "?" because its expected result still has to be agreed.
💡 Простими словами: кожна гілка сценарію — окремий тест, і гілки «щось пішло не так» важливіші за щасливий шлях.
💡 In plain words: every branch of the scenario is its own test, and the "something went wrong" branches matter more than the happy path.
🗣 Як читати вголос Юз-кейс для мене — готова карта сценаріїв. Основний потік відновлення пароля даю одним наскрізним тестом, а далі йду по гілках: невідомий email, прострочене посилання, вже використане посилання, слабкий новий пароль. На кожну гілку — щонайменше один тест, і я пишу в ньому номер кроку, щоб було видно трасування. Окремо думаю про те, чого в юз-кейсі нема, наприклад два запити поспіль, і з цим іду до аналітика, а не вигадую очікування сам.
🗣 How to say it out loud To me a use case is a ready-made map of scenarios. The main password-reset flow becomes one end-to-end test, and then I walk the branches: unknown email, expired link, a link that was already used, a weak new password. Each branch gets at least one test, and I note the step number so the traceability is visible. I also think about what the use case leaves out, like two requests in a row, and I take that to the analyst instead of inventing the expected result myself.
36 Як перетворити вгадування помилок на систематичну техніку на прикладі поля завантаження файлу? How do you turn error guessing into a systematic technique, using a file upload field as the example?
Тест-дизайнTest design Middle ▶

Що це. Вгадування помилок (error guessing) — техніка, заснована на досвіді: тестувальник передбачає, де розробник міг помилитись, спираючись на минулі дефекти, типові збої в подібних системах і знання технологій. У CTFL 4.0 її систематизована форма — атака на збої (fault attack): заздалегідь складений список можливих помилок, під який пишуться тести.

What it is. Error guessing is an experience-based technique: the tester anticipates where the developer may have gone wrong, drawing on past defects, typical failures in similar systems and knowledge of the technology. In CTFL 4.0 its systematic form is the fault attack: a list of likely faults prepared in advance, with tests written against it.

Навіщо. Формальні техніки покривають те, що написано у вимогах. Вгадування помилок ловить те, про що вимоги мовчать: файл нульового розміру, подвійне розширення, обрив мережі на середині. Воно найкраще працює як доповнення після EP і BVA, а не замість них.

Why it matters. Formal techniques cover what is written in the requirements. Error guessing catches what the requirements are silent about: a zero-byte file, a double extension, a network drop halfway through. It works best as an addition after EP and BVA, not as a replacement.

Приклад. Вимога: «аватар JPG або PNG до 5 МБ». EP і BVA дадуть типи файлів і межу 5 МБ. Мій список атак додає: файл .exe, перейменований на .jpg; розширення у верхньому регістрі .JPG; ім'я з пробілами, кирилицею і 200 символами; SVG з вбудованим скриптом; зображення 20000×20000 пікселів при малому розмірі файлу; повторне завантаження того самого файлу; скасування посередині.

Example. Requirement: "avatar in JPG or PNG up to 5 MB". EP and BVA give the file types and the 5 MB boundary. My attack list adds: an .exe renamed to .jpg; an upper-case .JPG extension; a name with spaces, Cyrillic and 200 characters; an SVG with an embedded script; a 20000×20000 pixel image with a small file size; uploading the same file twice; cancelling halfway.

Підводні камені. Без списку техніка залежить від настрою і досвіду конкретної людини, а результат не можна відтворити. Тому я веду командний чекліст атак і поповнюю його після кожного продакшн-інциденту. І не варто видавати вгадування помилок за повне покриття: воно не дає метрики на кшталт «усі класи перевірено».

Pitfalls. Without a list the technique depends on one person's mood and experience, and the result cannot be repeated. That is why I keep a team checklist of attacks and extend it after every production incident. And error guessing should not be presented as full coverage: it gives no metric like "all partitions checked".

Список атак для завантаження аватара
Attack list for an avatar upload
# Вимога: JPG/PNG, до 5 МБ
#   Атака                              Очікування
A1  0 байт, avatar.png                 зрозуміла помилка
A2  virus.exe → перейменовано .jpg     відхилено за вмістом
A3  PHOTO.JPG (верхній регістр)        прийнято
A4  фото профілю (1).png               прийнято, ім'я коректне
A5  ім'я довжиною 200 символів         прийнято або обрізано
A6  image.svg зі скриптом              відхилено
A7  20000×20000 px, 300 КБ             відхилено / без зависання
A8  той самий файл двічі               без дублікатів
A9  обрив мережі на 50%                повідомлення, повтор
# Джерело: інциденти INC-112, INC-140 + чекліст команди
# Requirement: JPG/PNG, up to 5 MB
#   Attack                             Expected
A1  0 bytes, avatar.png                clear error message
A2  virus.exe → renamed to .jpg        rejected by content
A3  PHOTO.JPG (upper case)             accepted
A4  my photo (1).png                   accepted, name intact
A5  200-character file name            accepted or truncated
A6  image.svg with a script            rejected
A7  20000×20000 px, 300 KB             rejected / no freeze
A8  same file twice                    no duplicates
A9  network drop at 50%                message, retry
# Source: incidents INC-112, INC-140 + team checklist
🔧 Як читати: кожен рядок — гіпотеза про конкретну помилку розробника та тест під неї. A2 перевіряє, що тип визначається за вмістом, а не за розширенням; A7 — так звану «декомпресійну бомбу», коли маленький файл розгортається в гігантське зображення. Останній рядок показує, звідки взято атаки, тож список можна відтворити й доповнити.
🔧 How to read it: each row is a hypothesis about a specific developer mistake plus the test for it. A2 checks that the type is detected by content rather than extension; A7 targets a so-called "decompression bomb", where a small file expands into a huge image. The last line shows where the attacks came from, so the list can be repeated and extended.
💡 Простими словами: досвід, записаний у чекліст, — це вже техніка; досвід у голові — це везіння.
💡 In plain words: experience written into a checklist is a technique; experience kept in your head is luck.
🗣 Як читати вголос Вгадування помилок я не роблю «на око». У мене є список атак, який росте після кожного інциденту. Для завантаження файлу, наприклад, я одразу перевіряю нульовий файл, exe під виглядом картинки, розширення великими літерами, дивні імена, SVG зі скриптом і обрив мережі посередині. Спочатку проходжу формальні техніки, тобто класи й межі, а вже потім цей список, бо він ловить саме те, про що вимога мовчить. І я не видаю це за повне покриття, це доповнення.
🗣 How to say it out loud I do not do error guessing by gut feeling. I have an attack list that grows after every incident. For a file upload, for instance, I go straight to an empty file, an exe disguised as a picture, an upper-case extension, odd file names, an SVG with a script, and a network drop halfway through. I run the formal techniques first, partitions and boundaries, and then this list, because it catches exactly what the requirement does not mention. And I never present it as full coverage — it is an addition.
37 Як обрати техніки тест-дизайну для форми бронювання готелю і вирішити, скільки тестів досить? How do you choose test design techniques for a hotel booking form and decide how many tests are enough?
Тест-дизайнTest design Senior ▶

Що це. Сеньйорське питання не про визначення технік, а про вибір: яку модель побудувати для кожної частини фічі і де зупинитись. Відповідь має показати, що техніка випливає зі структури вимоги (діапазон, комбінація правил, статуси, сценарій), а глибина — з ризику.

What it is. A senior question is not about defining techniques but about choosing: which model to build for each part of a feature and where to stop. The answer should show that the technique follows from the shape of the requirement (a range, a combination of rules, statuses, a scenario), while the depth follows from risk.

Навіщо. Одна фіча зазвичай містить усе одразу. У формі бронювання дати — діапазон з межами, кількість гостей — числа, тип номера і валюта — незалежні параметри, політика скасування — бізнес-правила, бронювання має статуси, а весь процес — наскрізний сценарій. Застосувати одну техніку до всього означає або роздути набір, або пропустити цілий клас дефектів.

Why it matters. One feature usually contains everything at once. In a booking form the dates are a range with boundaries, the guest count is numbers, room type and currency are independent parameters, the cancellation policy is business rules, the booking has statuses, and the whole process is an end-to-end scenario. Applying one technique to everything either bloats the suite or misses an entire class of defects.

Приклад. Для дат беру BVA (виїзд наступного дня після заїзду, максимум 30 ночей) плюс атаки на 29 лютого і перехід на літній час. Для політики скасування — таблицю рішень. Для статусів бронювання — переходи станів. Для конфігурацій — pairwise. Для всього процесу — юз-кейс. «Досить» визначаю через критерій покриття: усі класи, межі, правила й переходи з високим ризиком покриті, для низького ризику — двозначний BVA і скорочена таблиця.

Example. For dates I use BVA (check-out the day after check-in, a maximum of 30 nights) plus attacks on 29 February and the daylight saving switch. For the cancellation policy, a decision table. For booking statuses, state transitions. For configurations, pairwise. For the whole process, a use case. I define "enough" through a coverage criterion: all partitions, boundaries, rules and transitions with high risk are covered, while low-risk parts get two-value BVA and a collapsed table.

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

Pitfalls. The answer "there are enough tests when all bugs are found" is a red flag: principle 1 says testing cannot prove the absence of defects. Stopping is a deliberate decision based on the exit criteria in the test plan and an acceptable residual risk that I state openly to the team.

Карта технік для форми бронювання
Technique map for a booking form
Частина фічі            Техніка             Ризик   Глибина
Дати заїзду/виїзду      BVA + вгадування    високий 3-значний BVA,
                                                    29.02, літній час
Кількість гостей 1..6   EP + BVA            середній 2-значний BVA
Тип номера × валюта ×   pairwise            середній усі пари +
  спосіб оплати                                     топ-конфігурація
Політика скасування     таблиця рішень      високий повна таблиця
Статуси бронювання      переходи станів     високий усі переходи +
                                                    невалідні
Процес «знайти→оплатити» юз-кейс            високий основний +
                                                    усі винятки
# Досить = покриття з колонки «Глибина» + exit-критерії
Feature part            Technique           Risk    Depth
Check-in/out dates      BVA + err. guessing high    3-value BVA,
                                                    29 Feb, DST
Guests 1..6             EP + BVA            medium  2-value BVA
Room type × currency ×  pairwise            medium  all pairs +
  payment method                                    top config
Cancellation policy     decision table      high    full table
Booking statuses        state transition    high    all transitions
                                                    + invalid
"Search→pay" flow       use case            high    main flow +
                                                    all exceptions
# Enough = coverage in the Depth column + exit criteria
🔧 Як читати: стовпець «Техніка» відповідає на питання «яка модель», «Ризик» — наскільки дорогою буде помилка, «Глибина» — який критерій покриття ми беремо на себе. Разом це вже чернетка тестового підходу для фічі, яку можна показати команді й узгодити.
🔧 How to read it: the Technique column answers "which model", Risk says how costly a mistake would be, and Depth is the coverage criterion we commit to. Together this is already a draft test approach for the feature that can be shown to the team and agreed on.
💡 Простими словами: форма вимоги підказує техніку, ризик підказує глибину, exit-критерії кажуть, коли зупинитись.
💡 In plain words: the shape of the requirement suggests the technique, risk suggests the depth, and exit criteria say when to stop.
🗣 Як читати вголос Я не обираю одну техніку на всю фічу. Спочатку розбираю форму бронювання на частини і дивлюсь, яка в кожної структура: дати — це межі, політика скасування — комбінація правил, бронювання — статуси, оплата в різних конфігураціях — pairwise, а весь процес — юз-кейс. Потім кожній частині ставлю ризик, і від нього залежить глибина: де гроші, там повна таблиця й тризначні межі. Коли мене питають, скільки тестів досить, я відповідаю через критерій покриття та exit-критерії і чесно називаю залишковий ризик.
🗣 How to say it out loud I do not pick one technique for the whole feature. First I break the booking form into parts and look at the structure of each: dates are boundaries, the cancellation policy is a combination of rules, the booking has statuses, payment across configurations is pairwise, and the whole process is a use case. Then I give every part a risk level, and the depth follows from it: where money is involved, a full table and three-value boundaries. When asked how many tests are enough, I answer with a coverage criterion and exit criteria and name the residual risk honestly.
▶ 4 8
38 Що має бути в тест-кейсі, щоб його без питань виконав інший тестер? What must a test case contain so that another tester can run it without asking questions?
ДокументаціяDocumentation Junior ▶

Що це. Тест-кейс — це одна задокументована перевірка: передумови, вхідні дані, кроки й очікуваний результат, який можна однозначно порівняти з фактичним. У глосарії ISTQB це набір передумов, вхідних даних, дій, очікуваних результатів і постумов, розроблений на основі тестових умов.

What it is. A test case is one documented check: preconditions, input data, steps and an expected result that can be compared with the actual one without ambiguity. The ISTQB glossary defines it as a set of preconditions, inputs, actions, expected results and postconditions developed from test conditions.

Навіщо. Добрий кейс відтворюваний: його пройде новенький у команді, колега з іншого часового поясу або ти сам через пів року, і результат буде той самий. Посилання на вимогу дає трасованість, пріоритет підказує, що запускати першим, коли часу мало.

Why it matters. A good case is repeatable: a newcomer, a colleague in another time zone or you yourself six months later will run it and get the same outcome. The link to a requirement gives traceability, and the priority tells you what to run first when time is short.

Приклад. Нижче заповнений кейс на застосування промокоду в кошику. Зверни увагу: дані конкретні (код SPRING10, сума 1200 грн), а очікуваний результат містить число, а не фразу «знижка застосовується коректно».

Example. Below is a filled case for applying a promo code in the cart. Notice that the data is concrete (code SPRING10, a total of 1200 UAH) and the expected result contains a number rather than the phrase "the discount applies correctly".

Підводні камені. Найчастіші помилки: кілька перевірок в одному кейсі (тоді незрозуміло, що саме впало), розмитий очікуваний результат, кроки, що покладаються на «знання системи», і забуті передумови на кшталт ролі користувача чи стану даних. Ще одна пастка — надмірна деталізація UI («натисни синю кнопку зліва»): після редизайну такі кейси доводиться переписувати всі.

Pitfalls. The usual mistakes: several checks in one case (so you cannot tell what failed), a vague expected result, steps that rely on "knowing the system", and forgotten preconditions such as the user role or the state of the data. Another trap is over-describing the UI ("click the blue button on the left"): after a redesign every such case has to be rewritten.

Заповнений тест-кейс
A filled test case
ID:          TC-CART-014
Назва:       Промокод -10% зменшує суму кошика
Вимога:      REQ-PROMO-3
Пріоритет:   Високий
Передумови:  Користувач buyer01 залогінений;
             кошик порожній; код SPRING10 активний
Дані:        Товар «Чайник K-200», ціна 1200 грн
Кроки:
  1. Додати «Чайник K-200» у кошик
  2. Відкрити кошик
  3. Ввести SPRING10 у поле «Промокод»
  4. Натиснути «Застосувати»
Очікувано:
  - повідомлення «Промокод застосовано»
  - рядок «Знижка: -120 грн»
  - «До сплати: 1080 грн»
Постумова:   Очистити кошик
ID:             TC-CART-014
Title:          Promo code -10% reduces the cart total
Requirement:    REQ-PROMO-3
Priority:       High
Preconditions:  User buyer01 is logged in;
                cart is empty; code SPRING10 is active
Data:           Item "Kettle K-200", price 1200 UAH
Steps:
  1. Add "Kettle K-200" to the cart
  2. Open the cart
  3. Enter SPRING10 into the "Promo code" field
  4. Click "Apply"
Expected:
  - message "Promo code applied"
  - line "Discount: -120 UAH"
  - "To pay: 1080 UAH"
Postcondition:  Empty the cart
🔧 Як читати: ID і посилання на вимогу потрібні для звітів і матриці трасованості. Передумови описують стан системи до першого кроку, тому кроки починаються одразу з дії. Очікуваний результат розбитий на три перевірні пункти з конкретними числами. Постумова повертає дані у вихідний стан, щоб наступний кейс не залежав від цього.
🔧 How to read it: The ID and the requirement link feed the reports and the traceability matrix. Preconditions describe the system state before the first step, so the steps start straight with an action. The expected result is split into three checkable points with concrete numbers. The postcondition returns the data to its initial state so that the next case does not depend on this one.
💡 Простими словами: Якщо двоє тестерів, прочитавши кейс, можуть по-різному вирішити, пройшов він чи ні, — кейс ще не готовий.
💡 In plain words: If two testers could read the case and disagree on whether it passed, the case is not finished yet.
🗣 Як читати вголос Для мене тест-кейс — це інструкція, яку можна віддати іншій людині й отримати той самий результат. Тому я завжди прописую передумови: хто залогінений, які дані вже є в системі. Дані беру конкретні, наприклад конкретний промокод і конкретну ціну, а в очікуваному результаті пишу число, яке має з'явитися на екрані. Одна перевірка — один кейс, щоб при падінні було одразу видно, що зламалося. І обов'язково посилання на вимогу, бо без нього потім неможливо показати покриття.
🗣 How to say it out loud To me a test case is an instruction I can hand to someone else and get the same result back. So I always spell out preconditions: who is logged in and what data already exists. I use concrete data, say a specific promo code and a specific price, and in the expected result I write the number that should appear on screen. One check per case, so when it fails it is obvious what broke. And I always link it to a requirement, because otherwise I cannot show coverage later.
39 Коли достатньо чек-листа замість тест-кейсів і як групувати перевірки в тестовий набір? When is a checklist enough instead of test cases, and how do you group checks into a test suite?
ДокументаціяDocumentation Junior ▶

Що це. Чек-лист — перелік того, що треба перевірити, одним рядком на пункт, без детальних кроків і даних. Тест-кейс описує одну перевірку повністю. Тестовий набір (test suite) — це група кейсів або пунктів, зібраних за спільною ознакою: фіча, тип тестування, рівень ризику, смоук чи регресія.

What it is. A checklist is a list of things to verify, one line per item, without detailed steps or data. A test case describes one check in full. A test suite is a group of cases or items collected by a shared attribute: a feature, a test type, a risk level, smoke or regression.

Навіщо і коли. Чек-листа вистачає, коли продукт знає вся команда, фіча швидко змінюється, а виконують досвідчені тестери: він дешевий у підтримці й лишає місце для дослідження. Повні кейси потрібні там, де важлива відтворюваність і доказовість: регуляторні вимоги, передача роботи аутсорсу, складні розрахунки, кандидати в автоматизацію. Набори дозволяють запускати саме ту частину, що потрібна зараз, наприклад лише смоук після деплою.

When and why. A checklist is enough when the whole team knows the product, the feature changes quickly and experienced testers run it: it is cheap to maintain and leaves room for exploration. Full cases are needed where repeatability and evidence matter: regulatory requirements, handing work to an outsourced team, complex calculations, candidates for automation. Suites let you run exactly the part you need right now, for example only the smoke set after a deploy.

Приклад. Для фільтра пошуку товарів чек-лист із десяти рядків покриває основне за годину роботи. Ті самі пункти потім розкладаються в набори: критичні йдуть у смоук, решта — у регресію каталогу.

Example. For a product search filter a ten-line checklist covers the essentials in an hour of work. The same items are then spread across suites: the critical ones go into smoke, the rest into the catalogue regression.

Підводні камені. Пункт «перевірити фільтр» — це не чек-лист, а побажання: кожен рядок має називати конкретну умову. І навпаки, сто кейсів на кожен клік застарівають швидше, ніж їх встигають оновити. Набори варто переглядати: мертві кейси, які роками не знаходять дефектів, забирають час регресії.

Pitfalls. An item like "check the filter" is a wish, not a checklist line: each line must name a specific condition. At the other extreme, a hundred cases for every click go stale faster than anyone can update them. Suites need regular pruning: dead cases that have not found a defect in years eat regression time.

Чек-лист і структура наборів
A checklist and a suite structure
# Чек-лист: фільтр «Ціна» в каталозі
[ ] Діапазон 100–500 показує лише товари в межах
[ ] Межі включні: товар за 500 грн є у видачі
[ ] «Від» більше за «До» → підказка, запиту немає
[ ] Порожні поля → фільтр не застосовано
[ ] Літери в полі не вводяться
[ ] Фільтр зберігається після переходу на стор. 2
[ ] Фільтр потрапляє в URL і працює після F5
[ ] Скидання фільтра повертає повний список
[ ] Разом з фільтром «Бренд» діє умова І
[ ] 0 результатів → повідомлення «Нічого не знайдено»

# Набори
Smoke:          рядки 1, 8
Regression/Cat: усі 10 рядків
Cross-browser:  рядки 1, 6, 7 (Safari, Firefox)
# Checklist: "Price" filter in the catalogue
[ ] Range 100–500 shows only items within it
[ ] Bounds are inclusive: a 500 UAH item is listed
[ ] "From" greater than "To" → hint, no request
[ ] Empty fields → filter not applied
[ ] Letters cannot be typed into the field
[ ] Filter survives moving to page 2
[ ] Filter goes into the URL and works after F5
[ ] Reset returns the full list
[ ] Combined with "Brand" the condition is AND
[ ] 0 results → "Nothing found" message

# Suites
Smoke:          lines 1, 8
Regression/Cat: all 10 lines
Cross-browser:  lines 1, 6, 7 (Safari, Firefox)
🔧 Як читати: Кожен рядок чек-листа — одна умова з очікуваною поведінкою, але без кроків і тестових даних: їх тестер обирає сам. У нижній частині ті самі рядки розкладені по наборах за метою запуску, тому один пункт може жити в кількох наборах одночасно.
🔧 How to read it: Each checklist line is one condition with the expected behaviour, but with no steps or test data: the tester picks those. The bottom part spreads the same lines across suites by the purpose of the run, so one item can live in several suites at once.
💡 Простими словами: Чек-лист каже «що», тест-кейс — «що і як саме», набір — «що запускаємо разом».
💡 In plain words: A checklist says "what", a test case says "what and exactly how", a suite says "what we run together".
🗣 Як читати вголос Я обираю формат під контекст. Якщо команда маленька, продукт усі знають, а фіча ще активно змінюється, я пишу чек-лист: це швидко, і він не стримує дослідження. Повні кейси пишу для платежів, розрахунків, регуляторики і для того, що потім піде в автоматизацію. Набори в мене групуються за метою: смоук після деплою, регресія по модулю, крос-браузерні перевірки. А раз на кілька релізів я чищу набори від кейсів, які давно нічого не знаходять.
🗣 How to say it out loud I pick the format to fit the context. If the team is small, everyone knows the product and the feature is still changing a lot, I write a checklist: it is fast and it does not hold back exploration. I write full cases for payments, calculations, regulatory things and whatever will later be automated. My suites are grouped by purpose: smoke after a deploy, regression per module, cross-browser checks. And every few releases I clean the suites of cases that have not caught anything for ages.
40 Які розділи має тест-план і як виглядає односторінковий план на фічу? What sections does a test plan have, and what does a one-page plan for a feature look like?
ДокументаціяDocumentation Middle ▶

Що це. Тест-план описує, що, як, ким, коли і з якими ризиками тестуватиметься в межах проєкту чи релізу. Структуру зазвичай беруть з ISO/IEC/IEEE 29119-3, який замінив старий IEEE 829: контекст і обсяг, що в скоупі й поза ним, підхід і техніки, середовища й дані, ролі, графік, критерії входу й виходу, ризики, результати тестування (deliverables).

What it is. A test plan describes what will be tested, how, by whom, when and with what risks within a project or a release. The structure usually comes from ISO/IEC/IEEE 29119-3, which superseded the old IEEE 829: context and scope, what is in and out of scope, approach and techniques, environments and data, roles, schedule, entry and exit criteria, risks, and test deliverables.

Навіщо. План — це домовленість, а не формальність. Коли PM питає «чому ви не тестували IE?», відповідь уже записана в розділі «поза скоупом», і її погодили заздалегідь. Він також показує залежності: якщо стенд з'явиться на три дні пізніше, всі бачать, що зсуваються і терміни.

Why it matters. A plan is an agreement, not paperwork. When the PM asks "why didn't you test on IE?", the answer is already in the out-of-scope section and was agreed in advance. It also exposes dependencies: if the environment arrives three days late, everyone sees that the dates move too.

Приклад. В Agile-команді план на фічу вміщається на одну сторінку в Confluence або в описі епіка. Нижче такий план для оплати частинами: без води, але з усіма рішеннями, які хтось може оскаржити.

Example. In an Agile team a feature plan fits on one page in Confluence or in the epic description. Below is such a plan for pay-in-instalments: no filler, but every decision someone could challenge is written down.

Підводні камені. Сорокасторінковий план, скопійований з шаблону, ніхто не читає, і він застаріває до першого спринту. Інша крайність — плану немає зовсім, і скоуп з'ясовують у день релізу. Розділ ризиків часто заповнюють загальними фразами; корисний ризик завжди має конкретну дію-відповідь.

Pitfalls. A forty-page plan copied from a template goes unread and is out of date before the first sprint. The other extreme is no plan at all, with the scope discovered on release day. The risk section is often filled with generic phrases; a useful risk always comes with a concrete response.

Односторінковий тест-план
A one-page test plan
Тест-план: Оплата частинами (реліз 4.2)
Скоуп:      вибір 3/6/10 платежів, графік, API банку
Поза скоупом: кредитний скоринг (зона банку), IE11
Підхід:     EP/BVA для суми 500–50000 грн,
            таблиця рішень для умов доступності,
            API-перевірки у Postman, 2 сесії дослідження
Середовище: stage + sandbox банку; дані: 5 тест-карт
Ролі:       QA — Олена, Ігор; UAT — фінвідділ
Графік:     12–16.05 тестування, 19.05 UAT, 21.05 реліз
Вхід:       фіча на stage, sandbox доступний, AC погоджені
Вихід:      0 відкритих Critical/Major, UAT підписано
Ризики:     sandbox падає → мок відповіді банку;
            пізня здача фічі → різати крос-браузер
Результати: чек-листи, баг-репорти, звіт на 1 стор.
Test plan: Pay in instalments (release 4.2)
Scope:        3/6/10 payments, schedule, bank API
Out of scope: credit scoring (bank's side), IE11
Approach:     EP/BVA for amount 500–50000 UAH,
              decision table for eligibility rules,
              API checks in Postman, 2 exploratory sessions
Environment:  stage + bank sandbox; data: 5 test cards
Roles:        QA — Olena, Ihor; UAT — finance team
Schedule:     12–16 May testing, 19 May UAT, 21 May release
Entry:        feature on stage, sandbox up, AC agreed
Exit:         0 open Critical/Major, UAT signed off
Risks:        sandbox down → mock bank responses;
              late delivery → cut cross-browser
Deliverables: checklists, bug reports, 1-page report
🔧 Як читати: Кожен рядок відповідає розділу стандарту 29119-3, але в стислій формі. «Поза скоупом» так само важливий, як «скоуп»: він фіксує, за що команда не відповідає. У рядку ризиків кожна загроза має відповідь після стрілки, а критерії входу й виходу перевірні, тобто на них можна відповісти «так» чи «ні».
🔧 How to read it: Each line maps to a section of 29119-3, just in condensed form. "Out of scope" matters as much as "scope": it records what the team is not responsible for. In the risks line every threat has a response after the arrow, and the entry and exit criteria are checkable, so each can be answered with yes or no.
💡 Простими словами: Тест-план — це відповідь на питання «що саме ми пообіцяли протестувати і за яких умов».
💡 In plain words: A test plan answers the question "what exactly did we promise to test, and under what conditions".
🗣 Як читати вголос Структуру тест-плану я знаю зі стандарту 29119-3, але на практиці пишу його коротко, на сторінку для фічі. Там обов'язково є скоуп і те, що ми свідомо не тестуємо, бо це знімає суперечки в кінці. Далі підхід: які техніки, де ручне, де API. Середовища, дані, люди, дати. Критерії входу і виходу я формулюю так, щоб на них можна було відповісти «так» або «ні». А для кожного ризику одразу пишу, що робимо, якщо він спрацює, наприклад мокаємо банк, якщо впаде його пісочниця.
🗣 How to say it out loud I know the test plan structure from 29119-3, but in practice I keep it short, one page per feature. It always has the scope and what we deliberately leave out, because that settles arguments at the end. Then the approach: which techniques, what is manual, what goes through the API. Environments, data, people, dates. I word entry and exit criteria so each one can be answered yes or no. And for every risk I write straight away what we do if it fires, for example we mock the bank when its sandbox goes down.
41 Чим тестова стратегія відрізняється від тест-плану і хто за що відповідає? How does a test strategy differ from a test plan, and who owns which?
ДокументаціяDocumentation Middle ▶

Що це. Тестова стратегія — довгоживучий документ рівня продукту чи організації: які рівні тестування ми маємо, що автоматизуємо, які інструменти й середовища, як керуємо дефектами і що вважаємо достатньою якістю. Тест-план — конкретизація стратегії для одного проєкту, релізу чи фічі з датами, людьми та скоупом. Стратегія живе роками, план — тижні чи місяці.

What it is. A test strategy is a long-lived document at product or organisation level: which test levels we have, what we automate, which tools and environments we use, how defects are managed and what we consider good enough quality. A test plan applies the strategy to one project, release or feature with dates, people and scope. A strategy lives for years, a plan for weeks or months.

Навіщо. Без стратегії кожен план винаходить підхід заново, і команди одного продукту тестують по-різному. ISTQB описує типові підходи, з яких складають стратегію: аналітичний (зазвичай ризик-орієнтований), методичний (за чек-листами чи стандартом якості), реактивний (дослідницький, у відповідь на поведінку системи), консультативний, орієнтований на регресію, процесний. На практиці їх комбінують.

Why it matters. Without a strategy every plan reinvents the approach, and teams on one product test in different ways. ISTQB lists typical approaches a strategy is built from: analytical (usually risk-based), methodical (checklists or a quality standard), reactive (exploratory, responding to how the system behaves), consultative, regression-averse and process-compliant. In practice they are combined.

Приклад. Стратегія мобільного банку каже: платежі тестуються ризик-орієнтовано з обов'язковою автоматизованою регресією API, а UI — дослідницькими сесіями. План релізу 7.3 бере це правило й уточнює: цього разу змінено переказ за номером телефону, тож глибоко тестуємо його, а решту платежів проганяє регресія.

Example. A mobile bank's strategy says payments are tested risk-based with a mandatory automated API regression, and the UI through exploratory sessions. The plan for release 7.3 takes that rule and narrows it: this time transfer-by-phone-number changed, so it gets deep testing while the rest of the payments are covered by regression.

Підводні камені. У малих компаніях стратегію часто пишуть усередині плану, і це нормально, якщо розділ підходу справді відповідає на питання «як ми тестуємо взагалі». Погано, коли стратегія — красивий документ, який суперечить тому, що команда робить щодня.

Pitfalls. Small companies often write the strategy inside the plan, and that is fine as long as the approach section really answers "how do we test in general". It goes wrong when the strategy is a polished document that contradicts what the team does every day.

Порівняння стратегії та плану
Strategy compared with plan
               Стратегія             План
Рівень         продукт/організація   проєкт/реліз/фіча
Термін життя   роки                  тижні–місяці
Відповідає     «як ми тестуємо»      «що тестуємо зараз»
Власник        QA lead / head of QA  QA на проєкті
Приклад змісту піраміда тестів,      скоуп 7.3, дати,
               інструменти, типи     люди, ризики релізу
               середовищ, політика
               дефектів
Змінюється     коли змінюється       щорелізу
               продукт чи процес
               Strategy              Plan
Level          product/organisation  project/release/feature
Lifetime       years                 weeks–months
Answers        "how we test"         "what we test now"
Owner          QA lead / head of QA  QA on the project
Typical        test pyramid, tools,  scope of 7.3, dates,
content        environment types,    people, release risks
               defect policy
Changes        when product or       every release
               process changes
🔧 Як читати: Таблицю читай по рядках: кожен рядок — одна вісь, за якою документи різняться. Найважливіші — «Відповідає» і «Змінюється»: якщо документ доводиться переписувати щорелізу, це план, навіть якщо його назвали стратегією.
🔧 How to read it: Read the table row by row: each row is one axis on which the documents differ. The key ones are "Answers" and "Changes": if a document has to be rewritten every release, it is a plan, even if someone called it a strategy.
💡 Простими словами: Стратегія — правила гри для всього продукту, план — розстановка на конкретний матч.
💡 In plain words: The strategy is the rules of the game for the whole product; the plan is the line-up for one match.
🗣 Як читати вголос Я розрізняю їх за рівнем і часом життя. Стратегія описує, як ми тестуємо продукт узагалі: піраміду, інструменти, середовища, політику щодо багів, і вона роками майже не змінюється. План бере ці правила й застосовує до конкретного релізу: що саме в скоупі, хто, коли, які ризики саме цього разу. У невеликих командах стратегія може бути розділом плану, і я не бачу в цьому проблеми, аби вона відповідала реальній практиці.
🗣 How to say it out loud I tell them apart by level and lifetime. The strategy describes how we test the product in general: the pyramid, tools, environments, the bug policy, and it barely changes for years. The plan takes those rules and applies them to a specific release: what exactly is in scope, who, when, and which risks this time around. In small teams the strategy can be a section of the plan, and I do not see a problem there, as long as it matches what people actually do.
42 Що таке критерії входу і що робити, якщо збірку віддали на тестування без них? What are entry criteria, and what do you do when a build reaches testing without meeting them?
ДокументаціяDocumentation Middle ▶

Що це. Критерії входу (entry criteria) — умови, які мають виконатися, перш ніж починати тестову активність. У CTFL 4.0 їх пов'язують із definition of ready: доступні ресурси (люди, середовище, дані, інструменти), готовий тестовий базис (вимоги, AC) і прийнятна якість об'єкта тестування, наприклад пройдений смоук.

What it is. Entry criteria are the conditions that must hold before a test activity starts. CTFL 4.0 relates them to the definition of ready: available resources (people, environment, data, tools), a ready test basis (requirements, acceptance criteria) and acceptable quality of the test object, for example a passed smoke test.

Навіщо. Вони захищають час команди. Тестування збірки, у якій не працює логін, дає сотню дублікатних багів і нуль інформації про нову фічу. Явні критерії дозволяють сказати «ми не почали» з аргументами, а не з емоціями.

Why it matters. They protect the team's time. Testing a build where login is broken produces a hundred duplicate bugs and zero information about the new feature. Explicit criteria let you say "we have not started" with arguments rather than emotions.

Приклад. У п'ятницю ввечері на stage приходить збірка з оплатою частинами, але sandbox банку недоступний, а два з п'яти AC досі в статусі «обговорюється». Я не блокую все: тестую те, що вже можна (калькулятор графіку, UI-валідацію), фіксую невиконані критерії в каналі релізу і пропоную варіант з моком відповіді банку. Рішення, чи рухатися далі з ризиком, ухвалює власник релізу.

Example. On Friday evening a build with pay-in-instalments lands on stage, but the bank sandbox is down and two of the five acceptance criteria are still "under discussion". I do not block everything: I test what is already testable (the schedule calculator, UI validation), post the unmet criteria in the release channel and propose mocking the bank response. The release owner decides whether to go ahead with the risk.

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

Pitfalls. Criteria like "the code is stable" cannot be checked, so they do not work. The second trap is using them as a barrier and sitting idle: in agile teams an entry criterion is a reason to talk, not a ban on touching the build.

Критерії входу для системного тестування
Entry criteria for system testing
# Реліз 4.2, системне тестування
[x] Збірка 4.2.0-rc1 розгорнута на stage
[x] Смоук (12 перевірок) пройдено без збоїв
[ ] Sandbox банку відповідає            ← НЕ виконано
[x] Тестові карти й 5 акаунтів створені
[ ] AC для PAY-31, PAY-34 погоджені PO  ← НЕ виконано
[x] Release notes зі списком змін є

# Дія
Почати: калькулятор, валідацію форми
Відкласти: сценарії з банком, PAY-31/34
Ескалація: PO + DevOps, дедлайн пн 10:00
# Release 4.2, system testing
[x] Build 4.2.0-rc1 deployed to stage
[x] Smoke (12 checks) passed with no failures
[ ] Bank sandbox responds                ← NOT met
[x] Test cards and 5 accounts created
[ ] AC for PAY-31, PAY-34 agreed by PO   ← NOT met
[x] Release notes with the change list exist

# Action
Start: calculator, form validation
Defer: bank scenarios, PAY-31/34
Escalate: PO + DevOps, deadline Mon 10:00
🔧 Як читати: Кожен пункт бінарний: [x] виконано, [ ] ні. Нижній блок перетворює невиконані критерії на рішення — що почати, що відкласти і кому ескалювати з конкретним дедлайном, щоб проблема не повисла у повітрі.
🔧 How to read it: Every item is binary: [x] met, [ ] not met. The bottom block turns the unmet criteria into decisions — what to start, what to defer and whom to escalate to with a concrete deadline, so the problem does not hang in the air.
💡 Простими словами: Критерії входу відповідають на питання «чи є сенс уже починати?».
💡 In plain words: Entry criteria answer the question "does it make sense to start yet?".
🗣 Як читати вголос Критерії входу для мене — це перевірний список: збірка на стенді, смоук зелений, дані готові, вимоги погоджені. Якщо щось не виконано, я не кажу просто «не беру». Я дивлюся, що вже можна тестувати без відсутнього шматка, і починаю з цього, а невиконані пункти пишу в канал релізу з конкретним запитом і дедлайном. Далі власник релізу вирішує, чи йдемо з ризиком. Так ми не втрачаємо день і водночас ніхто не вдає, що все гаразд.
🗣 How to say it out loud For me entry criteria are a checkable list: the build is on the environment, smoke is green, data is ready, requirements are agreed. If something is missing I do not just refuse the build. I look at what I can already test without the missing piece and start there, and I post the unmet items in the release channel with a concrete request and a deadline. Then the release owner decides whether we proceed with the risk. That way we do not lose a day, and nobody pretends everything is fine.
43 Як сформулювати критерії виходу і хто вирішує, що тестування можна завершувати? How do you word exit criteria, and who decides that testing can stop?
ДокументаціяDocumentation Middle ▶

Що це. Критерії виходу (exit criteria) — умови, за яких тестову активність вважають завершеною. У CTFL 4.0 вони відповідають definition of done і зазвичай містять міри покриття, кількість і критичність відкритих дефектів, результати нефункціональних перевірок та готовність звіту. Єдиного стандарту чисел немає: «95% виконаних кейсів» чи «0 Critical» — це приклади, які команда погоджує в тест-плані під свій продукт і ризики.

What it is. Exit criteria are the conditions under which a test activity is considered complete. In CTFL 4.0 they correspond to the definition of done and usually include coverage measures, the number and severity of open defects, results of non-functional checks and a finished report. There is no standard set of numbers: "95% of cases executed" or "0 Critical" are examples the team agrees in the test plan for its own product and risks.

Навіщо. Без них тестування закінчується тоді, коли закінчився час, і ніхто не знає, наскільки ризикованим є реліз. Явні критерії перетворюють «здається, готово» на факти, на які можна послатися на go/no-go.

Why it matters. Without them testing ends when time runs out and nobody knows how risky the release is. Explicit criteria turn "looks done to me" into facts you can point to in a go/no-go meeting.

Приклад. Нижче критерії з плану релізу та знімок стану в день рішення. Один критерій не виконано: лишився відкритий Major. QA не ухвалює рішення про реліз одноосібно; я показую факти й залишковий ризик, а власник продукту вирішує, чи випускати з обхідним шляхом.

Example. Below are the criteria from the release plan and a status snapshot on decision day. One criterion is not met: one Major is still open. QA does not make the release decision alone; I show the facts and the residual risk, and the product owner decides whether to ship with a workaround.

Підводні камені. Числа без контексту дають хибну впевненість: 100% пройдених кейсів нічого не варті, якщо кейси не покривають змінену логіку. Також пам'ятай, що критерії можна переглянути, але це має бути свідоме рішення, записане разом з прийнятим ризиком, а не тихе заниження планки.

Pitfalls. Numbers without context give false confidence: 100% passed cases are worthless if the cases do not cover the changed logic. Also, criteria can be revised, but that has to be a conscious decision recorded together with the accepted risk, not a quiet lowering of the bar.

Критерії виходу і стан у день релізу
Exit criteria and status on release day
# Приклад, погоджений у тест-плані 4.2
Критерій                        Ціль     Факт   Стан
Виконано запланованих кейсів    ≥ 95%   97%    OK
Вимоги з тестами (RTM)          100%    100%   OK
Відкриті Blocker/Critical       0        0      OK
Відкриті Major                  0        1      НІ
Відповідь API оплати, p95       ≤ 800 мс 640 мс OK
UAT підписано фінвідділом       так      так    OK

# Для go/no-go
PAY-58 (Major): графік не оновлюється без F5.
Обхід: оновити сторінку. Фікс у 4.2.1.
Рішення: PO — go з відомим дефектом.
# Example agreed in test plan 4.2
Criterion                       Target   Actual Status
Planned cases executed          ≥ 95%   97%    OK
Requirements with tests (RTM)   100%    100%   OK
Open Blocker/Critical           0        0      OK
Open Major                      0        1      NO
Payment API response, p95       ≤ 800 ms 640 ms OK
UAT signed off by finance       yes      yes    OK

# For go/no-go
PAY-58 (Major): schedule not refreshed without F5.
Workaround: reload the page. Fix in 4.2.1.
Decision: PO — go with a known defect.
🔧 Як читати: Колонка «Ціль» — домовленість з плану, «Факт» — вимірювання на момент рішення. Будь-який рядок зі станом «НІ» не зупиняє реліз автоматично: він потрапляє в нижній блок, де описано дефект, обхідний шлях і хто саме прийняв ризик.
🔧 How to read it: The "Target" column is the agreement from the plan, "Actual" is the measurement at decision time. A row marked "NO" does not stop the release automatically: it moves to the bottom block, which records the defect, the workaround and who exactly accepted the risk.
💡 Простими словами: Критерії виходу — це домовленість про те, як виглядає «достатньо протестовано» саме для цього релізу.
💡 In plain words: Exit criteria are an agreement on what "tested enough" looks like for this particular release.
🗣 Як читати вголос Я одразу кажу, що універсальних чисел немає. Відсотки виконаних кейсів чи нуль відкритих критичних багів ми погоджуємо в тест-плані під конкретний продукт. У день релізу я показую таблицю: ціль, факт, статус. Якщо щось не виконано, це не автоматичний стоп, а інформація для рішення. Рішення про реліз ухвалює власник продукту, а моя задача — чесно показати залишковий ризик і обхідний шлях. І якщо критерій знижують, я прошу зафіксувати це письмово.
🗣 How to say it out loud I say straight away that there are no universal numbers. The percentage of executed cases or zero open critical bugs is something we agree in the test plan for a specific product. On release day I show a table: target, actual, status. If something is not met, that is not an automatic stop but input for a decision. The product owner makes the release call, and my job is to show the residual risk and the workaround honestly. And if a criterion gets lowered, I ask for that to be written down.
44 Навіщо матриця трасованості вимог і чим покриття вимог відрізняється від покриття коду? Why keep a requirements traceability matrix, and how does requirement coverage differ from code coverage?
ДокументаціяDocumentation Middle ▶

Що це. Матриця трасованості (RTM) зв'язує вимоги з тестами, а тести — з результатами й дефектами. Звіт про покриття вимог рахує, скільки вимог мають хоча б один тест і скільки з них пройдено. Покриття коду — інша міра: частка рядків (statement) чи гілок (branch), які виконались під час автотестів; його збирають інструменти на кшталт JaCoCo, Istanbul чи coverage.py.

What it is. A requirements traceability matrix (RTM) links requirements to tests, and tests to results and defects. A requirement coverage report counts how many requirements have at least one test and how many of those passed. Code coverage is a different measure: the share of statements or branches executed while automated tests ran; tools such as JaCoCo, Istanbul or coverage.py collect it.

Навіщо. RTM відповідає на питання «що ми забули протестувати?» і «що зачепить зміна вимоги REQ-7?». Для регульованих доменів (медицина, фінанси) вона часто обов'язкова. Покриття коду показує, які частини коду тести взагалі не запускали, але не каже, чи перевіряли вони щось осмислене.

Why it matters. An RTM answers "what did we forget to test?" and "what does a change to REQ-7 affect?". In regulated domains (medical, finance) it is often mandatory. Code coverage shows which parts of the code the tests never ran, but not whether they checked anything meaningful.

Приклад. У матриці нижче одразу видно дві проблеми: REQ-4 (блокування після п'яти невдалих спроб) не має жодного тесту, а в REQ-3 тест упав і пов'язаний з відкритим дефектом. Покриття вимог тут 3 з 4, пройдено 2 з 4 — це і є рядок у звіті.

Example. The matrix below shows two problems at once: REQ-4 (lock after five failed attempts) has no test at all, and the test for REQ-3 failed and is linked to an open defect. Requirement coverage here is 3 of 4, passed 2 of 4 — that is the line that goes into the report.

Підводні камені. Один тест на вимогу — ще не повне покриття: вимога «пароль 6–20 символів» потребує кількох перевірок меж. А 90% покриття коду не гарантують якості: тест без жодної перевірки (assert) теж «покриває» рядки. Матрицю, яку ведуть вручну в Excel, швидко закидають, тому краще тримати зв'язки в трекері (Jira, TestRail, Xray).

Pitfalls. One test per requirement is not full coverage: a rule like "password 6–20 characters" needs several boundary checks. And 90% code coverage does not guarantee quality: a test with no assertion also "covers" lines. A matrix maintained by hand in Excel gets abandoned quickly, so keep the links in the tracker (Jira, TestRail, Xray).

Матриця трасованості з прогалиною
A traceability matrix with a gap
Вимога  Опис                       Тести        Результат  Дефект
REQ-1   Логін email+пароль         TC-01, TC-02 pass
REQ-2   Пароль 6–20 символів       TC-03..TC-08 pass
REQ-3   «Запам'ятати мене» 30 днів TC-09        fail       BUG-212
REQ-4   Блок після 5 спроб         —            —          —

Покриття вимог:  3/4 (75%)  → REQ-4 без тестів
Пройдено:        2/4 (50%)  → REQ-3 блокує вихід
Req     Description                Tests        Result  Defect
REQ-1   Login with email+password  TC-01, TC-02 pass
REQ-2   Password 6–20 characters   TC-03..TC-08 pass
REQ-3   "Remember me" for 30 days  TC-09        fail    BUG-212
REQ-4   Lock after 5 attempts      —            —       —

Requirement coverage: 3/4 (75%) → REQ-4 has no tests
Passed:               2/4 (50%) → REQ-3 blocks exit
🔧 Як читати: Рядок — одна вимога. Прочерк у колонці «Тести» — прогалина в покритті (пряма трасованість), а заповнена колонка «Дефект» дозволяє йти у зворотний бік: від бага до вимоги, яку він порушує. Два підсумкові рядки — готові числа для звіту про покриття.
🔧 How to read it: Each row is one requirement. A dash in the "Tests" column is a coverage gap (forward traceability), and a filled "Defect" column lets you go the other way: from a bug to the requirement it breaks. The two summary lines are ready-made numbers for the coverage report.
💡 Простими словами: RTM показує, що саме ти перевірив з того, що обіцяли користувачу; покриття коду — яку частину коду тести хоча б запустили.
💡 In plain words: An RTM shows what you checked out of what was promised to the user; code coverage shows how much of the code the tests at least ran.
🗣 Як читати вголос Матриця трасованості в мене живе в трекері: кожна вимога прив'язана до тестів, тести до результатів і багів. Найкорисніше в ній — пусті клітинки, бо це вимоги, які ніхто не перевіряв. Коли змінюється вимога, я по ній же бачу, які тести переглянути. Покриття коду — це вже метрика автотестів: скільки рядків чи гілок виконалось. Вона корисна, щоб знайти неторкані місця, але високий відсоток сам по собі нічого не гарантує, якщо в тестах слабкі перевірки.
🗣 How to say it out loud My traceability matrix lives in the tracker: every requirement is linked to tests, and tests to results and bugs. The most useful part of it is the empty cells, because those are requirements nobody checked. When a requirement changes, the same links tell me which tests to revisit. Code coverage is an automation metric: how many lines or branches ran. It helps find untouched areas, but a high percentage guarantees nothing on its own if the tests have weak assertions.
45 Як оцінити тривалість тестування фічі і як захистити цю оцінку перед менеджером? How do you estimate the testing effort for a feature, and how do you defend that estimate to a manager?
ДокументаціяDocumentation Senior ▶

Що це. Оцінка тестування — прогноз зусиль на аналіз, дизайн, підготовку даних і середовища, виконання, ретести та звітність. Основні техніки з CTFL 4.0: декомпозиція роботи (WBS), трьохточкова оцінка, оцінка на основі історичних даних (ratio-based, наприклад частка від зусиль розробки) і експертна оцінка, зокрема Wideband Delphi чи planning poker.

What it is. A test estimate forecasts the effort for analysis, design, data and environment preparation, execution, retests and reporting. The main techniques in CTFL 4.0 are work breakdown (WBS), three-point estimation, estimation from historical data (ratio-based, such as a share of development effort) and expert-based estimation, including Wideband Delphi or planning poker.

Навіщо. Оцінка — це не обіцянка, а інструмент планування: вона показує, що саме займе час і де невизначеність. Трьохточкова формула (O + 4M + P) / 6 з PERT враховує оптимістичний, найімовірніший і песимістичний сценарій, а стандартне відхилення (P − O) / 6 дає чесний діапазон замість одного числа.

Why it matters. An estimate is a planning tool, not a promise: it shows what takes time and where the uncertainty is. The PERT three-point formula (O + 4M + P) / 6 accounts for the optimistic, most likely and pessimistic cases, and the standard deviation (P − O) / 6 gives an honest range instead of a single number.

Приклад. Для оплати частинами я розбиваю роботу на задачі, оцінюю кожну трьома числами і окремо додаю цикл ретестів, бо його забувають найчастіше. Виходить близько 8 днів із розкидом менше ніж на день. Менеджеру я показую не лише підсумок, а й драйвери: найбільший розкид дає інтеграція з банком через нестабільний sandbox.

Example. For pay-in-instalments I break the work into tasks, estimate each with three numbers and add a retest cycle separately, because that is the part people forget most often. It comes to about 8 days, give or take less than a day. I show the manager not just the total but the drivers: the widest spread comes from the bank integration because its sandbox is unstable.

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

Pitfalls. Estimating only case execution and forgetting data, environments and retests. Agreeing to "can you do it in three days?" without changing the scope: the right answer is "yes, if we drop these items and accept this risk". And comparing with past features without adjusting for the difference in complexity.

Трьохточкова оцінка (дні)
Three-point estimate (days)
Задача                     O     M     P    E=(O+4M+P)/6
Аналіз вимог, AC          0.5   1     1.5   1.0
Дизайн тестів (EP, DT)    1     1.5   2     1.5
Дані й доступ до sandbox  0.5   1     3     1.25
Виконання + дослідження   2     2.5   4     2.67
Ретести і регресія        1     1     2     1.17
Звіт, UAT-підтримка       0.5   0.5   1     0.58
                                              ──────
Разом                                         ≈ 8.2 дня
σ ≈ √Σ((P−O)/6)² ≈ 0.6  →  діапазон ≈ 7.6–8.8 дня
Головний драйвер ризику: sandbox банку (P = 3)
Task                       O     M     P    E=(O+4M+P)/6
Requirements, AC analysis 0.5   1     1.5   1.0
Test design (EP, DT)      1     1.5   2     1.5
Data and sandbox access   0.5   1     3     1.25
Execution + exploration   2     2.5   4     2.67
Retests and regression    1     1     2     1.17
Report, UAT support       0.5   0.5   1     0.58
                                              ──────
Total                                         ≈ 8.2 days
σ ≈ √Σ((P−O)/6)² ≈ 0.6  →  range ≈ 7.6–8.8 days
Main risk driver: bank sandbox (P = 3)
🔧 Як читати: O, M, P — оптимістична, найімовірніша й песимістична оцінки в днях. Колонка E зважує M учетверо, тож одна погана задача не роздуває підсумок. Сигма підсумку рахується як корінь із суми квадратів сигм задач, звідси діапазон. Рядок із найбільшою різницею P − O і є тим ризиком, про який варто говорити з менеджером.
🔧 How to read it: O, M and P are the optimistic, most likely and pessimistic estimates in days. Column E weights M four times, so one bad task does not inflate the total. The total sigma is the square root of the sum of the tasks' squared sigmas, which gives the range. The row with the largest P − O gap is the risk worth raising with the manager.
💡 Простими словами: Дай діапазон і назви, що його розширює, — тоді торг іде про скоуп і ризик, а не про твою швидкість.
💡 In plain words: Give a range and name what widens it — then the negotiation is about scope and risk, not about how fast you work.
🗣 Як читати вголос Я оцінюю знизу вгору: розбиваю роботу на аналіз, дизайн, дані, виконання, ретести і звіт, бо саме ретести й підготовку даних зазвичай забувають. Для кожної задачі даю три числа і рахую за PERT, тож на виході маю діапазон, а не одне число. Менеджеру показую, що найбільше розхитує оцінку, наприклад нестабільний sandbox. Якщо просять швидше, я не кажу «ні», а пропоную, що можна прибрати зі скоупу і який ризик ми тоді беремо.
🗣 How to say it out loud I estimate bottom-up: I split the work into analysis, design, data, execution, retests and reporting, because retests and data preparation are what usually get forgotten. Each task gets three numbers and I use PERT, so I end up with a range rather than a single figure. I show the manager what shakes the estimate most, for example an unstable sandbox. If they ask for it faster, I do not say no; I suggest what could come out of scope and which risk we take on as a result.
▶ 5 6
46 Через які стани проходить дефект від знаходження до закриття і хто його переводить між ними? Which states does a defect go through from discovery to closure, and who moves it between them?
ДефектиDefects Junior ▶

Що це. Життєвий цикл дефекту (defect life cycle) — узгоджений у команді набір станів і дозволених переходів, через які проходить звіт у трекері. Типовий ланцюжок: New → Open (Assigned) → In Progress → Fixed (Resolved) → Retest → Closed. Якщо перевірка після виправлення не пройшла, звіт переходить у Reopened і повертається до розробника. Є й бічні виходи: Rejected (це не дефект), Duplicate, Deferred (відкладено на пізніший реліз) і Cannot Reproduce.

What it is. The defect life cycle is the set of states and allowed transitions a report goes through in the tracker, as agreed by the team. A typical chain is New → Open (Assigned) → In Progress → Fixed (Resolved) → Retest → Closed. If the check after the fix fails, the report goes to Reopened and returns to the developer. There are side exits too: Rejected (not a defect), Duplicate, Deferred (postponed to a later release) and Cannot Reproduce.

Навіщо. Статус відповідає на просте питання: у кого зараз м'яч. Тестувальник створює звіт і закриває його після confirmation testing; тріаж-зустріч або тімлід призначає виконавця й пріоритет; розробник переводить у In Progress і Fixed. Без чітких переходів баги тижнями висять у Fixed, і ніхто не знає, чи фікс уже доїхав на стенд.

Why it matters. The status answers one plain question: who holds the ball right now. The tester creates the report and closes it after confirmation testing; a triage meeting or the team lead assigns an owner and a priority; the developer moves it to In Progress and Fixed. Without clear transitions bugs sit in Fixed for weeks and nobody knows whether the fix has reached the test environment.

Приклад. Звіт «знижка не застосовується до другого товару в кошику» створено в New. На тріажі його відкрили й призначили на бекенд. Розробник позначив Fixed у збірці 2.14.3, але на стенді ще 2.14.2, тож тестувальник чекає деплою, а не перевіряє одразу. Після деплою перевірка пройшла, разом із нею прогнано регресію кошика — звіт закрито.

Example. The report "discount is not applied to the second item in the cart" is created as New. Triage opens it and assigns it to the back end. The developer marks it Fixed in build 2.14.3, but the environment still runs 2.14.2, so the tester waits for the deploy instead of checking at once. After the deploy the check passes, the cart regression runs alongside it, and the report is closed.

Підводні камені. Закривати звіт, не звіривши номер збірки з фіксом. Перевідкривати старий баг, коли з'явилась схожа, але інша проблема, — краще новий звіт із посиланням на старий. Назви станів у Jira, YouTrack чи Azure DevOps різняться, тому на співбесіді пояснюй логіку переходів, а не конкретну схему. Як написати сам звіт, розібрано в окремому гайді Bug Reporting на цьому сайті.

Pitfalls. Closing a report without matching the build number to the fix. Reopening an old bug when a similar but different problem appears — a new report that links to the old one is better. State names differ between Jira, YouTrack and Azure DevOps, so in an interview explain the logic of the transitions rather than one tool's workflow. How to write the report itself is covered in the separate Bug Reporting guide on this site.

Діаграма станів дефекту
Defect state diagram
 [New] ──тріаж──► [Open/Assigned] ──► [In Progress]
   │                    ▲                   │
   │                    │                   ▼
   │               [Reopened]           [Fixed]
   │                    ▲                   │ деплой на стенд
   │                    │ не пройшло        ▼
   │                    └────────────── [Retest]
   │                                        │ пройшло
   ▼                                        ▼
 [Rejected] [Duplicate]                 [Closed]
 [Deferred] [Cannot Reproduce]
 [New] ──triage──► [Open/Assigned] ──► [In Progress]
   │                    ▲                   │
   │                    │                   ▼
   │               [Reopened]           [Fixed]
   │                    ▲                   │ deployed to env
   │                    │ failed            ▼
   │                    └────────────── [Retest]
   │                                        │ passed
   ▼                                        ▼
 [Rejected] [Duplicate]                 [Closed]
 [Deferred] [Cannot Reproduce]
🔧 Як читати: квадратні дужки — стани, стрілки — дозволені переходи, підпис біля стрілки — подія, що його запускає. Бічні стани внизу можливі одразу з New після тріажу. Retest має лише два виходи: Closed, якщо перевірка пройшла, і Reopened, якщо ні.
🔧 How to read it: square brackets are states, arrows are allowed transitions, and a label on an arrow is the event that triggers it. The side states at the bottom are reachable straight from New after triage. Retest has only two exits: Closed when the check passes and Reopened when it does not.
💡 Простими словами: статус бага — це естафетна паличка: з нього видно, хто зараз має щось зробити.
💡 In plain words: a bug's status is a relay baton — it shows who has to act next.
🗣 Як читати вголос Для мене життєвий цикл бага — це про відповідальність. Я створюю звіт у статусі New, на тріажі йому дають пріоритет і власника, розробник веде його до Fixed. Далі м'яч знову в мене: я дивлюсь, у якій збірці фікс, дочікуюсь її на стенді і тільки тоді перевіряю, плюс проганяю регресію навколо. Пройшло — закриваю, ні — перевідкриваю з коментарем, що саме не так. Якщо бачу схожу, але нову проблему, заводжу окремий звіт і лінкую. Назви статусів у кожній компанії свої, але логіка однакова.
🗣 How to say it out loud For me the bug life cycle is about ownership. I file the report as New, triage gives it a priority and an owner, and the developer takes it to Fixed. Then the ball is back with me: I look up which build holds the fix, wait until that build is on the environment, and only then verify it, running some regression around the change as well. If it passes I close it; if not, I reopen it with a comment on what exactly is still wrong. When I see a similar but new problem I file a separate report and link them. Every company names the states differently, but the logic stays the same.
47 Чим severity відрізняється від priority і чому в одного бага вони можуть розходитися? How does severity differ from priority, and why can they point in different directions for the same bug?
ДефектиDefects Junior ▶

Що це. Severity (серйозність) за глосарієм ISTQB — ступінь впливу дефекту на роботу системи: падіння, втрата даних, неправильний розрахунок, косметика. Її зазвичай пропонує тестувальник, бо він бачив наслідок. Priority (пріоритет) — рівень бізнесової важливості й терміновості: як швидко це треба виправити. Його остаточно ставить власник продукту або тріаж, бо він знає релізні плани, клієнтів і гроші.

What it is. Severity, per the ISTQB glossary, is the degree of impact a defect has on the operation of the system: a crash, data loss, a wrong calculation, a cosmetic glitch. The tester usually proposes it because they saw the consequence. Priority is the level of business importance and urgency: how soon it has to be fixed. The product owner or the triage meeting sets it in the end, because they know the release plans, the customers and the money involved.

Навіщо розрізняти. Це дві різні осі, і саме тому шкал дві. Технічно тяжкий дефект може чекати, якщо він у рідкісному сценарії, а дрібниця може блокувати реліз, якщо її побачать усі. Коли команда плутає осі, розробники виправляють те, що гучніше звучить, а не те, що важливіше для користувачів.

Why keep them apart. These are two different axes, which is exactly why there are two scales. A technically severe defect can wait if it lives in a rare scenario, while a trivial one can block a release if everyone will see it. When a team mixes the axes, developers fix whatever sounds loudest rather than what matters most to users.

Приклад. Падіння адмінського експорту звітів за 2019 рік, яким користуються двічі на рік, — severity висока, priority низький. Помилка в назві бренду на головній сторінці в день рекламної кампанії — severity низька (нічого не ламається), priority найвищий. Решта прикладів — у матриці нижче.

Example. The admin export of 2019 reports crashes, and it is used twice a year — high severity, low priority. The brand name is misspelled on the home page on the day an ad campaign launches — low severity (nothing breaks), top priority. The other combinations are in the matrix below.

Підводні камені. Ставити Critical усім багам, щоб їх швидше взяли, — шкала знецінюється за тиждень. Вважати, що severity визначає черговість виправлення: черговість визначає priority. Шкали (Blocker/Critical/Major/Minor/Trivial чи P1–P4) у кожній команді свої, тому їх описують у тест-плані з прикладами. Детальніше про оформлення — у гайді Bug Reporting.

Pitfalls. Marking every bug Critical so it gets picked up faster — the scale loses its meaning within a week. Assuming severity decides the fixing order: priority does. Each team has its own scales (Blocker/Critical/Major/Minor/Trivial or P1–P4), so they are described in the test plan with examples. The report format itself is covered in the Bug Reporting guide.

Матриця severity × priority
Severity × priority matrix
                  │ Priority високий         │ Priority низький
──────────────────┼──────────────────────────┼─────────────────────────
Severity висока   │ Оплата карткою падає     │ Падає експорт звітів
                  │ з 500 для всіх           │ за 2019 рік в адмінці
                  │ → фікс сьогодні, hotfix  │ → у беклог, обхід є
──────────────────┼──────────────────────────┼─────────────────────────
Severity низька   │ Помилка в назві бренду   │ Відступ 2px у футері
                  │ на головній у день акції │ сторінки «Про нас»
                  │ → виправити до запуску   │ → коли буде час
                  │ High priority            │ Low priority
──────────────────┼──────────────────────────┼─────────────────────────
High severity     │ Card payment fails       │ Admin export of 2019
                  │ with 500 for everyone    │ reports crashes
                  │ → fix today, hotfix      │ → backlog, workaround
──────────────────┼──────────────────────────┼─────────────────────────
Low severity      │ Brand name misspelled on │ 2px padding off in the
                  │ home page on launch day  │ About page footer
                  │ → fix before launch      │ → when there is time
🔧 Як читати: рядки — наскільки сильно дефект б'є по системі, стовпці — наскільки терміново бізнес хоче виправлення. У кожній клітинці — приклад і рішення після стрілки. Діагональ «висока/низька» — саме ті випадки, про які люблять питати на співбесіді.
🔧 How to read it: rows show how hard the defect hits the system, columns show how urgently the business wants it fixed. Each cell holds an example and the decision after the arrow. The high/low diagonal holds exactly the cases interviewers like to ask about.
💡 Простими словами: severity — наскільки боляче, priority — наскільки терміново.
💡 In plain words: severity is how much it hurts, priority is how soon it must be fixed.
🗣 Як читати вголос Я пояснюю це як дві незалежні осі. Severity — це вплив на систему, і я як тестувальник пропоную її, бо бачив наслідок на власні очі. Priority — терміновість для бізнесу, і фінальне слово тут за продакт-овнером. Класичний приклад: друкарська помилка в логотипі на головній у день акції — дрібниця технічно, але виправляти треба негайно. А падіння рідкісного звіту в адмінці може спокійно почекати спринт. Я намагаюсь не завищувати severity, інакше команда перестає мені вірити.
🗣 How to say it out loud I explain it as two independent axes. Severity is the impact on the system, and as the tester I propose it, since I saw the consequence myself. Priority is urgency for the business, and the product owner has the final word on it. The classic case is a typo in the brand name on the home page on launch day: technically trivial, yet it has to be fixed right now. A crash in a rarely used admin report, on the other hand, can wait a sprint. I try not to inflate severity, because once I do, the team stops trusting my labels.
48 Як провести root cause analysis після інциденту на проді, щоб він не повторився? How do you run a root cause analysis after a production incident so that it does not happen again?
ДефектиDefects Senior ▶

Що це. Root cause analysis (RCA) — пошук першопричини дефекту чи інциденту, а не лише симптому. Фікс прибирає конкретний баг; RCA відповідає, чому процес дозволив йому виникнути і дійти до користувача. Найпоширеніші інструменти — «5 чому» (питати «чому?», доки відповідь не впреться в процес чи рішення) і діаграма Ісікави (fishbone), що розкладає причини за категоріями: вимоги, код, середовище, дані, процес, люди.

What it is. Root cause analysis (RCA) looks for the underlying cause of a defect or incident, not just its symptom. A fix removes one specific bug; RCA answers why the process let it be introduced and reach users. The common tools are the 5 Whys (keep asking "why?" until the answer hits a process or a decision) and the Ishikawa (fishbone) diagram, which sorts causes into categories: requirements, code, environment, data, process, people.

Як я її веду. Спершу збираю факти: таймлайн, логи, які збірки були на проді, скільки користувачів зачепило. Потім зустріч без пошуку винних (blameless) з розробником, QA і тим, хто чергував. Для кожної гілки причин формулюємо дію з власником і терміном; дія на кшталт «бути уважнішими» не приймається. Через кілька тижнів перевіряю, що дії справді виконані.

How I run it. First I gather facts: a timeline, logs, which builds were in production, how many users were affected. Then a blameless meeting with the developer, QA and whoever was on call. For each branch of causes we write an action with an owner and a deadline; an action such as "be more careful" is not accepted. A few weeks later I check that the actions were actually done.

Приклад. Частину клієнтів списали двічі за одне замовлення. Ланцюжок «5 чому» нижче веде від подвійного кліку до відсутності ідемпотентності в API оплати і прогалини в чеклісті ризиків. У підсумку чотири дії, серед них одна для QA: регресійний тест на подвійне надсилання форми.

Example. Some customers were charged twice for one order. The 5 Whys chain below leads from a double click to a payment API without idempotency and a gap in the risk checklist. The result is four actions, one of them for QA: a regression test for double form submission.

Підводні камені. Зупинитись на першому «чому» і записати причиною «розробник помилився». Шукати винного — люди перестануть ділитись фактами. Робити RCA для кожного дрібного бага: вона потрібна для інцидентів, повторюваних класів дефектів і втікачів із регресії.

Pitfalls. Stopping at the first "why" and recording "the developer made a mistake" as the cause. Hunting for someone to blame — people stop sharing facts. Running RCA for every minor bug: it pays off for incidents, recurring defect classes and bugs that slipped past regression.

«5 чому» для подвійного списання
5 Whys for a double charge
Симптом: 37 клієнтів списано двічі за одне замовлення

1. Чому? API оплати отримав два однакові запити.
2. Чому? Кнопка «Оплатити» лишалась активною, поки
   перший запит ще йшов, і клієнти клікали вдруге.
3. Чому? Під час рефакторингу форми зникло блокування
   кнопки, а code review цього не помітило.
4. Чому зміну не зловили тести? Жоден тест не
   перевіряв повторне надсилання форми.
5. Чому API прийняв дубль? Немає ідемпотентного ключа,
   і в чеклісті ризиків оплати такого пункту не було.

Дії (власник, термін):
- Idempotency-Key в API оплати        (бекенд, 2 тижні)
- блокувати кнопку до відповіді        (фронт, спринт)
- тест на подвійний сабміт у регресії  (QA, спринт)
- пункт «повторна дія» в чеклісті      (QA lead, тиждень)
Symptom: 37 customers charged twice for one order

1. Why? The payment API received two identical requests.
2. Why? The Pay button stayed enabled while the first
   request was in flight, and customers clicked again.
3. Why? A form refactoring removed the button lock,
   and code review did not notice it.
4. Why did tests miss it? No test covered submitting
   the form twice.
5. Why did the API accept a duplicate? There is no
   idempotency key, and the payment risk checklist
   had no such item.

Actions (owner, deadline):
- Idempotency-Key in the payment API  (back end, 2 weeks)
- lock the button until response      (front end, sprint)
- double-submit test in regression    (QA, sprint)
- "repeated action" checklist item    (QA lead, week)
🔧 Як читати: кожне «чому» питає про відповідь попереднього рядка. Кроки 3–5 уже не про код, а про процес: рев'ю, покриття тестами і проєктування API. Саме з таких рядків і виростають дії внизу — у кожної є власник і термін, інакше RCA лишається протоколом зустрічі.
🔧 How to read it: each "why" questions the answer on the line above. Steps 3–5 are no longer about code but about process: review, test coverage and API design. The actions at the bottom grow out of exactly those lines — each has an owner and a deadline, otherwise the RCA stays just meeting minutes.
💡 Простими словами: фікс лікує цей баг, RCA — ціле сімейство таких самих у майбутньому.
💡 In plain words: a fix cures this bug; RCA cures the whole family of similar bugs to come.
🗣 Як читати вголос Після серйозного інциденту я спершу збираю таймлайн і логи, а потім роблю зустріч у форматі без пошуку винних. Найчастіше використовую п'ять «чому»: наприклад, у нас було подвійне списання, і ланцюжок привів не до «розробник забув», а до того, що API не мав ідемпотентного ключа і ні в кого в чеклісті не було сценарію повторного кліку. Кожна дія отримує власника й дедлайн, і я через кілька тижнів дивлюсь, чи їх виконали. Для QA там майже завжди з'являється новий регресійний тест або пункт у чеклісті.
🗣 How to say it out loud After a serious incident I first put together the timeline and the logs, then hold a blameless meeting. I mostly use the five whys: once we had customers charged twice, and the chain did not end at "the developer forgot"; it ended at an API with no idempotency key and a checklist where nobody had a repeated-click scenario. Every action gets an owner and a deadline, and a few weeks later I check whether they were done. For QA there is almost always a new regression test or a new checklist item coming out of it.
49 Які знання HTTP потрібні мануальному тестувальнику, щоб зрозуміти, де баг — на фронтенді чи на бекенді? What HTTP knowledge does a manual tester need to tell whether a bug is in the front end or the back end?
ДефектиDefects Junior ▶

Що це. Мінімум, який реально потрібен: методи (GET читає, POST створює, PUT/PATCH змінює, DELETE видаляє), групи статус-кодів (2xx — успіх, 3xx — перенаправлення, 4xx — помилка запиту клієнта, 5xx — помилка сервера), заголовки на кшталт Content-Type і Authorization, а також тіло запиту й відповіді, найчастіше в JSON. Усе це видно у вкладці Network у DevTools, а будь-який запит звідти можна скопіювати як curl.

What it is. The minimum you really need: methods (GET reads, POST creates, PUT/PATCH changes, DELETE removes), status code groups (2xx success, 3xx redirect, 4xx client request error, 5xx server error), headers such as Content-Type and Authorization, and the request and response bodies, usually JSON. All of it is visible in the DevTools Network tab, and any request there can be copied as curl.

Навіщо. Це дозволяє локалізувати баг, а не просто описати симптом. Якщо сервер повернув правильні дані, а екран показує інше — проблема на фронтенді. Якщо відповідь уже неправильна або прийшов 500 — на бекенді. Якщо запит узагалі не пішов — шукай у JavaScript-помилках консолі. Такий звіт розробник бере в роботу без зайвих уточнень.

Why it matters. It lets you localise the bug instead of only describing the symptom. If the server returned correct data but the screen shows something else, the problem is in the front end. If the response is already wrong or a 500 arrives, it is the back end. If the request was never sent, look for JavaScript errors in the console. A developer can pick up such a report without follow-up questions.

Приклад. При додаванні двох одиниць товару в кошик UI мовчки нічого не робить. У Network видно POST на /cart/items зі статусом 422 і полем error: qty_exceeds_stock. Бекенд поводиться правильно: на складі одна штука. Баг на фронтенді — він не показує користувачу повідомлення про помилку. Той самий запит, відтворений через curl, іде в звіт як доказ.

Example. Adding two units of a product to the cart silently does nothing in the UI. Network shows a POST to /cart/items with status 422 and an error field qty_exceeds_stock. The back end behaves correctly: only one unit is in stock. The bug is in the front end, which never shows the user an error message. The same request replayed with curl goes into the report as evidence.

Підводні камені. Вважати, що 200 означає «все добре»: деякі API повертають 200 з помилкою в тілі. Вставляти у звіт curl з живим токеном Authorization — його треба замаскувати. Плутати 401 (не автентифікований) і 403 (автентифікований, але без прав).

Pitfalls. Assuming 200 means "all good": some APIs return 200 with an error in the body. Pasting curl with a live Authorization token into the report — mask it. Confusing 401 (not authenticated) with 403 (authenticated but not allowed).

Відтворення запиту через curl
Replaying the request with curl
# запит скопійовано з Network → Copy as cURL, токен замасковано
curl -i -X POST https://api.shop.test/v1/cart/items \
  -H "Authorization: Bearer ***" \
  -H "Content-Type: application/json" \
  -d '{"productId": 42, "qty": 2}'

# відповідь сервера
HTTP/1.1 422 Unprocessable Content
Content-Type: application/json

{"error": "qty_exceeds_stock", "available": 1}

# висновок: бекенд правий, фронтенд не показав помилку
# copied from Network → Copy as cURL, token masked
curl -i -X POST https://api.shop.test/v1/cart/items \
  -H "Authorization: Bearer ***" \
  -H "Content-Type: application/json" \
  -d '{"productId": 42, "qty": 2}'

# server response
HTTP/1.1 422 Unprocessable Content
Content-Type: application/json

{"error": "qty_exceeds_stock", "available": 1}

# verdict: back end is right, front end hid the error
🔧 Як читати: -i виводить статус і заголовки відповіді, -X POST задає метод, кожен -H додає заголовок, -d передає тіло запиту. Зворотні скісні риски в кінці рядків — перенесення команди в shell. 422 означає, що запит зрозумілий, але дані не пройшли бізнес-перевірку.
🔧 How to read it: -i prints the response status and headers, -X POST sets the method, each -H adds a header, and -d sends the request body. The backslashes at line ends continue the command in the shell. 422 means the request was understood but the data failed a business check.
💡 Простими словами: подивись у Network, що сервер відповів, — і ти знатимеш, чия це помилка.
💡 In plain words: look at what the server answered in Network, and you will know whose bug it is.
🗣 Як читати вголос Коли на екрані щось не так, я першим ділом відкриваю Network і знаходжу відповідний запит. Дивлюсь на статус і тіло відповіді: якщо сервер віддав правильні дані, а інтерфейс їх показав криво — це фронт; якщо відповідь уже погана або там п'ятсота — бекенд. Потім копіюю запит як curl, прибираю токен і вставляю у звіт, щоб розробник міг відтворити за секунди. Ще я пам'ятаю, що двісті не завжди означає успіх, і уважно читаю тіло.
🗣 How to say it out loud When something looks wrong on screen, the first thing I do is open Network and find the matching request. I check the status and the response body: if the server sent correct data and the interface rendered it badly, it is the front end; if the response is already bad or it is a five hundred, it is the back end. Then I copy the request as curl, strip the token and put it in the report so the developer can reproduce it in seconds. I also keep in mind that a two hundred is not always success, so I read the body too.
50 Як через SQL перевірити, що замовлення, оформлене в UI, правильно записалося в базу? How do you use SQL to check that an order placed in the UI was stored correctly in the database?
ДефектиDefects Middle ▶

Що це. Для мануального QA база — ще один оракул. Екран «Дякуємо за замовлення» лише каже, що фронтенд отримав успішну відповідь; чи записались правильна сума, статус, позиції і чи не з'явився дубль, видно тільки в даних. Достатньо впевнено писати SELECT із WHERE і ORDER BY, робити JOIN між таблицями, рахувати через COUNT, SUM і GROUP BY та шукати дублікати через HAVING.

What it is. For a manual QA the database is one more oracle. The "Thank you for your order" screen only says the front end got a successful response; whether the right total, status and line items were stored, and whether a duplicate appeared, can be seen only in the data. It is enough to write SELECT with WHERE and ORDER BY confidently, JOIN tables, aggregate with COUNT, SUM and GROUP BY, and find duplicates with HAVING.

Навіщо. Частина дефектів ніколи не з'являється на екрані одразу: неправильно округлена сума, яку побачить бухгалтерія, статус, що не змінився після оплати, позиція без ціни. Перевірка в базі ловить їх у день тестування, а не через місяць у звіті фінансистів.

Why it matters. Some defects never show on screen right away: a badly rounded total that accounting will see later, a status that did not change after payment, a line item without a price. A database check catches them on the day of testing rather than a month later in a finance report.

Приклад. Клієнт 1017 купує два товари з промокодом. Перший запит знаходить останнє замовлення клієнта, другий звіряє суму позицій зі збереженим total з урахуванням знижки, третій перевіряє, що за останні десять хвилин у клієнта не створилось два замовлення (наслідок подвійного кліку).

Example. Customer 1017 buys two items with a promo code. The first query finds the customer's latest order, the second compares the sum of the line items with the stored total after the discount, and the third checks that the customer did not get two orders in the last ten minutes (the result of a double click).

Підводні камені. Запускати UPDATE чи DELETE «щоб підготувати дані» на спільному стенді й ламати тести колегам. Ходити на прод без дозволу і без read-only доступу. Порівнювати гроші у float — суми зберігають у DECIMAL або в копійках, і порівнювати треба так само. Забувати про часові пояси в created_at.

Pitfalls. Running UPDATE or DELETE "to prepare data" on a shared environment and breaking colleagues' tests. Querying production without permission and without read-only access. Comparing money as float — amounts are stored as DECIMAL or in minor units, and must be compared the same way. Forgetting time zones in created_at.

Перевірочні SQL-запити
Verification SQL queries
-- 1. останнє замовлення клієнта
SELECT id, status, total, created_at
FROM orders
WHERE customer_id = 1017
ORDER BY created_at DESC
LIMIT 1;  -- очікую: status = 'paid'

-- 2. сума позицій мінус знижка = total?
SELECT o.total,
       SUM(i.qty * i.price) - o.discount AS expected
FROM orders o
JOIN order_items i ON i.order_id = o.id
WHERE o.id = 58213
GROUP BY o.total, o.discount;

-- 3. дублікати за останні 10 хвилин
SELECT customer_id, COUNT(*) AS orders_cnt
FROM orders
WHERE created_at > now() - INTERVAL '10 minutes'
GROUP BY customer_id
HAVING COUNT(*) > 1;  -- очікую: 0 рядків
-- 1. customer's latest order
SELECT id, status, total, created_at
FROM orders
WHERE customer_id = 1017
ORDER BY created_at DESC
LIMIT 1;  -- expect: status = 'paid'

-- 2. line items minus discount = total?
SELECT o.total,
       SUM(i.qty * i.price) - o.discount AS expected
FROM orders o
JOIN order_items i ON i.order_id = o.id
WHERE o.id = 58213
GROUP BY o.total, o.discount;

-- 3. duplicates in the last 10 minutes
SELECT customer_id, COUNT(*) AS orders_cnt
FROM orders
WHERE created_at > now() - INTERVAL '10 minutes'
GROUP BY customer_id
HAVING COUNT(*) > 1;  -- expect: 0 rows
🔧 Як читати: -- починає коментар у SQL. JOIN ... ON з'єднує замовлення з його позиціями за ключем order_id. GROUP BY збирає рядки в групи, а HAVING фільтрує вже групи, тому умова на COUNT(*) стоїть саме там, а не в WHERE. Синтаксис INTERVAL '10 minutes' — PostgreSQL; у MySQL це INTERVAL 10 MINUTE.
🔧 How to read it: -- starts a comment in SQL. JOIN ... ON links an order to its line items by the order_id key. GROUP BY collects rows into groups, and HAVING filters those groups, which is why the condition on COUNT(*) goes there and not into WHERE. INTERVAL '10 minutes' is PostgreSQL syntax; in MySQL it is INTERVAL 10 MINUTE.
💡 Простими словами: екран показує, що система пообіцяла; база — що вона насправді зробила.
💡 In plain words: the screen shows what the system promised; the database shows what it actually did.
🗣 Як читати вголос Я не зупиняюсь на екрані подяки після покупки, бо він лише означає, що фронт отримав успішну відповідь. Відкриваю базу з read-only доступом і дивлюсь останнє замовлення клієнта: статус, суму, час. Далі звіряю через JOIN суму позицій зі збереженим тоталом з урахуванням знижки, а ще окремим запитом із HAVING шукаю дублікати, бо подвійний клік — класика. Нічого не змінюю в спільних даних, а гроші порівнюю в тих самих одиницях, у яких вони лежать у таблиці.
🗣 How to say it out loud I do not stop at the thank-you screen after a purchase, since it only means the front end got a successful response. I open the database with read-only access and look at the customer's latest order: status, total, timestamp. Then I use a JOIN to compare the line items against the stored total after the discount, and a separate query with HAVING hunts for duplicates, because a double click is a classic. I never change shared data, and I compare money in the same units it is stored in.
51 Як вирішити, що перед тобою — баг, запит на зміну чи «так задумано»? How do you decide whether you are looking at a bug, a change request or "works as designed"?
ДефектиDefects Middle ▶

Що це. Дефект — це розбіжність між фактичною поведінкою і тестовою базою: вимогами, критеріями приймання, дизайном, стандартом чи обґрунтованим очікуванням користувача. Запит на зміну (change request) — бажання, щоб система поводилась інакше, ніж домовлено. «Так задумано» (works as designed) — поведінка відповідає базі, навіть якщо тестувальнику вона не подобається.

What it is. A defect is a mismatch between actual behaviour and the test basis: requirements, acceptance criteria, design, a standard or a reasonable user expectation. A change request is a wish for the system to behave differently from what was agreed. "Works as designed" means the behaviour matches the basis, even if the tester does not like it.

Навіщо. Від класифікації залежить, хто і коли платить за роботу. Баг виправляють у поточному релізі в межах естімейту; зміна йде в беклог, її оцінюють і пріоритезують як нову історію. Коли все підряд заводять багами, метрики якості брешуть, а суперечки на тріажі затягуються.

Why it matters. The classification decides who pays for the work and when. A bug is fixed in the current release within the estimate; a change goes to the backlog and is estimated and prioritised like a new story. When everything is filed as a bug, quality metrics lie and triage arguments drag on.

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

Example. The catalogue filter resets after moving to page two. The acceptance criteria say "the filter persists across pagination" — that is a bug. If pagination is not mentioned but the company's own mobile app keeps the filter, it is still a defect because consistency is broken, and I cite the mobile app as the oracle. If the PO deliberately chose to reset the filter and the tester just finds it inconvenient, that is an improvement proposal.

Підводні камені. Сперечатися «мені здається» замість посилання на конкретний рядок вимог або на оракул. Закривати звіт як works as designed, коли вимога сама суперечлива, — тоді дефект у вимозі, і його теж варто зафіксувати.

Pitfalls. Arguing with "I feel that" instead of pointing to a specific line of the requirements or to an oracle. Closing a report as works as designed when the requirement itself is contradictory — then the defect lives in the requirement, and that deserves a record too.

Таблиця тріажу
Triage table
Спостереження               │ Тестова база        │ Рішення
────────────────────────────┼─────────────────────┼──────────────
Фільтр скидається на стор.2 │ AC-7: «зберігається»│ Баг, Major
Фільтр скидається на стор.2 │ нічого; моб. версія │ Баг (оракул:
                            │ фільтр зберігає     │ узгодженість)
Сортування за замовч. — ціна│ PO вирішив: новизна │ WAD → CR
                            │                     │ у беклог
Кнопка «Купити» сіра, хоча  │ AC-3 суперечить     │ Дефект вимоги,
товар є на складі           │ макету              │ питання до BA
Observation                 │ Test basis          │ Decision
────────────────────────────┼─────────────────────┼──────────────
Filter resets on page 2     │ AC-7: "persists"     │ Bug, Major
Filter resets on page 2     │ silent; mobile app  │ Bug (oracle:
                            │ keeps the filter    │ consistency)
Default sort is by price    │ PO chose: by newest │ WAD → CR
                            │                     │ to backlog
Buy button grey though      │ AC-3 contradicts    │ Requirement
item is in stock            │ the mockup          │ defect, ask BA
🔧 Як читати: ліворуч — що побачив тестувальник, посередині — на що можна спертися, праворуч — висновок. Однакове спостереження в перших двох рядках отримує різне обґрунтування, бо тестова база різна. WAD → CR означає: поведінка правильна, але пропозицію оформлюють як окремий запит на зміну.
🔧 How to read it: the left column is what the tester saw, the middle is what can be relied on, the right is the conclusion. The same observation in the first two rows gets a different justification because the test basis differs. WAD → CR means the behaviour is correct, but the suggestion is filed as a separate change request.
💡 Простими словами: баг — це «не так, як домовлялись», зміна — «хочемо домовитись інакше».
💡 In plain words: a bug is "not what we agreed"; a change is "let us agree on something else".
🗣 Як читати вголос У суперечках на тріажі я завжди відштовхуюсь від тестової бази. Якщо можу показати рядок у критеріях приймання чи в макеті, який поведінка порушує, — це баг. Якщо прямої вимоги немає, шукаю інший оракул, наприклад, як та сама функція працює в нашому мобільному застосунку. А коли поведінка відповідає рішенню продакт-овнера, я не тисну: оформлюю це як пропозицію в беклог. І окремо фіксую випадки, коли самі вимоги суперечать одна одній, бо це теж дефект, тільки знайдений рано.
🗣 How to say it out loud In triage arguments I always start from the test basis. If I can point to a line in the acceptance criteria or the mockup that the behaviour breaks, it is a bug. If there is no direct requirement, I look for another oracle, for instance how the same feature works in our mobile app. When the behaviour matches a decision the product owner made, I do not push; I file it as a suggestion for the backlog. And I separately record cases where the requirements contradict each other, because that is a defect as well, just one caught early.
▶ 6 11
52 Що робить тестувальник протягом Scrum-спринту, якщо тестування в Agile — справа всієї команди? What does a tester do during a Scrum sprint if testing in Agile is the whole team's job?
ПроцесProcess Middle ▶

Що це. Agile-тестування — це тестування, вбудоване в кожну ітерацію, а не окрема фаза після розробки. Підхід whole-team означає, що за якість відповідає вся команда: розробники пишуть компонентні тести, PO уточнює критерії приймання, а тестувальник веде тестову експертизу, ставить незручні питання і допомагає іншим тестувати краще. Роль QA не зникає — вона зсувається від «перевірити готове» до «не дати зробити неправильно».

What it is. Agile testing is testing built into every iteration rather than a separate phase after development. The whole-team approach means the entire team owns quality: developers write component tests, the PO sharpens acceptance criteria, and the tester brings testing expertise, asks the awkward questions and helps others test better. The QA role does not disappear — it shifts from "check what is finished" to "prevent building the wrong thing".

Навіщо. Двотижневий спринт не залишає часу на тижневу регресію наприкінці. Якщо тестування почнеться в останні два дні, історії масово переїдуть у наступний спринт, а команда отримає «міні-водоспад» усередині Scrum.

Why it matters. A two-week sprint leaves no room for a week-long regression at the end. If testing starts in the last two days, stories roll over to the next sprint en masse and the team ends up with a mini-waterfall inside Scrum.

Приклад. На рефайнменті тестувальник помічає, що історія «оплата частинами» не каже, що робити при поверненні товару, і це питання потрапляє в критерії ще до оцінки. На дейлі він каже не «тестую», а «API розстрочки перевірив, чекаю збірку з UI, блокер — немає тестового банку». Для планування покриття корисні квадранти Agile-тестування (Marick, Crispin і Gregory): технологічні тести, що підтримують команду, бізнес-тести, дослідницькі та нефункціональні перевірки.

Example. At refinement the tester notices that the "pay in instalments" story says nothing about refunds, and that question lands in the criteria before estimation. At the daily they do not say "testing" but "instalment API checked, waiting for the UI build, blocker — no test bank account". For planning coverage, the Agile testing quadrants (Marick, Crispin and Gregory) help: technology-facing tests that support the team, business-facing tests, exploratory and non-functional checks.

Підводні камені. Тестувальник як «воротар», який у п'ятницю вирішує, чи випускати, — ознака того, що whole-team не працює. Друга пастка — вважати, що в Agile немає документації: тест-план стає легшим, але критерії, чекліст регресії й нотатки сесій нікуди не зникають.

Pitfalls. A tester acting as a gatekeeper who decides on Friday whether to ship is a sign the whole-team approach is not working. The second trap is believing Agile has no documentation: the test plan gets lighter, but criteria, a regression checklist and session notes are still there.

Активності QA по днях спринту
QA activities across the sprint
Спринт 10 робочих днів
День 1   Планування: оцінка тестування в story points,
         ризики, тестові дані, що автоматизуємо
Дні 1-3  Тест-ідеї з AC, тестові дані, стенд;
         три аміго для нових історій
Дні 2-8  Тестування кожної історії одразу після
         мерджу; API раніше за UI; баги в дошці
Дні 4-8  Рефайнмент наступного спринту: питання
         до AC, приклади, тестованість
Дні 8-9  Регресія зміненої зони, дослідницькі сесії
День 10  Review: показуємо працююче; Retro: чому
         баг втік, що змінити в процесі
Sprint of 10 working days
Day 1     Planning: test effort in story points,
          risks, test data, what we automate
Days 1-3  Test ideas from AC, test data, environment;
          three amigos for new stories
Days 2-8  Test each story right after merge;
          API before UI; bugs on the board
Days 4-8  Refinement of next sprint: questions
          on AC, examples, testability
Days 8-9  Regression of changed area, exploratory sessions
Day 10    Review: demo what works; Retro: why a bug
          escaped, what to change in the process
🔧 Як читати: ліва колонка — дні спринту, права — що робить тестувальник. Головне тут перекриття: тестування йде паралельно з розробкою з другого дня, а рефайнмент наступного спринту — паралельно з поточною роботою. Великої «фази тестування» в кінці немає.
🔧 How to read it: the left column is the sprint day, the right one is what the tester does. The point is the overlap: testing runs in parallel with development from day two, and refinement of the next sprint runs alongside current work. There is no big "testing phase" at the end.
💡 Простими словами: в Agile тестувальник з'являється не тоді, коли код готовий, а тоді, коли історію ще тільки обговорюють.
💡 In plain words: in Agile the tester shows up not when the code is ready, but when the story is still being discussed.
🗣 Як читати вголос Для мене Agile-тестування — це коли я не чекаю кінця спринту. Я вже на рефайнменті розбираю історію і питаю про крайові випадки, на плануванні закладаю час на тестові дані й стенд, а кожну історію тестую одразу після мерджу, часто спершу через API. За якість відповідає вся команда: розробники пишуть свої тести, я допомагаю вирішити, що і як перевіряти. Якщо баг проскочив у прод, ми розбираємо це на ретро, а не шукаємо винного серед тестувальників.
🗣 How to say it out loud To me Agile testing means I do not wait for the end of the sprint. At refinement I already take the story apart and ask about edge cases, at planning I reserve time for test data and the environment, and I test every story right after it is merged, often through the API first. The whole team owns quality: developers write their own tests, and I help decide what to check and how. If a bug slips into production, we discuss it at the retro instead of looking for a guilty tester.
53 Як проходить зустріч «трьох аміго» і що з неї має вийти для тестування? How does a three amigos session run, and what should testing get out of it?
ПроцесProcess Middle ▶

Що це. Три аміго — коротка зустріч (15–30 хвилин) трьох перспектив навколо однієї історії до початку розробки: бізнесу (PO або BA — що і навіщо), розробки (як це зробити і що технічно ризиковано) і тестування (що може піти не так). Учасників може бути більше трьох, важливі саме перспективи, а не кількість людей.

What it is. Three amigos is a short meeting (15–30 minutes) of three perspectives around one story before development starts: business (PO or BA — what and why), development (how to build it and what is technically risky) and testing (what can go wrong). There can be more than three people; what matters is the perspectives, not the headcount.

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

Why it matters. Most "bugs" in new features are really different readings of a requirement. When those gaps are found at the table, they cost a conversation rather than rewritten code and another round of testing.

Приклад. Історія: «Як покупець я хочу зберегти картку, щоб платити швидше». Тестувальник питає, що буде з простроченою карткою і чи можна зберегти дві однакові; розробник уточнює, що номер картки зберігає платіжний провайдер, а ми маємо лише токен. Результат зустрічі — конкретні приклади, які стають критеріями приймання та першими тест-кейсами. Популярний формат — Example Mapping: жовта картка для історії, сині для правил, зелені для прикладів, червоні для відкритих питань.

Example. Story: "As a shopper I want to save my card so I can pay faster". The tester asks what happens to an expired card and whether the same card can be saved twice; the developer clarifies that the card number is stored by the payment provider and we only keep a token. The output is concrete examples that become acceptance criteria and the first test cases. A popular format is Example Mapping: a yellow card for the story, blue ones for rules, green for examples, red for open questions.

Підводні камені. Зустріч без результату на папері швидко забувається — фіксуйте приклади в самій історії. І не перетворюйте три аміго на оцінку або дизайн архітектури: якщо червоних карток забагато, історія не готова і її варто повернути PO.

Pitfalls. A meeting with no written output is forgotten quickly — record the examples in the story itself. And do not turn three amigos into estimation or architecture design: if there are too many red cards, the story is not ready and should go back to the PO.

Example Mapping для історії «зберегти картку»
Example Mapping for the save-card story
[ІСТОРІЯ] Зберегти картку для швидкої оплати
[ПРАВИЛО] Зберігаємо лише після успішної оплати
   [ПРИКЛАД] оплата пройшла, чекбокс увімкнено → картка в профілі
   [ПРИКЛАД] оплату відхилено → картку не збережено
[ПРАВИЛО] Одна картка — один запис
   [ПРИКЛАД] та сама картка вдруге → запис не дублюється
[ПРАВИЛО] Прострочена картка не пропонується
   [ПРИКЛАД] термін 03/24, сьогодні 04/24 → прихована в оплаті
[ПИТАННЯ] Чи попереджаємо за місяць до закінчення терміну?
[ПИТАННЯ] Скільки карток максимум?
[STORY] Save a card for faster checkout
[RULE] Save only after a successful payment
   [EXAMPLE] payment ok, checkbox on → card in profile
   [EXAMPLE] payment declined → card not saved
[RULE] One card — one record
   [EXAMPLE] same card again → no duplicate record
[RULE] Expired card is not offered
   [EXAMPLE] expiry 03/24, today 04/24 → hidden at checkout
[QUESTION] Do we warn a month before expiry?
[QUESTION] What is the maximum number of cards?
🔧 Як читати: кожне правило має щонайменше один приклад, а приклад — це майже готовий тест: вхідні умови і очікуваний результат. Питання без відповіді означають, що історію ще рано брати в спринт або що PO має вирішити до початку розробки.
🔧 How to read it: every rule has at least one example, and an example is almost a finished test: the input conditions and the expected result. Unanswered questions mean the story is not ready for the sprint yet, or the PO must decide before development starts.
💡 Простими словами: три аміго — це п'ятнадцять хвилин, які заощаджують кілька днів переробок.
💡 In plain words: three amigos is fifteen minutes that save several days of rework.
🗣 Як читати вголос Три аміго я сприймаю як найдешевше тестування в усьому процесі. Ми збираємося втрьох — бізнес, розробник і я — і проходимо історію на прикладах. Моє завдання — питати «а що як»: прострочена картка, повторне збереження, відмова банку. Розробник часто одразу каже, що технічно неможливо або ризиковано. На виході в нас правила, приклади і список відкритих питань. Приклади я переношу в критерії приймання, і вони ж стають моїми першими тестами.
🗣 How to say it out loud I see three amigos as the cheapest testing in the whole process. The three of us — business, a developer and me — walk through the story with examples. My job is to ask "what if": an expired card, saving it twice, the bank declining. The developer often says straight away what is technically impossible or risky. We leave with rules, examples and a list of open questions. I move the examples into the acceptance criteria, and they also become my first tests.
54 Якими мають бути критерії приймання, щоб за ними можна було одразу писати тести? What should acceptance criteria look like so you can write tests from them straight away?
ПроцесProcess Junior ▶

Що це. Критерії приймання (acceptance criteria, AC) — умови, які конкретна історія має виконати, щоб PO її прийняв. Вони описують поведінку з погляду користувача, а не реалізацію. Пишуть їх двома способами: списком правил («знижка не поєднується з іншими промокодами») або сценаріями у форматі Given/When/Then.

What it is. Acceptance criteria (AC) are the conditions a specific story must meet for the PO to accept it. They describe behaviour from the user's point of view, not the implementation. They are written in two ways: as a list of rules ("the discount cannot be combined with other promo codes") or as Given/When/Then scenarios.

Навіщо. Для тестувальника AC — головна тестова основа (test basis) історії: з кожного критерію виходить щонайменше одна позитивна і одна негативна перевірка. Якщо критерій не можна перевірити — «швидко», «зручно», «коректно» — його треба переписати до початку розробки. Це частина літери T (Testable) у моделі INVEST.

Why it matters. For a tester AC are the main test basis of a story: every criterion yields at least one positive and one negative check. If a criterion cannot be verified — "fast", "convenient", "correctly" — it must be rewritten before development starts. This is the T (Testable) in the INVEST model.

Приклад. Історія «Як покупець я хочу застосувати промокод у кошику». Поганий критерій: «промокод працює правильно». Хороші: «код знижує суму на вказаний відсоток», «прострочений код показує повідомлення і не змінює суму», «код не чутливий до регістру». Кожен із них одразу підказує тестові дані та очікуваний результат.

Example. Story: "As a shopper I want to apply a promo code in the cart". A bad criterion: "the promo code works correctly". Good ones: "the code reduces the total by the stated percentage", "an expired code shows a message and leaves the total unchanged", "the code is case-insensitive". Each one immediately suggests test data and an expected result.

Підводні камені. AC не замінюють Definition of Done: DoD однаковий для всіх історій, а AC — унікальні для однієї. Ще одна помилка — вважати, що AC охоплюють усе: тестувальник додає крайові випадки й нефункціональні ризики, про які в критеріях не написали.

Pitfalls. AC do not replace the Definition of Done: the DoD is the same for every story, while AC are unique to one. Another mistake is assuming AC cover everything: the tester adds edge cases and non-functional risks the criteria never mention.

Історія, критерії та тести з них
Story, criteria and the tests derived from them
Історія: застосувати промокод у кошику
AC1  Код SAVE10 знижує суму на 10%
AC2  Прострочений код → «Термін дії коду минув»,
     сума не змінюється
AC3  Регістр не має значення (save10 = SAVE10)
AC4  Лише один код на замовлення

Тести
T1  Кошик 1000 грн + SAVE10     → 900 грн      (AC1)
T2  Кошик 1000 грн + OLD5       → 1000 грн,
    повідомлення про термін                     (AC2)
T3  Кошик 1000 грн + save10     → 900 грн      (AC3)
T4  SAVE10, потім WELCOME5      → другий код
    відхилено, 900 грн                          (AC4)
Story: apply a promo code in the cart
AC1  Code SAVE10 reduces the total by 10%
AC2  Expired code → "This code has expired",
     total unchanged
AC3  Case does not matter (save10 = SAVE10)
AC4  Only one code per order

Tests
T1  Cart 1000 UAH + SAVE10      → 900 UAH      (AC1)
T2  Cart 1000 UAH + OLD5        → 1000 UAH,
    expiry message                              (AC2)
T3  Cart 1000 UAH + save10      → 900 UAH      (AC3)
T4  SAVE10, then WELCOME5       → second code
    rejected, 900 UAH                           (AC4)
🔧 Як читати: верхній блок — критерії з номерами, нижній — тести з конкретними даними і посиланням на критерій у дужках. Таке посилання дає простеньку трасованість: видно, що кожен критерій покритий, і якщо AC3 зміниться, одразу зрозуміло, який тест оновити.
🔧 How to read it: the top block is the numbered criteria, the bottom one is tests with concrete data and a reference to the criterion in brackets. That reference gives simple traceability: you see every criterion is covered, and if AC3 changes you know right away which test to update.
💡 Простими словами: якщо з критерію не виходить тест із конкретним числом або повідомленням, критерій ще не дописаний.
💡 In plain words: if a criterion does not give you a test with a concrete number or message, the criterion is not finished yet.
🗣 Як читати вголос Критерії приймання — це мій основний вхід для тестів по історії. Я перевіряю, щоб кожен критерій можна було однозначно перевірити: не «працює правильно», а «сума зменшується на десять відсотків» або «з'являється таке-то повідомлення». Якщо бачу слова на кшталт «швидко» чи «зручно», прошу PO дати число або приклад. Далі з кожного критерію роблю хоча б позитивний і негативний тест і ставлю посилання на номер критерію. Але я пам'ятаю, що AC — це мінімум, крайові випадки я додаю сам.
🗣 How to say it out loud Acceptance criteria are my main input for testing a story. I make sure each one can be checked unambiguously: not "works correctly" but "the total drops by ten percent" or "this exact message appears". When I see words like "fast" or "convenient", I ask the PO for a number or an example. Then from each criterion I build at least one positive and one negative test and tag it with the criterion number. But I remember that the AC are the minimum; I add the edge cases myself.
55 Чим Definition of Ready відрізняється від Definition of Done і що в обох має бути від тестування? How does the Definition of Ready differ from the Definition of Done, and what should testing contribute to each?
ПроцесProcess Middle ▶

Що це. Definition of Ready (DoR) — домовленість команди про те, коли історію можна брати в спринт: вона зрозуміла, оцінена, має критерії й не заблокована. Definition of Done (DoD) — спільний для всіх історій список того, що має бути зроблено, щоб інкремент вважався завершеним. DoD офіційно входить у Scrum Guide як зобов'язання щодо інкременту; DoR — поширена практика, яку Scrum Guide не вимагає.

What it is. The Definition of Ready (DoR) is the team's agreement on when a story can enter a sprint: it is understood, estimated, has criteria and is not blocked. The Definition of Done (DoD) is a checklist shared by all stories of what must be finished for the increment to count as complete. The DoD is formally part of the Scrum Guide as the commitment for the Increment; the DoR is a common practice the Scrum Guide does not require.

Навіщо. DoR захищає вхід спринту від сирих історій, DoD — вихід від «майже готового». Без DoD «готово» означає для розробника «код змерджено», а для PO — «можна показувати клієнтам», і ця різниця вилазить на демо.

Why it matters. The DoR guards the sprint entrance against half-baked stories; the DoD guards the exit against "almost done". Without a DoD, "done" means "code merged" to a developer and "ready for customers" to the PO, and that gap surfaces at the demo.

Приклад. Від тестування в DoR варто внести: критерії перевірювані, відомі тестові дані й доступи, зрозуміло, на якому стенді тестувати. У DoD — усі AC перевірені, автотести на нову логіку є і зелені, немає відкритих дефектів severity critical і major за цією історією, регресія зміненої зони пройдена.

Example. Testing should put into the DoR: criteria are testable, test data and access are known, and it is clear which environment to test on. Into the DoD: all AC verified, automated tests for the new logic exist and are green, no open critical or major defects for the story, regression of the changed area passed.

Підводні камені. DoR, перетворений на бюрократичну браму, гальмує команду — історію з одним відкритим питанням часто можна взяти, якщо відповідь буде до середини спринту. Критерії приймання не є частиною DoD: вони описують конкретну історію, а DoD — загальну планку якості.

Pitfalls. A DoR turned into a bureaucratic gate slows the team down — a story with one open question can often be taken if the answer arrives by mid-sprint. Acceptance criteria are not part of the DoD: they describe one story, while the DoD is the general quality bar.

Приклади DoR і DoD команди
A team's DoR and DoD examples
Definition of Ready (історія)
[ ] Історія у форматі «хто / що / навіщо»
[ ] AC записані і перевірювані (без «швидко»)
[ ] Дизайн і тексти погоджені
[ ] Залежності від інших команд зняті
[ ] Відомо, які тестові дані й доступи потрібні
[ ] Оцінена командою, влазить у спринт

Definition of Done (для кожної історії)
[ ] Код пройшов code review
[ ] Компонентні тести нової логіки зелені в CI
[ ] Усі AC перевірені на стенді QA
[ ] Немає відкритих critical/major дефектів
[ ] Регресія зміненої зони пройдена
[ ] Документація/release notes оновлені
Definition of Ready (story)
[ ] Story in "who / what / why" form
[ ] AC written and testable (no "fast")
[ ] Design and copy agreed
[ ] Dependencies on other teams cleared
[ ] Required test data and access are known
[ ] Estimated by the team, fits into a sprint

Definition of Done (every story)
[ ] Code has passed code review
[ ] Component tests for new logic green in CI
[ ] All AC verified on the QA environment
[ ] No open critical/major defects
[ ] Regression of the changed area passed
[ ] Docs/release notes updated
🔧 Як читати: обидва списки — чекліст, який відмічають для кожної історії. Верхній перевіряють на рефайнменті чи плануванні, нижній — перед тим, як перенести картку в колонку Done. Пункти про тестування видно в обох: у DoR це підготовка до тестування, у DoD — його результат.
🔧 How to read it: both lists are checklists ticked for every story. The top one is checked at refinement or planning, the bottom one before the card moves to Done. Testing items appear in both: in the DoR it is preparation for testing, in the DoD it is the result.
💡 Простими словами: DoR — «можна починати», DoD — «можна вважати готовим». Між ними — робота спринту.
💡 In plain words: the DoR says "we can start", the DoD says "we can call it finished". The sprint's work sits between them.
🗣 Як читати вголос Я пояснюю це як вхід і вихід спринту. Definition of Ready каже, коли історію можна брати: є зрозумілі критерії, погоджений дизайн, я знаю, які дані й доступи мені знадобляться. Definition of Done — одна планка для всіх історій: код переглянуто, автотести зелені, критерії перевірено, критичних багів немає. DoD прописаний у Scrum Guide, а DoR — практика, яку команди додають самі. І я стежу, щоб DoR не став бюрократією, яка блокує роботу через одне дрібне питання.
🗣 How to say it out loud I explain it as the sprint's entrance and exit. The Definition of Ready says when a story can be taken: clear criteria, agreed design, and I know which data and access I will need. The Definition of Done is one bar for all stories: code reviewed, automated tests green, criteria verified, no critical bugs. The DoD is in the Scrum Guide, while the DoR is a practice teams add themselves. And I watch that the DoR does not turn into bureaucracy that blocks work over one small question.
56 Що таке BDD насправді — підхід до спільного розуміння чи просто Gherkin для автотестів? What is BDD really — an approach to shared understanding or just Gherkin for automated tests?
ПроцесProcess Middle ▶

Що це. Behaviour-Driven Development — підхід, у якому поведінку системи описують конкретними прикладами, зрозумілими бізнесу, розробці й тестуванню. У ньому три практики: discovery (обговорення прикладів, наприклад на трьох аміго), formulation (запис прикладів мовою Gherkin — Given/When/Then) і automation (перетворення сценаріїв на виконувані тести через Cucumber, SpecFlow, Behave тощо).

What it is. Behaviour-Driven Development is an approach where system behaviour is described through concrete examples that business, development and testing all understand. It has three practices: discovery (discussing examples, for instance at three amigos), formulation (writing the examples in Gherkin — Given/When/Then) and automation (turning scenarios into executable tests with Cucumber, SpecFlow, Behave and so on).

Навіщо. Сценарії стають живою документацією: якщо поведінка зміниться, а сценарій ні, тест впаде. Бізнес читає ту саму специфікацію, яку виконує CI, і розбіжність між «що хотіли» та «що зробили» стає видимою.

Why it matters. Scenarios become living documentation: if behaviour changes and the scenario does not, the test fails. The business reads the same specification that CI executes, so the gap between "what we wanted" and "what we built" becomes visible.

Приклад. Для правила «безкоштовна доставка від 1000 грн» пишемо декларативний сценарій — про бізнес-правило, а не про кліки. Імперативний варіант («я клікаю кнопку з id cart, вводжу 1000 у поле…») читається як скрипт і ламається від кожної зміни UI.

Example. For the rule "free delivery from 1000 UAH" we write a declarative scenario — about the business rule, not about clicks. The imperative version ("I click the button with id cart, I type 1000 into the field…") reads like a script and breaks with every UI change.

Підводні камені. Найчастіша помилка — «BDD без розмов»: тестувальник сам пише .feature-файли після розробки, і Gherkin стає лише зайвим шаром над автотестами. Друга — сотні сценаріїв на кожну дрібницю: Gherkin варто залишати для бізнес-правил, а перевірки полів тестувати нижче.

Pitfalls. The most common mistake is "BDD without conversations": a tester writes .feature files alone after development, and Gherkin becomes an extra layer on top of automation. The second is hundreds of scenarios for every detail: keep Gherkin for business rules and test field checks at lower levels.

Декларативний сценарій Gherkin
A declarative Gherkin scenario
Feature: Безкоштовна доставка
  # Правило з Example Mapping: від 1000 грн доставка 0

  Scenario Outline: Вартість доставки залежить від суми
    Given у кошику товари на <сума> грн
    When покупець переходить до оформлення
    Then вартість доставки <доставка> грн

    Examples:
      | сума | доставка |
      | 999  | 80       |
      | 1000 | 0        |
Feature: Free delivery
  # Rule from Example Mapping: from 1000 UAH delivery is 0

  Scenario Outline: Delivery cost depends on the total
    Given the cart holds goods worth <total> UAH
    When the shopper proceeds to checkout
    Then the delivery cost is <delivery> UAH

    Examples:
      | total | delivery |
      | 999   | 80       |
      | 1000  | 0        |
🔧 Як читати: ключові слова Gherkin (Feature, Scenario Outline, Given, When, Then, Examples) лишаються англійською, текст кроків може бути будь-якою мовою. Scenario Outline виконується для кожного рядка таблиці Examples, а значення підставляються в місця з кутовими дужками. Дві межі — 999 і 1000 — це аналіз граничних значень, записаний як специфікація.
🔧 How to read it: the Gherkin keywords (Feature, Scenario Outline, Given, When, Then, Examples) stay in English; step text can be in any language. A Scenario Outline runs once per row of the Examples table, and the values are substituted into the angle-bracket slots. The two edges, 999 and 1000, are boundary value analysis written down as a specification.
💡 Простими словами: BDD — це спершу розмова на прикладах, потім запис, і лише потім автоматизація. Без першого кроку це просто незручний синтаксис тестів.
💡 In plain words: BDD is a conversation with examples first, then writing them down, and only then automation. Without the first step it is just awkward test syntax.
🗣 Як читати вголос Для мене BDD — насамперед про спільне розуміння, а Gherkin тут лише формат запису. Ми з PO і розробником обговорюємо правило на прикладах, записуємо їх як Given, When, Then, а потім ці сценарії автоматизуються і живуть як документація. Я намагаюся писати декларативно: про те, що має статися в бізнесі, а не про те, куди клікнути. Бачив проєкти, де тестувальник сам писав feature-файли після релізу, — користі від цього нуль, тільки ще один шар підтримки.
🗣 How to say it out loud To me BDD is first about shared understanding; Gherkin is only the notation. The PO, a developer and I discuss a rule through examples, write them as Given, When, Then, and later those scenarios are automated and live on as documentation. I try to write declaratively: about what should happen in business terms, not where to click. I have seen projects where a tester wrote the feature files alone after the release, and it brought nothing except one more layer to maintain.
57 Як виглядає цикл Red-Green-Refactor у TDD на маленькому прикладі і що він дає тестувальнику? What does the Red-Green-Refactor cycle of TDD look like on a small example, and what does it give a tester?
ПроцесProcess Middle ▶

Що це. Test-Driven Development — практика розробки, де тест пишуть до коду короткими циклами. Red: пишемо один маленький тест, запускаємо і бачимо, що він падає з очікуваної причини. Green: пишемо мінімальний код, щоб тест пройшов. Refactor: прибираємо дублювання і покращуємо назви, не змінюючи поведінку, — тести мають лишатися зеленими.

What it is. Test-Driven Development is a development practice where the test is written before the code, in short cycles. Red: write one small test, run it and see it fail for the expected reason. Green: write the minimal code to make it pass. Refactor: remove duplication and improve names without changing behaviour — the tests must stay green.

Навіщо. TDD змушує продумати поведінку і межі до реалізації, а код виходить тестованим за побудовою. Для тестувальника це означає, що базові випадки вже перевірені на рівні компонента, тож ручне і системне тестування можна зосередити на інтеграціях, сценаріях і ризиках.

Why it matters. TDD forces you to think through behaviour and boundaries before the implementation, and the code comes out testable by construction. For a tester it means the basic cases are already checked at component level, so manual and system testing can focus on integrations, scenarios and risks.

Приклад. Функція isAdult для реєстрації з обмеженням 18+. Спершу тест на 18 — червоний, бо функції ще немає. Потім найпростіший код і другий тест на 17, який змушує написати справжню умову. Наостанок рефакторинг: магічне число стає константою. Тестувальник може підказати розробнику граничні значення 17 і 18 ще до першого рядка коду.

Example. An isAdult function for an 18+ sign-up rule. First a test for 18 — red, because the function does not exist yet. Then the simplest code, and a second test for 17 that forces a real condition. Finally a refactor: the magic number becomes a constant. A tester can suggest the boundary values 17 and 18 to the developer before the first line of code.

Підводні камені. TDD не гарантує 100% покриття і не замінює тестування: тести перевіряють лише те, що розробник уявив. Висока покриттєвість, досягнута TDD, нічого не каже про пропущені вимоги чи інтеграційні дефекти. І пропускати фазу Red небезпечно — тест, який жодного разу не падав, міг би нічого не перевіряти.

Pitfalls. TDD does not guarantee full code coverage and does not replace testing: the tests check only what the developer imagined. High coverage reached through TDD says nothing about missed requirements or integration defects. And skipping the Red step is risky — a test that has never failed might not be checking anything.

Три кроки циклу на JavaScript (Jest)
Three steps of the cycle in JavaScript (Jest)
// 1. RED — тест є, функції ще немає → падає
test('18 років — повнолітній', () => {
  expect(isAdult(18)).toBe(true);
});

// 2. GREEN — мінімум, щоб пройти; тест на 17
//    одразу покаже, що return true замало
test('17 років — неповнолітній', () => {
  expect(isAdult(17)).toBe(false);
});
function isAdult(age) { return age >= 18; }

// 3. REFACTOR — поведінка та сама, тести зелені
const ADULT_AGE = 18;
function isAdult(age) { return age >= ADULT_AGE; }
// 1. RED — test exists, function does not → fails
test('18 years old is an adult', () => {
  expect(isAdult(18)).toBe(true);
});

// 2. GREEN — minimum to pass; the test for 17
//    shows at once that return true is not enough
test('17 years old is a minor', () => {
  expect(isAdult(17)).toBe(false);
});
function isAdult(age) { return age >= 18; }

// 3. REFACTOR — same behaviour, tests stay green
const ADULT_AGE = 18;
function isAdult(age) { return age >= ADULT_AGE; }
🔧 Розбір синтаксису: test(назва, функція) реєструє тест у Jest, expect(x).toBe(y) порівнює значення строгою рівністю. Крок 2 показує тріангуляцію: другий тест із протилежним очікуванням не дає «обдурити» перший, повернувши константу. На кроці 3 змінюється лише запис, тому обидва тести мусять лишитися зеленими.
🔧 Syntax breakdown: test(name, fn) registers a test in Jest, and expect(x).toBe(y) compares values with strict equality. Step 2 shows triangulation: a second test with the opposite expectation stops you from "cheating" the first one by returning a constant. Step 3 changes only the wording of the code, so both tests must remain green.
💡 Простими словами: спершу доведи, що тест уміє падати, потім зроби його зеленим, потім прибери за собою.
💡 In plain words: first prove the test can fail, then make it green, then clean up after yourself.
🗣 Як читати вголос TDD — це цикл Red, Green, Refactor. Розробник пише маленький тест, бачить, що він червоний, дописує мінімум коду, щоб він позеленів, і потім чистить код, не ламаючи тестів. На прикладі перевірки віку: тест на вісімнадцять, тест на сімнадцять, і вже потім константа замість числа. Я як тестувальник корисний тут тим, що підказую межі ще до коду. Але я не вважаю, що TDD дає стовідсоткове покриття чи знімає потребу в тестуванні: інтеграції і сценарії все одно на мені.
🗣 How to say it out loud TDD is the Red, Green, Refactor cycle. A developer writes a small test, sees it go red, adds the minimum code to turn it green, and then tidies the code without breaking the tests. With an age check: a test for eighteen, a test for seventeen, and only then a constant instead of the number. As a tester I help by suggesting the boundaries before any code exists. But I do not believe TDD gives a hundred percent coverage or removes the need for testing: integrations and scenarios are still mine.
58 Що конкретно означає shift-left і наскільки дешевше знаходити дефект раніше? What exactly does shift-left mean, and how much cheaper is it to find a defect earlier?
ПроцесProcess Middle ▶

Що це. Shift-left — перенесення тестових активностей якомога раніше в життєвий цикл: рев'ю вимог і дизайну, три аміго, статичний аналіз, компонентні та API-тести ще до готового UI, вимоги до тестованості на етапі архітектури. Це пряме застосування третього принципу ISTQB: раннє тестування заощаджує час і гроші.

What it is. Shift-left means moving testing activities as early as possible in the life cycle: reviewing requirements and design, three amigos, static analysis, component and API tests before the UI is ready, testability requirements at the architecture stage. It is a direct application of the third ISTQB principle: early testing saves time and money.

Навіщо. Чим пізніше знайдено дефект, тим більше роботи він тягне за собою: переписати вимогу, код, тести, повторно протестувати, випустити хотфікс, а іноді ще й відшкодувати клієнтам. Проте популярні множники на кшталт «у 100 разів дорожче» походять зі старих досліджень (Boehm, 1970–80-ті) на проєктах іншого типу і сьогодні оскаржуються, тож на співбесіді краще говорити якісно, без точних коефіцієнтів.

Why it matters. The later a defect is found, the more work it drags along: rewriting the requirement, the code and the tests, retesting, shipping a hotfix, sometimes compensating customers. However, popular multipliers such as "100 times more expensive" come from old studies (Boehm, 1970s–80s) on very different projects and are disputed today, so in an interview it is better to argue qualitatively, without precise ratios.

Приклад. У вимозі сказано «повернення коштів протягом 14 днів», але не сказано, від якої дати — оплати чи доставки. На рев'ю вимоги це одне питання в коментарі. Після релізу це суперечка з клієнтами, зміна логіки, міграція даних і повторна регресія.

Example. A requirement says "refund within 14 days" but not from which date — payment or delivery. At requirement review that is one question in a comment. After release it is a dispute with customers, a logic change, a data migration and another regression round.

Підводні камені. Shift-left не означає «тестувальник приходить раніше і робить те саме»: змінюється тип роботи — більше запитань, прикладів і профілактики. Він також не скасовує shift-right: моніторинг, feature flags і канаркові релізи ловлять те, що до продакшну не відтворити.

Pitfalls. Shift-left does not mean "the tester arrives earlier and does the same thing": the kind of work changes — more questions, examples and prevention. Nor does it cancel shift-right: monitoring, feature flags and canary releases catch what cannot be reproduced before production.

Де ловимо один і той самий дефект і що доведеться переробити
Where the same defect is caught and what must be redone
Дефект: «14 днів» — від оплати чи від доставки?

Вимоги      ● коментар у рев'ю → PO уточнює текст
Дизайн      ● змінити поле дати в макеті й API-контракті
Код         ● переписати логіку + компонентні тести
Система     ● баг-репорт, фікс, retest, регресія
Продакшн    ● хотфікс, міграція даних, скарги,
              повернення коштів вручну

Що правіше — то більше артефактів і людей зачеплено
Defect: "14 days" — from payment or from delivery?

Requirements ● review comment → PO clarifies text
Design       ● change date field in mock-up and API contract
Code         ● rewrite logic + component tests
System       ● bug report, fix, retest, regression
Production   ● hotfix, data migration, complaints,
               manual refunds

The further right, the more artefacts and people involved
🔧 Як читати: рядки — етапи життєвого циклу зліва направо, праворуч — що треба переробити, якщо дефект виявлено саме там. Порівняння навмисно якісне: воно показує, як росте кількість зачеплених артефактів, без вигаданих множників вартості.
🔧 How to read it: the rows are life-cycle stages from left to right, and the right column is what has to be redone if the defect is found there. The comparison is deliberately qualitative: it shows how the number of affected artefacts grows, without invented cost multipliers.
💡 Простими словами: найдешевший баг — той, що помер у вигляді питання на рев'ю вимоги.
💡 In plain words: the cheapest bug is the one that died as a question in a requirement review.
🗣 Як читати вголос Shift-left для мене — це коли я підключаюся ще на рівні вимог: читаю історії, питаю про крайові випадки, прошу тестовані критерії і допомагаю розробникам з тестами на рівні API. Чому це вигідно — бо дефект, знайдений у тексті вимоги, виправляється одним коментарем, а в проді тягне хотфікс, міграцію і скарги. Цифри на кшталт «у сто разів дорожче» я не наводжу як факт, це старі дослідження, які сьогодні критикують. І shift-left я поєдную з shift-right, тобто з моніторингом після релізу.
🗣 How to say it out loud To me shift-left means joining at the requirements stage: I read stories, ask about edge cases, push for testable criteria and help developers with API-level tests. Why it pays off: a defect found in the requirement text is fixed with one comment, while in production it brings a hotfix, a migration and complaints. I do not quote figures like "a hundred times more expensive" as fact; they come from old studies that are criticised today. And I combine shift-left with shift-right, meaning monitoring after the release.
59 Як виглядає continuous testing у CI/CD-пайплайні і де в ньому ставлять quality gates? What does continuous testing look like in a CI/CD pipeline, and where do the quality gates go?
ПроцесProcess Middle ▶

Що це. Continuous testing — автоматичне виконання тестів на кожному етапі пайплайна, від коміту до продакшну, щоб кожна зміна одразу отримувала оцінку ризику. Quality gate — умова, без виконання якої збірка не йде далі: впали компонентні тести, статичний аналіз знайшов критичну проблему, smoke на стенді червоний.

What it is. Continuous testing is running tests automatically at every stage of the pipeline, from commit to production, so every change gets an immediate risk assessment. A quality gate is a condition without which the build does not move on: component tests failed, static analysis found a critical issue, the smoke run on the environment is red.

Навіщо. Швидкий зворотний зв'язок: розробник дізнається про поломку через кілька хвилин, поки ще пам'ятає, що змінював. Без цього регресія накопичується до кінця спринту, і вже ніхто не знає, котрий із сорока мерджів усе зламав.

Why it matters. Fast feedback: a developer learns about a break within minutes, while they still remember what they changed. Without it, regressions pile up until the end of the sprint and nobody knows which of forty merges broke things.

Приклад. На pull request запускаються лінтер і компонентні тести — кілька хвилин. Після мерджу — API- та інтеграційні тести на ефемерному стенді. Перед релізом — короткий набір E2E на критичних шляхах і, за потреби, навантажувальний тест. Після деплою — smoke на продакшні і моніторинг помилок. Мануальний QA тут не зникає: він тестує нове дослідницьки, поки пайплайн стереже старе.

Example. On a pull request the linter and component tests run — a few minutes. After merge, API and integration tests run on an ephemeral environment. Before release, a short E2E set on critical paths and, if needed, a load test. After deploy, a production smoke and error monitoring. The manual QA does not vanish: they explore what is new while the pipeline guards what already exists.

Підводні камені. Повільний або нестабільний пайплайн люди починають обходити — перезапускають, доки не позеленіє, або вимикають гейт. Тому швидкі тести ставлять першими, а флейкі ізолюють. Ще одна пастка — перенести всю ручну регресію в UI-автотести: такий набір виконується годину і ламається від кожної зміни верстки.

Pitfalls. People start bypassing a slow or unstable pipeline — rerunning until it goes green or disabling the gate. So fast tests go first and flaky ones are quarantined. Another trap is moving the whole manual regression into UI automation: such a suite takes an hour and breaks with every layout change.

Пайплайн з тестами і воротами
A pipeline with tests and gates
коміт/PR ─► [лінтер + компонентні тести]  ~5 хв
                 │ ворота: 0 падінь, аналіз без critical
                 ▼
мердж ─────► [API + інтеграційні на стенді] ~15 хв
                 │ ворота: контракти й API зелені
                 ▼
реліз-кандидат ► [E2E критичних шляхів]     ~20 хв
                 │ ворота: checkout, логін, оплата ОК
                 ▼
деплой ────► [smoke у проді + моніторинг]
                 │ ворота: помилки 5xx не зросли
                 ▼
             відкат або реліз для всіх
commit/PR ─► [linter + component tests]    ~5 min
                 │ gate: 0 failures, no critical findings
                 ▼
merge ─────► [API + integration on env]    ~15 min
                 │ gate: contracts and API green
                 ▼
release cand ► [E2E of critical paths]     ~20 min
                 │ gate: checkout, login, payment OK
                 ▼
deploy ────► [prod smoke + monitoring]
                 │ gate: 5xx errors did not grow
                 ▼
             roll back or release to all
🔧 Як читати: кожен рядок — етап пайплайна і набір тестів на ньому, під ним — умова воріт. Час на етапах — приблизний приклад, а не норма. Порядок від найшвидшого і найдешевшого до найповільнішого відповідає піраміді тестів: чим вище етап, тим менше тестів і тим критичніші сценарії.
🔧 How to read it: each line is a pipeline stage with its test set, and below it is the gate condition. The timings are a rough example, not a norm. The order from fastest and cheapest to slowest follows the test pyramid: the higher the stage, the fewer the tests and the more critical the scenarios.
💡 Простими словами: кожна зміна проходить кілька фільтрів; дрібне сито — на початку, щоб більшість проблем відсівалась за хвилини.
💡 In plain words: every change passes through several filters; the fine sieve comes first so most problems are caught within minutes.
🗣 Як читати вголос Continuous testing — це коли тести біжать на кожному кроці пайплайна, а не раз на спринт. На пул-реквесті — швидкі компонентні і лінтер, після мерджу — API на стенді, перед релізом — невеликий набір E2E по грошових сценаріях, після деплою — smoke у проді і моніторинг. На кожному кроці є ворота: якщо щось червоне, збірка далі не йде. Для мене важливо, щоб пайплайн був швидким і стабільним, інакше команда почне його обходити. А сам я в цей час досліджую нове руками.
🗣 How to say it out loud Continuous testing means tests run at every pipeline step, not once a sprint. On a pull request — fast component tests and a linter, after merge — API tests on an environment, before release — a small E2E set on the money flows, after deploy — a production smoke and monitoring. Every step has a gate: if something is red, the build goes no further. What matters to me is a fast, stable pipeline, otherwise the team will start working around it. Meanwhile I explore the new work by hand.
60 Як організувати парне тестування з розробником, щоб воно не перетворилось на демонстрацію фічі? How do you run pair testing with a developer so it does not turn into a feature demo?
ПроцесProcess Middle ▶

Що це. Парне тестування — дві людини тестують одну річ за одним комп'ютером: одна веде (driver, керує клавіатурою), друга спостерігає, пропонує ідеї і записує (navigator). Пара буває «тестувальник + розробник», «тестувальник + BA чи PO», «досвідчений + новачок». Якщо учасників більше, це вже mob testing — вся команда навколо одного екрана.

What it is. Pair testing is two people testing one thing at one computer: one drives (holds the keyboard), the other observes, suggests ideas and takes notes (the navigator). Pairs can be tester + developer, tester + BA or PO, senior + newcomer. With more participants it becomes mob testing — the whole team around one screen.

Навіщо. Розробник бачить, як тестувальник думає, і наступного разу сам перевіряє ці випадки. Тестувальник дізнається, як фіча влаштована всередині, і знаходить ризики, про які не здогадався б ззовні. Дефекти виправляються одразу, без баг-репорту й черги.

Why it matters. The developer sees how a tester thinks and checks those cases on their own next time. The tester learns how the feature works inside and spots risks they would not guess from outside. Defects are fixed on the spot, with no bug report and no queue.

Приклад. Розробник закінчив імпорт товарів з CSV. Сесія на 45 хвилин із чартером: «дослідити імпорт на кривих файлах». Тестувальник веде, розробник коментує: «тут ми читаємо по 500 рядків». Одразу виникає ідея — файл на 501 рядок, де помилка саме в останньому рядку. Ролі змінюються кожні 15 хвилин.

Example. A developer has finished product import from CSV. A 45-minute session with a charter: "explore the import with broken files". The tester drives, the developer comments: "we read 500 rows at a time here". An idea appears at once — a 501-row file with the error in the very last row. Roles swap every 15 minutes.

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

Pitfalls. If the developer drives the whole time, you get a happy-path demo — so the tester should be at the keyboard at least half the time. Without a charter and a timebox the session drifts. And do not pair on every story: it is an expensive format, kept for complex or risky changes.

План парної сесії
Pair session plan
Чартер:   Дослідити імпорт товарів з CSV на
          некоректних і великих файлах
Пара:     Оля (QA, driver) + Андрій (dev, navigator)
Таймбокс: 45 хв, зміна ролей кожні 15 хв

00-15  порожній файл, лише заголовок, BOM, ; замість ,
15-30  501 рядок з помилкою в останньому, дублікати SKU
30-40  файл 20 МБ, повторний імпорт того самого файлу
40-45  підсумок: 3 баги, 2 питання до PO, 1 ідея
       для компонентного тесту (розбиття по 500)
Charter:  Explore product import from CSV with
          invalid and large files
Pair:     Olha (QA, driver) + Andrii (dev, navigator)
Timebox:  45 min, roles swap every 15 min

00-15  empty file, header only, BOM, ; instead of ,
15-30  501 rows with error in the last, duplicate SKUs
30-40  20 MB file, importing the same file twice
40-45  wrap-up: 3 bugs, 2 questions for PO, 1 idea
       for a component test (500-row batches)
🔧 Як читати: верх — мета, учасники і таймбокс, низ — хвилини сесії та ідеї, які пара перевіряє. Рядок про 501 рядок з'явився з підказки розробника про пакети по 500 — це і є цінність пари. Останній блок — результат, який фіксують одразу, поки деталі свіжі.
🔧 How to read it: the top is the goal, the people and the timebox; the bottom is the session minutes and the ideas the pair checks. The 501-row line came from the developer's hint about 500-row batches — that is exactly the value of pairing. The last block is the outcome, recorded right away while the details are fresh.
💡 Простими словами: одна людина знає, як воно зроблено, друга — як його зламати; разом вони знаходять більше, ніж поодинці.
💡 In plain words: one person knows how it was built, the other knows how to break it; together they find more than either alone.
🗣 Як читати вголос Парне тестування я використовую для складних фіч, найчастіше разом із розробником. У нас є чартер і таймбокс хвилин на сорок п'ять, ролі міняємо кожні п'ятнадцять хвилин. Важливо, щоб за клавіатурою сидів не лише автор коду, інакше вийде показ щасливого сценарію. Найкорисніше, що розробник по ходу пояснює внутрішню логіку, і з цього народжуються дуже прицільні тести. Баги ми часто виправляємо прямо під час сесії, а в кінці записуємо короткий підсумок.
🗣 How to say it out loud I use pair testing for complex features, most often together with a developer. We have a charter and a timebox of about forty-five minutes, and we swap roles every fifteen. It matters that the code's author is not the only one at the keyboard, otherwise you get a happy-path show. The most useful part is the developer explaining the internal logic as we go, and very targeted tests come out of that. We often fix bugs during the session itself and write a short summary at the end.
61 Як ви боретеся з флейкі-тестами на рівні процесу, а не лише перезапуском? How do you deal with flaky tests at the process level rather than just rerunning them?
ПроцесProcess Senior ▶

Що це. Флейкі-тест — тест, який на тому самому коді й середовищі то проходить, то падає. Типові причини: гонки й фіксовані очікування, спільні тестові дані між паралельними тестами, залежність від порядку виконання, реальний час і часові пояси, нестабільні зовнішні сервіси чи стенд. Іноді флейкі-тест насправді ловить справжній гонковий дефект у продукті.

What it is. A flaky test passes and fails on the same code and environment. Typical causes: races and fixed sleeps, test data shared between parallel tests, dependence on execution order, real time and time zones, unstable external services or environments. Sometimes a flaky test is actually catching a real race condition in the product.

Навіщо з ними боротись системно. Кожен флейкі-тест знецінює весь набір: команда звикає, що червоне «нічого не означає», і пропускає справжню регресію. Автоматичний retry ховає проблему і подвоює час пайплайна.

Why deal with them systematically. Every flaky test devalues the whole suite: the team gets used to red "meaning nothing" and misses a real regression. Automatic retries hide the problem and double the pipeline time.

Приклад політики. Вимірюємо: частка нестабільних прогонів кожного тесту за останні 14 днів. Тест, що хоч раз «пройшов після перезапуску», автоматично потрапляє в карантин — виконується, але не блокує мердж, і на нього одразу створюється задача з власником і терміном. Якщо тест не виправили за спринт, його видаляють або переписують нижчим рівнем. Retry дозволений лише як тимчасовий захід і обов'язково звітується.

Policy example. We measure: the share of unstable runs for each test over the last 14 days. A test that ever "passed on retry" goes to quarantine automatically — it still runs but does not block the merge, and a ticket with an owner and a deadline is created straight away. If it is not fixed within a sprint, it is deleted or rewritten at a lower level. Retries are allowed only as a temporary measure and are always reported.

Підводні камені. Карантин без власника перетворюється на кладовище, де лежать сотні вимкнених тестів. І не списуйте все на «інфраструктуру»: спершу перевірте, чи не падає тест через справжній дефект конкурентності.

Pitfalls. A quarantine without owners becomes a graveyard of hundreds of disabled tests. And do not blame everything on "infrastructure": first check whether the test fails because of a genuine concurrency defect.

Таблиця розбору флейкі-тестів
Flaky test triage table
Тест               Падінь/14д  Причина            Дія
checkout_promo     7 з 120     спільний промокод   унікальні дані
                               між воркерами      на кожен тест
order_history      4 з 120     sleep(2000) замість чекати відповідь
                               очікування події   API, прибрати sleep
report_daily       3 з 120     дата UTC vs Kyiv   фіксований час
                               біля півночі       у тесті
payment_callback   5 з 120     реальна гонка в    баг у продукті,
                               обробці webhook    не в тесті!

Правило: pass-on-retry → карантин + задача
з власником; не виправлено за спринт → видалити
Test               Fails/14d   Cause              Action
checkout_promo     7 of 120    promo code shared  unique data
                               across workers     per test
order_history      4 of 120    sleep(2000) not    wait for the API
                               waiting on event   response, drop sleep
report_daily       3 of 120    UTC vs Kyiv date   fixed clock
                               near midnight      in the test
payment_callback   5 of 120    real race in       product bug,
                               webhook handling   not a test bug!

Rule: pass-on-retry → quarantine + ticket
with owner; not fixed in a sprint → delete
🔧 Як читати: кожен рядок — один нестабільний тест, кількість падінь на сто двадцять прогонів, знайдена причина і конкретна дія. Останній рядок навмисно показує, що флейкі-тест може бути симптомом справжнього дефекту. Правило внизу — це політика, яку команда погоджує і автоматизує в CI.
🔧 How to read it: each row is one unstable test, its failures out of 120 runs, the cause found and a concrete action. The last row deliberately shows that a flaky test can be a symptom of a real defect. The rule at the bottom is the policy the team agrees on and automates in CI.
💡 Простими словами: флейкі-тест — це або баг у тесті, або баг у продукті. «Просто не пощастило» таким не буває.
💡 In plain words: a flaky test is either a bug in the test or a bug in the product. "Just bad luck" is never the answer.
🗣 Як читати вголос Для мене флейкі-тест — це дефект, просто ще не зрозуміло, де саме: у тесті чи в продукті. Я спершу міряю: скільки разів тест падав за останні два тижні і чи проходив після перезапуску. Такий тест іде в карантин — він біжить, але не блокує мердж, і на нього одразу є задача з власником. Найчастіші причини — спільні дані між паралельними тестами, sleep замість очікування і час біля півночі. Але одного разу за «нестабільним» тестом у нас ховалась реальна гонка в обробці вебхука, тож списувати все на інфраструктуру я не поспішаю.
🗣 How to say it out loud To me a flaky test is a defect whose location we do not know yet: the test or the product. First I measure how often it failed over the last two weeks and whether it passed on retry. Such a test goes to quarantine — it runs but does not block merges, and it immediately gets a ticket with an owner. The most common causes are data shared between parallel tests, a sleep instead of a proper wait, and times near midnight. But once an "unstable" test was hiding a real race in webhook handling, so I am in no hurry to blame the infrastructure.
62 Що показує мутаційне тестування, чого не видно з відсотка покриття коду? What does mutation testing reveal that a code coverage percentage cannot?
ПроцесProcess Senior ▶

Що це. Мутаційне тестування оцінює якість самих тестів. Інструмент робить у коді маленьку зміну — мутанта: замінює >= на >, + на -, true на false, видаляє виклик — і запускає тести. Якщо хоч один тест упав, мутанта «вбито»; якщо всі зелені, мутант «вижив», тобто тести не помітили зміни поведінки. Mutation score — частка вбитих мутантів серед усіх, крім еквівалентних.

What it is. Mutation testing assesses the quality of the tests themselves. A tool makes a small change in the code — a mutant: it replaces >= with >, + with -, true with false, removes a call — and runs the tests. If at least one test fails, the mutant is "killed"; if all stay green, it "survived", meaning the tests did not notice the behaviour change. The mutation score is the share of killed mutants among all non-equivalent ones.

Навіщо. Покриття коду каже лише, що рядок виконувався під час тестів, а не що результат перевіряли. Тест без жодного assert дає 100% покриття і вбиває нуль мутантів. Мутації показують слабкі перевірки й пропущені граничні значення.

Why it matters. Code coverage only says a line was executed during tests, not that the result was checked. A test with no assertion at all can still reach 100% line coverage and kill zero mutants. Mutations expose weak assertions and missing boundary values.

Приклад. Правило «безкоштовна доставка від 1000 грн». Тест перевіряє лише суму 1500 — покриття рядка повне. Мутант замінює >= на > і виживає, бо 1500 більше за 1000 в обох версіях. Додаємо тест на рівно 1000 — мутанта вбито. Мутаційне тестування фактично змусило нас зробити аналіз граничних значень.

Example. The rule "free delivery from 1000 UAH". The test checks only a total of 1500 — line coverage is complete. A mutant replaces >= with > and survives, because 1500 is above 1000 in both versions. We add a test for exactly 1000 — the mutant is killed. Mutation testing effectively forced us to do boundary value analysis.

Підводні камені. Це дорого: кожен мутант — окремий прогін тестів, тому запускають на критичних модулях або лише на змінених файлах у PR. Еквівалентні мутанти, які не змінюють поведінки, вбити неможливо, і їх доводиться розбирати вручну. Інструменти — PIT (pitest) для Java, Stryker для JavaScript/TypeScript і .NET, mutmut для Python.

Pitfalls. It is expensive: each mutant is a separate test run, so it is used on critical modules or only on files changed in a PR. Equivalent mutants that do not change behaviour cannot be killed and must be reviewed by hand. Tools: PIT (pitest) for Java, Stryker for JavaScript/TypeScript and .NET, mutmut for Python.

Код, мутант і тест, що його вбиває
Code, mutant and the test that kills it
// Оригінал
function isFreeDelivery(total) { return total >= 1000; }

// Мутант, згенерований інструментом: >= → >
function isFreeDelivery(total) { return total > 1000; }

// Слабкий тест: 100% покриття рядка, мутант ВИЖИВ
test('1500 — безкоштовно', () =>
  expect(isFreeDelivery(1500)).toBe(true));

// Тест на межі: мутанта ВБИТО (false замість true)
test('рівно 1000 — безкоштовно', () =>
  expect(isFreeDelivery(1000)).toBe(true));
// Original
function isFreeDelivery(total) { return total >= 1000; }

// Mutant generated by the tool: >= → >
function isFreeDelivery(total) { return total > 1000; }

// Weak test: 100% line coverage, mutant SURVIVED
test('1500 is free', () =>
  expect(isFreeDelivery(1500)).toBe(true));

// Boundary test: mutant KILLED (false instead of true)
test('exactly 1000 is free', () =>
  expect(isFreeDelivery(1000)).toBe(true));
🔧 Розбір синтаксису: мутанта ніхто не пише руками — інструмент (Stryker, PIT) змінює код у пам'яті, проганяє тести і повертає оригінал. Перший тест виконує рядок, тому покриття повне, але на 1500 обидві версії повертають true. Другий тест на 1000 дає різні результати: оригінал — true, мутант — false, тому toBe(true) падає, і мутант вважається вбитим.
🔧 Syntax breakdown: nobody writes the mutant by hand — the tool (Stryker, PIT) changes the code in memory, runs the tests and restores the original. The first test executes the line, so coverage is complete, but for 1500 both versions return true. The second test at 1000 produces different results: the original gives true, the mutant false, so toBe(true) fails and the mutant counts as killed.
💡 Простими словами: покриття відповідає на питання «чи тести тут були», мутації — «чи тести тут щось перевіряли».
💡 In plain words: coverage answers "were the tests here", mutations answer "did the tests check anything here".
🗣 Як читати вголос Мутаційне тестування я пояснюю як тест для тестів. Інструмент трохи псує код, наприклад міняє більше-або-дорівнює на строго більше, і дивиться, чи хоч один тест це помітив. Якщо всі тести зелені, значить, вони цей рядок виконують, але по-справжньому не перевіряють. Класичний випадок — нема тесту рівно на межі. Це дорогий інструмент, тому я б запускав його на критичних модулях або тільки на змінених файлах. Для Java є PIT, для JavaScript — Stryker.
🗣 How to say it out loud I describe mutation testing as a test for the tests. The tool slightly breaks the code, for example turning greater-or-equal into strictly greater, and checks whether any test noticed. If every test stays green, they run that line but do not really verify it. The classic case is a missing test exactly at the boundary. It is an expensive tool, so I would run it on critical modules or only on changed files. For Java there is PIT, for JavaScript there is Stryker.
▶ 7 7
63 Чим exploratory testing відрізняється від хаотичного «потицяти» і як написати для нього чартер? How is exploratory testing different from random clicking, and how do you write a charter for it?
СтратегіяStrategy Middle ▶

Що це. Дослідницьке тестування — підхід, у якому вивчення продукту, проєктування тестів і їх виконання відбуваються одночасно: результат попередньої перевірки підказує наступну. Від хаотичного клікання його відрізняють три речі: чітка мета (чартер), обмежений час і нотатки, з яких потім можна відтворити, що перевірили і що знайшли. ISTQB відносить його до технік, заснованих на досвіді.

What it is. Exploratory testing is an approach in which learning the product, designing tests and running them happen at the same time: the result of one check suggests the next. Three things set it apart from random clicking: a clear goal (the charter), a time box and notes from which you can later reconstruct what was covered and what was found. ISTQB classes it among experience-based techniques.

Навіщо і коли. Коли вимоги неповні, фіча нова, часу мало або скриптові тести вже «зношені» і перестали знаходити дефекти. Воно добре доповнює тест-кейси: скрипт перевіряє відоме, дослідження шукає невідоме. Корисні евристики: SFDIPOT (структура, функції, дані, інтерфейси, платформа, операції, час), CRUD, межі, переривання дії, повтор дії.

Why and when. When requirements are incomplete, the feature is new, time is short, or scripted tests have worn out and stopped finding defects. It complements test cases well: a script checks the known, exploration hunts for the unknown. Useful heuristics: SFDIPOT (structure, function, data, interfaces, platform, operations, time), CRUD, boundaries, interrupting an action, repeating an action.

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

Example. A charter follows Elisabeth Hendrickson's template: "Explore target with resources to discover information". For promo codes in the cart it is 60 minutes on expired, stacked and mixed-case codes, aimed at finding discount calculation errors. Findings go into time-stamped notes, and bugs go straight to the tracker.

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

Pitfalls. Calling the absence of any plan exploratory testing. Keeping no notes — then the result can be neither shown nor repeated. Inflating the charter to "test the whole checkout": it must fit into one session.

Чартер дослідницької сесії
Exploratory session charter
ЧАРТЕР #14
Дослідити:  застосування промокодів у кошику
З:          прострочені, одноразові, комбіновані коди,
            різний регістр і пробіли, 2 вкладки браузера
Щоб знайти: помилки розрахунку знижки й повторне
            використання одноразового коду
Час:        60 хв

Ідеї (евристики):
- межа: код, що спливає сьогодні о 23:59
- повтор: застосувати той самий код двічі
- переривання: застосувати код і оновити сторінку
- дані: « SALE10 », «sale10», «SALE10» з кирилицею

Нотатки:
10:05 SALE10 + FREESHIP → обидві знижки, OK за AC
10:22 одноразовий код у 2 вкладках → знижка двічі! BUG-812
10:40 код з кириличною «С» → 500 замість помилки. BUG-813
CHARTER #14
Explore:     applying promo codes in the cart
With:        expired, single-use, stacked codes,
             mixed case and spaces, 2 browser tabs
To discover: discount calculation errors and reuse
             of a single-use code
Time:        60 min

Ideas (heuristics):
- boundary: a code expiring today at 23:59
- repeat: apply the same code twice
- interrupt: apply a code and reload the page
- data: " SALE10 ", "sale10", SALE10 with a Cyrillic C

Notes:
10:05 SALE10 + FREESHIP → both discounts, OK per AC
10:22 single-use code in 2 tabs → discount twice! BUG-812
10:40 code with Cyrillic C → 500, not an error. BUG-813
🔧 Як читати: верхня частина — сам чартер у форматі «дослідити / з / щоб знайти» плюс ліміт часу. «Ідеї» — евристики, з яких тестувальник стартує, але не зобов'язаний їх виконати всі. «Нотатки» з позначкою часу — головний результат сесії: у них видно, що перевірено, що працює за вимогами і які баги заведено.
🔧 How to read it: the top part is the charter itself in the explore / with / to discover format plus a time limit. "Ideas" are heuristics the tester starts from without being bound to run them all. The time-stamped "Notes" are the main output of the session: they show what was checked, what works as required and which bugs were filed.
💡 Простими словами: дослідницьке тестування — це вільний пошук, але з компасом, годинником і блокнотом.
💡 In plain words: exploratory testing is a free search, but with a compass, a clock and a notebook.
🗣 Як читати вголос Для мене дослідницьке тестування — не «потицяти», а сесія з метою. Я пишу короткий чартер: що досліджую, чим і що хочу знайти, і ставлю собі годину. Наприклад, для промокодів я цілеспрямовано пробую прострочені коди, дві вкладки, дивний регістр. Під час роботи веду нотатки з часом, тож потім можу показати, що саме перевірив. Найцікавіші баги, як-от одноразовий код, що спрацював двічі, я знаходжу саме так, бо тест-кейси до такого зазвичай не додумуються.
🗣 How to say it out loud For me exploratory testing is not clicking around, it is a session with a purpose. I write a short charter — what I explore, with what, and what I want to find — and give myself an hour. With promo codes, say, I deliberately try expired codes, two tabs, odd letter case. I keep time-stamped notes while I work, so afterwards I can show exactly what I covered. The most interesting bugs, like a single-use code that worked twice, I find precisely this way, because scripted test cases rarely think of such things.
64 Як session-based test management робить дослідницьке тестування вимірюваним і звітним? How does session-based test management make exploratory testing measurable and reportable?
СтратегіяStrategy Middle ▶

Що це. Session-based test management (SBTM) — спосіб керувати дослідницьким тестуванням, запропонований Джонатаном і Джеймсом Бахами. Робота ділиться на сесії: безперервний відрізок часу (зазвичай 60–120 хвилин) під один чартер без відволікань. Після кожної сесії тестувальник заповнює session sheet і проходить коротке обговорення з лідом (debrief).

What it is. Session-based test management (SBTM) is a way to manage exploratory testing, proposed by Jonathan and James Bach. Work is split into sessions: an uninterrupted block of time (usually 60–120 minutes) on one charter without distractions. After each session the tester fills in a session sheet and goes through a short debrief with the lead.

Навіщо. Менеджер часто питає: «Скільки ви протестували, якщо тест-кейсів немає?» SBTM дає відповідь цифрами: кількість сесій на область, розподіл часу між проєктуванням і виконанням тестів, розслідуванням багів і налаштуванням (TBS-метрики), частку роботи за чартером проти побічних знахідок. Debrief за схемою PROOF (Past, Results, Obstacles, Outlook, Feelings) перетворює нотатки на рішення: що дослідити далі.

Why it matters. A manager often asks: "How much did you test if there are no test cases?" SBTM answers with numbers: sessions per area, the split of time between test design and execution, bug investigation and setup (TBS metrics), and the share of on-charter work versus opportunity findings. A debrief following PROOF (Past, Results, Obstacles, Outlook, Feelings) turns notes into a decision about what to explore next.

Приклад. Сесія на чартер «імпорт CSV з клієнтами» тривала 90 хвилин. 20% часу пішло на підготовку файлів, 25% — на розслідування двох багів, решта — на власне тестування. Лід на debrief бачить, що підготовка даних з'їдає багато часу, і просить розробника додати набір готових файлів у репозиторій.

Example. A session on the charter "import customers from CSV" lasted 90 minutes. 20% of the time went into preparing files, 25% into investigating two bugs, and the rest into testing proper. At the debrief the lead sees that data preparation eats a lot of time and asks a developer to add a set of ready-made files to the repository.

Підводні камені. Перетворити session sheet на бюрократію на пів години — форма має заповнюватися за кілька хвилин. Пропускати debrief: без нього метрики просто лежать у папці. Порівнювати тестувальників за кількістю знайдених багів за сесію — це вбиває чесні нотатки.

Pitfalls. Turning the session sheet into half an hour of paperwork — it should take a few minutes. Skipping the debrief: without it the metrics just sit in a folder. Ranking testers by bugs found per session — that kills honest notes.

Session sheet
Session sheet
СЕСІЯ:     2026-09-14 / О.Коваль / #27
ЧАРТЕР:    Дослідити імпорт CSV з клієнтами з файлами
           різного кодування й розміру, щоб знайти
           втрату або спотворення даних
ТРИВАЛІСТЬ: нормальна (90 хв)

РОЗПОДІЛ ЧАСУ (TBS):
  T  проєктування і виконання тестів   55%
  B  розслідування і опис багів        25%
  S  налаштування, підготовка даних    20%
  За чартером / побічні знахідки       85 / 15

ФАЙЛИ ДАНИХ: utf8_bom.csv, cp1251.csv, 50k_rows.csv
БАГИ:      BUG-901 cp1251 → спотворені символи в імені
           BUG-902 50k рядків → таймаут без повідомлення
ПРОБЛЕМИ:  немає готових файлів, кожен раз генерую вручну
DEBRIEF (PROOF): далі — сесія на оновлення існуючих
           клієнтів через імпорт
SESSION:   2026-09-14 / O.Koval / #27
CHARTER:   Explore importing customers from CSV with
           files of different encodings and sizes to
           discover lost or corrupted data
DURATION:  normal (90 min)

TIME SPLIT (TBS):
  T  test design and execution          55%
  B  bug investigation and reporting    25%
  S  setup, data preparation            20%
  On charter / opportunity             85 / 15

DATA FILES: utf8_bom.csv, cp1251.csv, 50k_rows.csv
BUGS:      BUG-901 cp1251 → garbled characters in name
           BUG-902 50k rows → timeout with no message
ISSUES:    no ready-made files, I generate them by hand
DEBRIEF (PROOF): next — a session on updating existing
           customers through import
🔧 Як читати: шапка ідентифікує сесію і чартер. Блок TBS показує, куди пішов час: T — test design and execution, B — bug investigation, S — session setup. «Проблеми» (issues) — не баги продукту, а те, що заважає тестувати; саме їх лід вирішує після debrief. Останній рядок — висновок Outlook зі схеми PROOF.
🔧 How to read it: the header identifies the session and the charter. The TBS block shows where the time went: T is test design and execution, B is bug investigation, S is session setup. "Issues" are not product bugs but whatever blocks testing; those are what the lead resolves after the debrief. The last line is the Outlook conclusion from PROOF.
💡 Простими словами: SBTM — це таймер, коротка форма і п'ятихвилинна розмова, які роблять вільне тестування видимим для менеджменту.
💡 In plain words: SBTM is a timer, a short form and a five-minute chat that make free-form testing visible to management.
🗣 Як читати вголос Коли мене питають, як звітувати про дослідницьке тестування, я розповідаю про SBTM. Ми працюємо сесіями по годині-півтори під один чартер, а після кожної я за кілька хвилин заповнюю аркуш: скільки часу пішло на тестування, скільки на баги і скільки на підготовку. Потім коротко обговорюємо з лідом, що знайшли і що заважало. Одного разу так стало видно, що п'яту частину часу я генерую CSV-файли вручну, і ми просто додали їх у репозиторій. Тобто метрики тут не для контролю, а щоб прибирати перешкоди.
🗣 How to say it out loud When I am asked how to report on exploratory testing, I talk about SBTM. We work in sessions of an hour or an hour and a half on one charter, and after each I spend a few minutes on a sheet: how much time went to testing, how much to bugs and how much to setup. Then the lead and I briefly discuss what we found and what got in the way. Once this showed that I spent a fifth of my time generating CSV files by hand, so we simply added them to the repository. So the metrics are not there for control; they are there to remove obstacles.
65 Як побудувати risk-based testing для релізу і як ризик змінює глибину перевірок? How do you build risk-based testing for a release, and how does risk change the depth of testing?
СтратегіяStrategy Senior ▶

Що це. Risk-based testing — підхід, у якому обсяг, порядок і глибина тестування визначаються рівнем ризику. Ризик за ISTQB — це ймовірність × вплив. Продуктові ризики стосуються якості (неправильна знижка, витік даних), проєктні — умов роботи (стенд не готовий, розробник у відпустці). Тестування зменшує саме продуктові ризики; проєктні враховують у плані.

What it is. Risk-based testing is an approach where the scope, order and depth of testing are set by the level of risk. Risk, per ISTQB, is likelihood × impact. Product risks concern quality (a wrong discount, a data leak); project risks concern working conditions (the environment is not ready, a developer is on leave). Testing reduces product risks; project risks are handled in the plan.

Як я це роблю. Разом із PO, розробниками й підтримкою складаю список ризиків для релізу. Ймовірність оцінюємо за складністю змін, новизною коду, історією дефектів; вплив — за грошима, кількістю користувачів, юридичними наслідками. Кожен ризик отримує оцінку 1–3 за двома осями, добуток визначає рівень. Високий — формальні техніки (таблиці рішень, межі), автотести, незалежна перевірка, дослідницькі сесії. Середній — стандартні тест-кейси. Низький — smoke або чекліст.

How I do it. With the PO, developers and support I build a list of risks for the release. Likelihood is judged by change complexity, code novelty and defect history; impact by money, number of users and legal consequences. Each risk gets a 1–3 score on both axes, and the product sets its level. High means formal techniques (decision tables, boundaries), automated checks, an independent review and exploratory sessions. Medium means standard test cases. Low means smoke or a checklist.

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

Example. An online shop release contains a new loyalty discount, an updated payment SDK, a footer redesign and a new filter. The matrix below shows payments and the discount getting most of the time, while the footer gets only a visual check. If time runs short, low risks are cut first, and that decision is recorded together with the residual risk.

Підводні камені. Оцінювати ризики самотужки — QA не знає всіх бізнес-наслідків. Скласти матрицю один раз і не переглядати її, коли з'являються нові дефекти. Сприймати низький ризик як «не тестувати зовсім».

Pitfalls. Scoring risks alone — QA does not know every business consequence. Building the matrix once and never revisiting it as new defects appear. Treating low risk as "do not test at all".

Матриця ризиків релізу
Release risk matrix
Ризик                         │ Ймов.│ Вплив│ Рівень │ Глибина
──────────────────────────────┼──────┼──────┼────────┼────────────────
Оплата падає після оновл. SDK │  3   │  3   │ 9 вис. │ повна регресія
                              │      │      │        │ оплат, 3 банки
Знижка лояльності рахує хибно │  2   │  3   │ 6 вис. │ табл. рішень,
                              │      │      │        │ межі, SQL-звірка
Новий фільтр губить товари    │  2   │  2   │ 4 сер. │ тест-кейси + EP
Редизайн футера ламає верстку │  2   │  1   │ 2 низ. │ візуальний огляд

Шкала: 1 — низько, 2 — середньо, 3 — високо
Рівень = ймовірність × вплив: 6–9 вис., 3–4 сер., 1–2 низ.
Risk                          │ Like.│ Imp. │ Level  │ Depth
──────────────────────────────┼──────┼──────┼────────┼────────────────
Payment fails after SDK update│  3   │  3   │ 9 high │ full payment
                              │      │      │        │ regression, 3 banks
Loyalty discount miscalculates│  2   │  3   │ 6 high │ decision table,
                              │      │      │        │ bounds, SQL check
New filter drops products     │  2   │  2   │ 4 med  │ test cases + EP
Footer redesign breaks layout │  2   │  1   │ 2 low  │ visual review

Scale: 1 low, 2 medium, 3 high
Level = likelihood × impact: 6–9 high, 3–4 medium, 1–2 low
🔧 Як читати: кожен рядок — один продуктовий ризик, сформульований як можлива проблема, а не як назва фічі. Дві оцінки множаться, і рівень прямо керує стовпцем «Глибина». Шкала і пороги — приклад, їх узгоджують у тест-стратегії чи тест-плані конкретного проєкту.
🔧 How to read it: each row is one product risk phrased as a possible problem, not as a feature name. The two scores are multiplied, and the level directly drives the "Depth" column. The scale and thresholds are an example; they are agreed in the test strategy or test plan of a given project.
💡 Простими словами: найбільше тестуй там, де найімовірніше зламається і найболючіше вдарить.
💡 In plain words: test most where things are most likely to break and would hurt the most.
🗣 Як читати вголос Я будую тестування релізу від ризиків, а не від списку фіч. Разом із продактом і розробниками формулюю, що саме може піти не так, і ставимо кожному ризику ймовірність і вплив від одного до трьох. Оплата після оновлення SDK — дев'ятка, тож там повна регресія і кілька банків. Редизайн футера — двійка, вистачить подивитись очима. Коли час стискається, я ріжу знизу таблиці і прямо пишу в статусі, який ризик ми свідомо приймаємо. Матрицю переглядаю, якщо в якомусь місці раптом посипались баги.
🗣 How to say it out loud I build release testing from risks, not from a feature list. Together with the product owner and developers I spell out what exactly could go wrong, and we give each risk a likelihood and an impact from one to three. Payments after the SDK update score nine, so they get full regression across several banks. The footer redesign scores two, and a visual look is enough. When time gets squeezed I cut from the bottom of the table and state plainly in the status report which risk we are knowingly accepting. I revisit the matrix whenever bugs suddenly start piling up in one area.
66 Що ти попросиш у розробників, щоб фічу реально можна було протестувати, і що таке testability? What would you ask developers for so that a feature can actually be tested, and what is testability?
СтратегіяStrategy Senior ▶

Що це. Testability (тестованість) — міра того, наскільки легко і ефективно систему можна протестувати. Вона тримається на кількох властивостях: керованість (можу привести систему в потрібний стан), спостережуваність (бачу, що всередині сталося), ізольованість (можу перевірити частину окремо від решти), простота і стабільність (поведінка не змінюється щодня без попередження).

What it is. Testability is the degree to which a system can be tested easily and effectively. It rests on a few properties: controllability (I can put the system into the state I need), observability (I can see what happened inside), isolation (I can check one part apart from the rest), simplicity and stability (behaviour does not change every day without notice).

Навіщо. Низька тестованість не робить тестування неможливим, вона робить його дорогим і повільним. Якщо щоб перевірити знижку на день народження треба чекати справжнього дня народження, а щоб побачити помилку треба просити логи в DevOps, цикл одного тесту розтягується на години. Тому тестованість — вимога, яку QA приносить на рефайнмент, а не скарга після релізу.

Why it matters. Low testability does not make testing impossible; it makes it expensive and slow. If checking a birthday discount means waiting for an actual birthday, and seeing an error means asking DevOps for logs, one test cycle stretches into hours. So testability is a requirement QA brings to refinement, not a complaint after the release.

Приклад. Команда робить підписку з автоматичним продовженням через 30 днів і листом за 3 дні до списання. Без змін у дизайні перевірити це можна лише за місяць. Мій список запитів нижче: керування часом на стенді, тестовий платіжний шлюз, доступ до листів, стабільні атрибути для локаторів і кореляційний ID у логах.

Example. The team is building a subscription that renews automatically after 30 days, with an email three days before the charge. Without design changes this can only be checked a month later. My list of requests is below: time control on the test environment, a sandbox payment gateway, access to sent emails, stable attributes for locators and a correlation ID in the logs.

Підводні камені. Просити тестованість після того, як код написано, — тоді кожен хук коштує переробки. Лишати тестові ендпоінти відкритими на проді: їх вимикають прапорцем або захищають. Робити обхідні шляхи, які змінюють поведінку системи, — тоді тестуєш уже не те, що піде до користувачів.

Pitfalls. Asking for testability after the code is written — every hook then costs rework. Leaving test endpoints open in production: they are disabled by a flag or protected. Building shortcuts that change the system's behaviour — then you are testing something other than what users will get.

Запити на тестованість для підписки
Testability requests for a subscription
Властивість       │ Запит до команди
──────────────────┼─────────────────────────────────────
Керованість       │ перевести годинник стенду:
                  │   POST /test/clock {"now": "+27d"}
                  │ створити підписку в потрібному стані
                  │   через API, а не через 5 екранів UI
Спостережуваність │ correlation-id у кожній відповіді
                  │ й у логах; вебінтерфейс поштової
                  │ «пастки» (MailHog/Mailpit) на стенді
Ізольованість     │ sandbox платіжного провайдера
                  │ з тестовими картками на відмову
Стабільність      │ data-testid на ключових кнопках,
                  │ changelog API на кожен реліз
Безпека           │ /test/* вимкнено на проді прапорцем
Property          │ Request to the team
──────────────────┼─────────────────────────────────────
Controllability   │ move the environment clock:
                  │   POST /test/clock {"now": "+27d"}
                  │ create a subscription in any state
                  │   via API, not through 5 UI screens
Observability     │ correlation-id in every response
                  │ and in logs; a mail catcher web UI
                  │ (MailHog/Mailpit) on the environment
Isolation         │ payment provider sandbox with
                  │ test cards that get declined
Stability         │ data-testid on key buttons,
                  │ API changelog for every release
Safety            │ /test/* disabled in prod by a flag
🔧 Як читати: ліворуч — властивість тестованості, праворуч — конкретний запит, який можна оцінити і взяти в спринт. Ендпоінт /test/clock вигаданий для прикладу: у кожної команди свій механізм керування часом. Останній рядок нагадує, що тестові хуки — теж код, який потребує захисту.
🔧 How to read it: the left column is a testability property, the right column is a concrete request that can be estimated and taken into a sprint. The /test/clock endpoint is made up for the example: every team has its own time-control mechanism. The last row is a reminder that test hooks are code too, and they need protecting.
💡 Простими словами: тестованість — це коли систему можна легко поставити в потрібний стан і легко побачити, що з нею сталося.
💡 In plain words: testability means you can easily put the system into a given state and easily see what happened to it.
🗣 Як читати вголос Я думаю про тестованість ще на рефайнменті. Питаю себе: чи зможу я привести систему в потрібний стан і чи побачу, що сталося всередині. Якщо ні — приношу конкретні запити. Наприклад, для підписки з продовженням через тридцять днів я попросив можливість переводити годинник на стенді, пісочницю платіжки і поштову пастку для листів. Інакше перевірка тривала б місяць. І обов'язково домовляюсь, що такі тестові хуки вимкнені на проді, бо це теж потенційна дірка.
🗣 How to say it out loud I think about testability as early as refinement. I ask myself whether I can put the system into the state I need and whether I will see what happened inside. If not, I bring concrete requests. For a subscription that renews after thirty days, for example, I asked for a way to move the clock on the test environment, a payment sandbox and a mail catcher for the emails. Otherwise the check would have taken a month. And I always agree that such test hooks are switched off in production, because they are a potential hole as well.
67 Як організувати тестові дані, щоб тести не заважали один одному і не порушували GDPR? How do you organise test data so that tests do not interfere with each other or break GDPR?
СтратегіяStrategy Senior ▶

Що це. Test data management — стратегія того, звідки беруться тестові дані, хто їх створює, як вони ізольовані між тестами й людьми і коли прибираються. Основні джерела: синтетичні дані (згенеровані з нуля), замасковані або анонімізовані копії продакшну, невеликі вибірки (subsets) і статичні довідники на кшталт країн чи валют.

What it is. Test data management is the strategy for where test data comes from, who creates it, how it is isolated between tests and people, and when it is cleaned up. The main sources are synthetic data (generated from scratch), masked or anonymised copies of production, small subsets and static reference data such as countries or currencies.

Навіщо. Більшість «нестабільних» тестів на спільному стенді насправді падають через дані: хтось змінив того самого користувача, закінчився товар на складі, промокод уже використаний. Друга причина — право: персональні дані з продакшну в тестовому середовищі під дією GDPR потребують законної підстави й захисту, тому дамп проду «як є» майже завжди поганий варіант.

Why it matters. Most "flaky" tests on a shared environment actually fail because of data: someone changed the same user, a product ran out of stock, a promo code was already used. The second reason is legal: under GDPR, personal data from production in a test environment needs a lawful basis and protection, so a raw production dump is almost always a bad option.

Приклад. Команда з п'яти тестувальників і нічною регресією ділить один стенд. Рішення в таблиці нижче: кожен тест створює свого користувача через API з унікальним префіксом прогону, довідники завантажуються один раз і лише читаються, копія проду для аналітики масується до потрапляння на стенд, а нічна задача видаляє все з префіксом старших за добу прогонів.

Example. A team of five testers and a nightly regression share one environment. The solution is in the table below: each test creates its own user through the API with a unique run prefix, reference data is loaded once and only read, the production copy for analytics is masked before it reaches the environment, and a nightly job deletes everything with a prefix from runs older than a day.

Підводні камені. Залежність тесту від даних, створених іншим тестом, — порядок запуску зміниться, і все посиплеться. Маскування, яке ламає зв'язки: замінили email у таблиці users, але не в orders. Відсутність прибирання: за пів року стенд гальмує від мільйона тестових замовлень.

Pitfalls. A test relying on data created by another test — change the run order and everything collapses. Masking that breaks relationships: the email was replaced in users but not in orders. No cleanup: within six months the environment crawls under a million test orders.

План тестових даних
Test data plan
Тип даних        │ Джерело          │ Створення     │ Прибирання
─────────────────┼──────────────────┼───────────────┼───────────────
Користувачі      │ синтетичні       │ API на старті │ нічна задача,
                 │ run_20260914_*   │ кожного тесту │ прогони > 1 дня
Замовлення       │ синтетичні       │ фабрика даних │ разом із
                 │                  │ (builder)     │ користувачем
Країни, валюти   │ статичний seed   │ 1 раз на деплой│ ніколи; тільки
                 │                  │               │ читання
Звіти для BI     │ копія проду      │ маскування до │ перезапис
                 │ (маскована)      │ копіювання    │ щотижня
Банківські картки│ тестові картки   │ з документації│ не потрібне
                 │ провайдера       │ sandbox       │
Data type        │ Source           │ Creation      │ Cleanup
─────────────────┼──────────────────┼───────────────┼───────────────
Users            │ synthetic        │ API at start  │ nightly job,
                 │ run_20260914_*   │ of every test │ runs > 1 day
Orders           │ synthetic        │ data builder  │ together with
                 │                  │               │ the user
Countries, FX    │ static seed      │ once per deploy│ never; read
                 │                  │               │ only
BI reports       │ prod copy        │ masked before │ overwritten
                 │ (masked)         │ copying       │ weekly
Bank cards       │ provider test    │ sandbox docs  │ not needed
                 │ cards            │               │
🔧 Як читати: для кожного типу даних план відповідає на три питання — звідки, як створити, як прибрати. Префікс прогону на кшталт run_20260914_* гарантує, що два паралельні тести не візьмуть одного користувача, і дає прибиральній задачі простий критерій. Рядок «копія проду» — єдине місце, де потрібне маскування, тому воно стоїть до копіювання.
🔧 How to read it: for each data type the plan answers three questions — where from, how to create, how to clean up. A run prefix such as run_20260914_* ensures two parallel tests never grab the same user and gives the cleanup job a simple rule. The "prod copy" row is the only place where masking is needed, which is why it happens before copying.
💡 Простими словами: кожен тест приносить свої дані й забирає їх за собою, а справжні персональні дані на стенд не потрапляють.
💡 In plain words: every test brings its own data and takes it away again, and real personal data never reaches the environment.
🗣 Як читати вголос Мій принцип простий: тест сам створює дані, які йому потрібні, і не залежить від чужих. Ми генеруємо користувачів і замовлення через API з унікальним префіксом прогону, а нічна задача прибирає старе. Довідники вантажимо один раз і тільки читаємо. Дамп проду без маскування я не беру навіть «на хвилинку», бо це персональні дані і GDPR. Коли в нас перестали ділити одного тестового юзера на всіх, кількість нестабільних падінь помітно зменшилась.
🗣 How to say it out loud My principle is simple: a test creates the data it needs and does not depend on anyone else's. We generate users and orders through the API with a unique run prefix, and a nightly job cleans out the old ones. Reference data is loaded once and only read. I never take an unmasked production dump, not even "for a minute", because that is personal data and GDPR applies. Once we stopped sharing one test user between everybody, the number of unstable failures dropped noticeably.
68 Вимог немає зовсім — як ти тестуватимеш фічу і на що спиратимешся? There are no requirements at all — how will you test the feature and what will you rely on?
СтратегіяStrategy Senior ▶

Ситуація. Розробник каже: «Я додав експорт замовлень в Excel, глянь до кінця дня». Документації, історії в трекері чи макетів немає. Інтерв'юер перевіряє, чи ти не відмовишся тестувати і не тестуватимеш навмання.

Situation. A developer says: "I added an export of orders to Excel, have a look by the end of the day". There is no documentation, no ticket history and no mockups. The interviewer is checking that you neither refuse to test nor test at random.

Що роблю. Перше — збираю неявні оракули: 15 хвилин розмови з розробником і PO про мету (хто і навіщо експортуватиме), схожі функції в нашому продукті (експорт клієнтів уже є), поведінку конкурентів, загальні стандарти (формат дат, кодування, ліміти Excel на рядки). Друге — записую припущення в журнал і надсилаю PO на підтвердження: так мовчазні рішення стають явними. Третє — тестую дослідницькими сесіями за чартерами, а знайдене перетворюю на чекліст, який стане основою майбутньої регресії.

What I do. First, I gather implicit oracles: 15 minutes with the developer and the PO about the goal (who will export and why), similar features in our product (a customer export already exists), competitors' behaviour and general standards (date format, encoding, Excel row limits). Second, I write my assumptions into a log and send it to the PO for confirmation: that way silent decisions become explicit. Third, I test in exploratory sessions with charters, and turn what I find into a checklist that becomes the basis of future regression.

Результат. Журнал нижче показує, як припущення перетворюються на рішення. Два з п'яти PO виправив — без журналу це були б «баги», які насправді ніхто не просив, або навпаки, пропущені вимоги.

Outcome. The log below shows assumptions turning into decisions. The PO corrected two of the five — without the log they would have been "bugs" nobody actually asked for or, the other way round, missed requirements.

Підводні камені. Мовчки тестувати за власними уявленнями, а потім сперечатися про кожен баг. Відмовитись до появи повного ТЗ — у реальних проєктах його може не бути ніколи. Забути повернути підтверджені припущення в документацію або в критерії приймання.

Pitfalls. Silently testing against your own ideas and then arguing over every bug. Refusing until a full specification appears — in real projects it may never come. Forgetting to put the confirmed assumptions back into the documentation or the acceptance criteria.

Журнал припущень
Assumptions log
#  │ Припущення                      │ Оракул           │ Відповідь PO
───┼─────────────────────────────────┼──────────────────┼──────────────
A1 │ експортуються лише замовлення   │ поточний фільтр  │ так
   │ з поточним фільтром на екрані   │ експорту клієнтів│
A2 │ формат .xlsx, дати ДД.ММ.РРРР   │ експорт клієнтів │ так
A3 │ суми з ПДВ                      │ екран замовлення │ НІ: без ПДВ +
   │                                 │                  │ окрема колонка
A4 │ максимум 1 048 576 рядків       │ ліміт Excel      │ НІ: до 50 000,
   │                                 │                  │ далі — помилка
A5 │ менеджер бачить лише свої       │ права в списку   │ так
   │ замовлення в експорті           │ замовлень        │
#  │ Assumption                      │ Oracle           │ PO answer
───┼─────────────────────────────────┼──────────────────┼──────────────
A1 │ only orders matching the        │ customer export  │ yes
   │ current on-screen filter        │ filter           │
A2 │ .xlsx format, dates DD.MM.YYYY  │ customer export  │ yes
A3 │ amounts include VAT             │ order screen     │ NO: excl. VAT
   │                                 │                  │ + VAT column
A4 │ up to 1,048,576 rows            │ Excel limit      │ NO: up to
   │                                 │                  │ 50,000, then error
A5 │ a manager sees only their own   │ order list       │ yes
   │ orders in the export            │ permissions      │
🔧 Як читати: кожне припущення має номер, на який можна посилатися в багах і тест-кейсах. Стовпець «Оракул» пояснює, звідки взялось очікування. Відповіді «НІ» — найцінніше: вони змінюють очікувані результати ще до того, як ти витратив час на хибні звіти. 1 048 576 — справжній ліміт рядків аркуша в сучасному Excel.
🔧 How to read it: each assumption has a number that bugs and test cases can refer to. The "Oracle" column explains where the expectation came from. The "NO" answers are the most valuable: they change the expected results before you spend time on false reports. 1,048,576 is the real row limit of a worksheet in modern Excel.
💡 Простими словами: немає вимог — зроби свої припущення видимими і дай бізнесу їх підтвердити.
💡 In plain words: no requirements — make your assumptions visible and let the business confirm them.
🗣 Як читати вголос Я не чекаю ідеального ТЗ і не тестую навмання. Спочатку витягую неявні вимоги: коротко говорю з розробником і продактом про мету, дивлюсь, як схожа функція вже працює в нас і в конкурентів. Потім пишу журнал припущень і прошу продакта пройтись по ньому, це займає десять хвилин. Останнього разу він виправив мені два пункти з п'яти, зокрема що суми мають бути без ПДВ. Далі тестую дослідницькими сесіями, а підтверджені припущення переношу в критерії приймання, щоб наступного разу вимоги вже були.
🗣 How to say it out loud I neither wait for a perfect spec nor test at random. First I dig out the implicit requirements: a short talk with the developer and the product owner about the goal, and a look at how a similar feature already works in our product and at competitors. Then I write an assumptions log and ask the product owner to go through it, which takes ten minutes. Last time he corrected two items out of five, including that amounts should exclude VAT. After that I test in exploratory sessions, and move the confirmed assumptions into the acceptance criteria so that next time the requirements already exist.
69 Реліз завтра, а часу на повне тестування немає — що ти перевіриш першим і як про це скажеш? The release is tomorrow and there is no time for full testing — what do you check first and how do you communicate it?
СтратегіяStrategy Senior ▶

Ситуація. Збірка прийшла о 16:00, реліз завтра о 10:00, регресія вручну займає два дні. Інтерв'юер хоче почути не «працюватиму вночі», а план пріоритезації і чесну комунікацію ризику. Рішення про реліз ухвалює бізнес; задача QA — дати йому точну картину.

Situation. The build arrived at 16:00, the release is tomorrow at 10:00, and manual regression takes two days. The interviewer wants to hear not "I will work all night" but a prioritisation plan and honest communication of risk. The business makes the release decision; QA's job is to give it an accurate picture.

Порядок. Перші 30 хвилин — smoke: збірка розгорнулась, логін, головний сценарій працює; якщо ні, далі тестувати немає сенсу. Потім зміни цього релізу: що саме змінено, за diff і тікетами, і що від цього залежить. Далі «грошові» й критичні шляхи: реєстрація, оплата, оформлення замовлення. Потім області з історією дефектів. Автотести запускаю паралельно з першої хвилини. Останнім іде все, що має низький ризик, — і саме це свідомо не встигаємо.

Order. The first 30 minutes are smoke: the build deployed, login works, the main scenario runs; if not, there is no point testing further. Then this release's changes: what exactly changed, from the diff and the tickets, and what depends on it. Next the money and critical paths: sign-up, payment, checkout. Then areas with a defect history. Automated checks run in parallel from the first minute. Last comes everything low-risk — and that is exactly what we knowingly do not reach.

Комунікація. Увечері надсилаю PO коротке повідомлення: що перевірено, що ні, які відомі дефекти лишились і яка моя рекомендація. Варіанти теж пропоную: реліз з вимкненою через feature flag ризиковою частиною, реліз зі швидким моніторингом після запуску або перенесення на день.

Communication. In the evening I send the PO a short message: what was checked, what was not, which known defects remain and what I recommend. I also offer options: release with the risky part switched off behind a feature flag, release with close monitoring right after launch, or a one-day postponement.

Підводні камені. Мовчки скоротити тестування і сказати «все ок». Взяти на себе рішення про реліз замість бізнесу. Тестувати в порядку тест-сьюта, а не за ризиком, і до ранку не дійти до оплати.

Pitfalls. Silently cutting testing and saying "all good". Taking the release decision instead of the business. Testing in test-suite order rather than by risk and never reaching payment before morning.

План на вечір і повідомлення PO
Evening plan and message to the PO
16:00  smoke збірки 3.8.0 (деплой, логін, пошук)     30 хв
16:30  зміни релізу: нова доставка, промо в кошику   2 год
18:30  оплата: картка, Apple Pay, повернення          1 год
19:30  зони з багами минулих релізів (кошик, фільтр) 1 год
весь час  автотести API + UI на CI паралельно
НЕ встигаємо: профіль, налаштування сповіщень, футер

Повідомлення PO, 20:30:
Перевірено: smoke, нова доставка, промо, оплата (3 способи).
Не перевірено: профіль, сповіщення — змін там не було,
  автотести зелені, ризик низький.
Відкриті баги: BUG-1204 (Minor, текст у листі).
Рекомендація: реліз о 10:00; доставку тримати за
  feature flag, моніторинг помилок оплати першу годину.
16:00  smoke of build 3.8.0 (deploy, login, search)  30 min
16:30  release changes: new delivery, cart promo     2 h
18:30  payment: card, Apple Pay, refund              1 h
19:30  areas with past-release bugs (cart, filter)   1 h
always  API + UI automated checks on CI in parallel
NOT reached: profile, notification settings, footer

Message to PO, 20:30:
Checked: smoke, new delivery, promo, payment (3 methods).
Not checked: profile, notifications — no changes there,
  automated checks green, low risk.
Open bugs: BUG-1204 (Minor, email text).
Recommendation: release at 10:00; keep delivery behind a
  feature flag, watch payment errors for the first hour.
🔧 Як читати: план упорядкований за ризиком, а не за модулями: спершу те, без чого немає сенсу продовжувати, потім змінене, потім гроші. Рядок «НЕ встигаємо» так само важливий, як і перевірене. Повідомлення має чотири частини — перевірено, не перевірено з обґрунтуванням, відкриті баги, рекомендація з варіантом зниження ризику.
🔧 How to read it: the plan is ordered by risk, not by module: first what makes further testing pointless if it fails, then what changed, then money. The "NOT reached" line matters as much as what was checked. The message has four parts — checked, not checked with a reason, open bugs, and a recommendation with a way to reduce the risk.
💡 Простими словами: коли часу мало, тестуй найважливіше першим і чесно називай те, що лишилось неперевіреним.
💡 In plain words: when time is short, test what matters most first and name honestly whatever stays untested.
🗣 Як читати вголос Я не обіцяю повну регресію за ніч, я пріоритезую. Спочатку пів години smoke, бо без робочої збірки решта не має сенсу. Далі саме те, що змінилось у релізі, потім оплата і оформлення замовлення, потім місця, де раніше часто були баги. Автотести крутяться паралельно. Увечері пишу продакту коротко: що перевірив, що ні і чому вважаю це прийнятним, які баги відкриті, і що раджу, наприклад тримати нову доставку за прапорцем. Рішення про реліз приймає бізнес, а моя задача — щоб воно було усвідомленим.
🗣 How to say it out loud I do not promise full regression overnight; I prioritise. First half an hour of smoke, because without a working build nothing else makes sense. Then exactly what changed in the release, then payment and checkout, then the places that used to be buggy. Automated checks run in parallel. In the evening I write a short note to the product owner: what I checked, what I did not and why I think that is acceptable, which bugs are open, and what I suggest, for example keeping the new delivery behind a flag. The business makes the release call; my job is to make sure it is an informed one.