vyvchy
    Теми розділу

    02 · Тест-дизайн

    Таблиці рішень

    Зміст

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

    Таблиця рішень (decision table) — техніка саме для цього: вона змушує виписати всі умови, всі дії та всі їх комбінації в одну компактну структуру, де прогалини й суперечності видно очима ще до першого тесту. На співбесідах це одна з найчастіших тем тест-дизайну: «побудуйте таблицю для знижки», «скільки тестів потрібно для трьох умов», «що таке don't care» — класика для рівня junior і вище.

    Коли таблиця, а коли ні

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

    Межі техніки теж варто знати, бо про них питають:

    СитуаціяЩо взяти
    Результат залежить від комбінації незалежних умов «тут і зараз»Таблиця рішень
    Результат залежить від історії: що було до цього, у якому стані обʼєктПереходи станів
    Одне поле з діапазонами значеньКласи еквівалентності + межі
    Багато параметрів без жорстких правил між ними (конфігурації, фільтри)Попарне тестування

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

    Структура: умови, дії, правила

    Таблиця складається з трьох частин:

    • Умови (conditions) — рядки у верхній частині: те, від чого залежить поведінка. У базовій, обмеженій формі (limited-entry) кожна умова бінарна: істина (T) або хиба (F).
    • Дії (actions) — рядки в нижній частині: те, що система робить. Позначка X у клітинці — «дія виконується».
    • Правила (rules) — колонки: кожна колонка задає одну комбінацію умов і дії, які їй відповідають. Правило читається зверху вниз: «якщо умови такі — роби ось це».

    Розберемо на живій вимозі. Специфікація інтернет-магазину каже:

    Доставка безкоштовна для замовлень від 1000 грн. Власникам преміум-підписки доставка безкоштовна завжди. В інших випадках діє тариф 80 грн. Преміум-підписка доступна лише залогіненим користувачам.

    Виписуємо умови й дії:

    • У1: користувач залогінений
    • У2: у користувача преміум-підписка
    • У3: сума замовлення від 1000 грн
    • Д1: доставка безкоштовна
    • Д2: тариф 80 грн

    Зверни увагу: «сума замовлення» — не бінарна умова, а діапазон. У таблицю вона потрапляє вже як предикат «сума ≥ 1000», тобто після розбиття на класи еквівалентності. Конкретні значення для тестів (999, 1000) потім дадуть граничні значення — техніки працюють разом, а не замість одна одної.

    Повна таблиця: 2^n правил

    Кожна бінарна умова подвоює кількість комбінацій, тож повна таблиця для n умов має 2^n правил. Для наших трьох умов — 8 колонок:

    П1П2П3П4П5П6П7П8
    У1: залогіненийTTTTFFFF
    У2: преміумTTFFTTFF
    У3: сума ≥ 1000TFTFTFTF
    Д1: безкоштовна доставкаXXX??X
    Д2: тариф 80 грнX??X

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

    Зростання 2^n — головне обмеження техніки: 5 умов — це 32 колонки, 10 — уже 1024. Тому повну таблицю будують для добірки звʼязаних умов (зазвичай 3–5), а не для всієї фічі одразу. Якщо умов справді багато й вони слабо повʼязані — це сигнал подивитись у бік попарного тестування.

    Згортання: don't care і неможливі комбінації

    Повну таблицю стискають двома інструментами.

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

    Don't care («байдуже», позначається «—») — випадок, коли значення умови не впливає на результат. Подивись на П1 і П2: якщо преміум є, доставка безкоштовна незалежно від суми. Дві колонки зливаються в одну з «—» у рядку суми. Так само П3 і П7: якщо преміуму немає, а сума достатня, — байдуже, залогінений користувач чи гість.

    Згорнута таблиця:

    К1К2К3
    У1: залогіненийT
    У2: преміумTFF
    У3: сума ≥ 1000TF
    Діябезкоштовнабезкоштовнатариф 80 грн

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

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

    Вимоги: «якщо… і… то…»

    Випиши умови та дії

    Повна таблиця: 2^n правил

    Викресли неможливі комбінації

    Згорни через don't care

    Мінімум один тест-кейс
    на кожне правило

    Вимоги: «якщо… і… то…»

    Випиши умови та дії

    Повна таблиця: 2^n правил

    Викресли неможливі комбінації

    Згорни через don't care

    Мінімум один тест-кейс
    на кожне правило

    Від правила до тест-кейсу

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

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

    • К1: преміум-користувач, сума — будь-яка з валідного класу, наприклад 200 грн. Очікування: доставка 0 грн.
    • К2: преміум відсутній, сума рівно 1000 грн — беремо граничне значення, бо саме на межі живуть off-by-one баги. Для don't care у рядку «залогінений» можна взяти гостя — так кейс заодно зачепить менш очевидну гілку.
    • К3: без преміуму, сума 999 грн — друга точка тієї ж межі. Очікування: тариф 80 грн.

    Таблиця природно лягає в параметризований автотест: колонки стають елементами масиву даних, а тест один.

    const rules = [
      { name: 'преміум: безкоштовно незалежно від суми', premium: true, total: 200, shipping: 0 },
      { name: 'сума 1000: безкоштовно без преміуму', premium: false, total: 1000, shipping: 0 },
      { name: 'без пільг: стандартний тариф', premium: false, total: 999, shipping: 80 },
    ];
    
    for (const rule of rules) {
      test(`доставка — ${rule.name}`, async ({ page }) => {
        await seedCart(page, { premium: rule.premium, total: rule.total });
        await expect(page.getByTestId('shipping-cost')).toHaveText(String(rule.shipping));
      });
    }

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

    Cause-effect: звідки беруться умови

    Найважчий крок техніки — не побудова таблиці, а видобування умов із розлогого тексту вимог. Тут допомагає причинно-наслідковий граф (cause-effect graph) — класична техніка, яку популяризував Гленфорд Маєрс у «The Art of Software Testing»: причини (входи й умови) зʼєднуються з наслідками (діями системи) логічними звʼязками І/АБО/НЕ, а обмеження фіксують залежності між самими причинами — наприклад, «преміум вимагає залогіненості».

    так

    ні

    вимагає

    Преміум-підписка

    АБО

    Сума замовлення ≥ 1000 грн

    Доставка безкоштовна

    Тариф 80 грн

    Користувач залогінений

    так

    ні

    вимагає

    Преміум-підписка

    АБО

    Сума замовлення ≥ 1000 грн

    Доставка безкоштовна

    Тариф 80 грн

    Користувач залогінений

    Граф і таблиця — два подання тієї самої логіки: граф зручно малювати, поки розплутуєш текст вимог, а таблицю — заповнювати й перевіряти на повноту. Класичний воркфлоу: прочитав вимоги → виписав причини й наслідки → звʼязав логікою → переніс причини в рядки умов, наслідки в рядки дій → перебрав комбінації. На практиці граф часто пропускають і йдуть одразу в таблицю — це нормально; але коли вимоги заплутані й суперечливі, проміжний граф рятує: суперечність двох речень специфікації на графі видно як конфлікт звʼязків.

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

    Типові помилки

    • Виглядає як «три умови — три тести: перевірю кожну окремо», а насправді логіка живе в комбінаціях: кожна умова окремо може працювати, а разом — ні. Мінімум — тест на кожне правило таблиці, а не на кожну умову.
    • Виглядає як «don't care — можна підставити будь-що й забути», а насправді це твердження, що результат однаковий за обох значень, — і його треба підтвердити специфікацією. Необґрунтований «—» ховає рівно ті баги, заради яких таблицю будували.
    • Виглядає як «неможливу комбінацію викреслив — і по всьому», а насправді «неможливе» іноді приходить: прямим викликом API, багом сусідньої системи, гонкою двох запитів. Викреслити з таблиці — так; викреслити з голови — ні.
    • Виглядає як «дві колонки з однаковими умовами й різними діями — я помилився в таблиці», а насправді це часто суперечність у самих вимогах: два речення специфікації командують різне. Така знахідка цінніша за десяток прогнаних тестів.
    • Виглядає як «сума замовлення — одна умова», а насправді це діапазон, який спершу треба розбити на класи еквівалентності; у таблицю заходить уже готовий предикат. Якщо запхати в одну умову кілька порогів — таблиця перестане бути бінарною й розповзеться.

    Підсумок

    • Таблиця рішень — техніка для логіки, де результат визначає комбінація умов, а не кожна умова окремо; сигнал — вимоги у стилі «якщо… і… то…».
    • Структура: умови й дії — рядки, правила — колонки; повна таблиця для n бінарних умов має 2^n правил.
    • Згортання — через don't care (умова не впливає на результат — підтверджено!) і викреслення неможливих комбінацій; покриття логіки при цьому не втрачається.
    • Мінімальне покриття — один тест-кейс на кожне правило згорнутої таблиці; конкретні дані для кейсу дають класи еквівалентності та граничні значення.
    • Таблиця — ще й інструмент рев'ю вимог: суперечності, прогалини й «а що, як?» видно на етапі заповнення, до першого запуску тесту.

    Що питають на співбесіді

    • «Скільки тестів потрібно для трьох (чотирьох, пʼяти) умов?» Пастка на розуміння 2^n: повна таблиця — 8 (16, 32) правил, але відповідь сильного кандидата продовжується словами «…а після згортання неможливих комбінацій і don't care — менше; мінімум один кейс на правило згорнутої таблиці». Інтервʼюер дивиться, чи не зупинишся ти на механічному 2^n.
    • «Що таке don't care і коли ним можна користуватися?» Перевіряють, чи розумієш різницю між «байдуже» як доведеним фактом і як лінню. Згадай, що don't care вимагає підтвердження специфікацією.
    • «Чим таблиця рішень відрізняється від класів еквівалентності? А від переходів станів?» Дивляться на розуміння меж технік: класи — про діапазони одного параметра, таблиця — про комбінації умов, стани — про залежність від історії.
    • «Побудуйте таблицю рішень для знижки/тарифу/доступу» — практична задача, найчастіший формат. Інтервʼюер оцінює процес: чи випишеш умови й дії з тексту, чи помітиш неможливі комбінації, чи поставиш уточнювальні питання про суперечності замість мовчки щось припустити. Розгорнутий розбір таких задач — у главі про класичні задачі співбесід.
    • «Що робити, якщо умов десять?» Перевірка на здоровий глузд: 1024 колонки ніхто не будує — розбити логіку на незалежні таблиці, згорнути, а для слабозвʼязаних параметрів перейти до попарного тестування.

    Джерела

    • ISTQB CTFL Syllabus v4.0 — розділ 4.2.3 «Decision Table Testing»: ця глава покриває його повністю, плюс cause-effect graphing поза силабусом.
    • Глосарій ISTQB — канонічні означення термінів decision table testing, cause-effect graphing, coverage item.
    • ISO/IEC/IEEE 29119-4 «Software and systems engineering — Software testing — Part 4: Test techniques» — формальний опис decision table testing і cause-effect graphing як специфікаційних технік.
    • Glenford Myers, Corey Sandler, Tom Badgett — «The Art of Software Testing» (3rd ed., Wiley, 2011) — класичний розгорнутий опис cause-effect graphing із повною нотацією обмежень.