Що не так з використанням техніки «Аналіз граничних значень»

💡 Усі статті, обговорення, новини про тестування — в одному місці. Приєднуйтесь до QA спільноти!

Привіт, шановні колеги. Мене звати Володимир Поздняков. Я QA-інженер з майже 6-річним стажем роботи в аутсорсі. Починав з ручного тестування, виріс в QA Lead, а зараз більшу частину часу займаюсь автоматизованим тестуванням.

Минулого разу ми обговорили тему використання техніки аналізу класів еквівалентності, та чому без глибшого її розуміння можливо допускати помилки у виявленні тих самих класів.

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

Застосування техніки тестування «Аналіз граничних значень»

Я: Ми більш менш розібрались, що лежить в основі класів еквівалентності та на що треба звертати увагу для більш точного та кваліфікованого визначення цих самих класів. А що там з граничними значеннями? Чи знайома тобі ця техніка?

Легковайті Тестущенко: Ну, ти таке питаєш [закочує очі до неба]... Та звісно, знайома! Це ж перше, з чого починаються будь-які курси з тестування.

Я: Чудово! То про що ж нам каже ця техніка? Вангую, що тобі знов допоможе всемогутній гугл? :)

Легковайті Тестущенко: А то! Ось, що кажуть нам декілька відповідей з інтернету:

Або так:

І так:

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

  1. на границі;
  2. зліва від границі;
  3. справа від границі.

Вірно?

Легковайті Тестущенко: Так! Сам же бачиш, що вірно [невпевнено примружується]... Ще скажи, що щось і тут не так — не повірю, бо це ж майже скрізь так написано і так використовується.

Я: Нууу... Так, проте не так :)

Легковайті Тестущенко: Твою ж.. Що на цей раз не так?

Я: Нумо розбиратися. І, як завжди, краще це буде зробити на прикладі. Візьмемо якусь надпросту вимогу:

Якщо користувач ввів число менше 1, то система повинна вивести «Х»,
якщо 1 і більше — вивести «Y».

Доволі просто, чи не так?

Легковайті Тестущенко: Ага [з підозрою].

Я: Тоді давай зобразимо це, як нам рекомендується, у вигляді числового променя з граничним значенням 1 та двома значеннями з боків:

Все вірно? Чи може я щось упустив?

Легковайті Тестущенко: Так. Все так. Навіть малюнок вийшов схожий з тими, що в інтернеті.

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

Легковайті Тестущенко: Звісно, знаю [у голосі чуються нотки роздратування]. Будь-яке програмне забезпечення — це по суті своїй програмний код. І всі умови, де є розгалуження логіки, як у твоєму прикладі, в програмному коді формуються однаково, використовуючи спеціальні знаки порівняння, подібні до тих, які використовуються в математичних виразах, тобто > (більше), < (менше), >= (більше або дорівнює), <= (менше або дорівнює).

І якщо в цьому випадку ми маємо доволі просте порівняння у вигляді <1 та >=1, то в реальному житті такі логічні вирази можуть бути доволі складними, що в рази підвищує ймовірність помилки.

Наприклад, якщо розробник зробив помилку і замість >= поставив >, тобто в нашому випадку: <1 та >1. Тоді ми бачимо, що значення 1 ніколи не увійде ні в який діапазон, і це призведе до неочікуваного результату.

Я: Ого, дякую. Яка розгорнута відповідь. Все саме так, як ти кажеш, і як приклад коду це може бути щось на кшталт цього:

function getRelatedData(num) {
    if (num < 1) {
        return "X";
    } else {
        return "Y";
    }
}

Все ж таки круто, що тестувальники розуміють, звідки «ноги ростуть». Отже, повернімося до нашого випадку.

Головна проблема в тому, що зображення числового променя графічно некоректне, що і призводить до невірної інтерпретації техніки.

У нашому випадку є два класи еквівалентності і значення, яким закінчується перший клас, однозначне і повністю визначене — це 0, а значення, з якого починається наступний клас еквівалентності, також однозначне і визначене — це 1. Кожне із цих чисел є граничним значенням для свого класу еквівалентності. Між цими числами не існує нічого, крок між ними — це порожнеча [нависає ніякове мовчання і тиша]!

Немає ніякого «значення на границі», «зліва від границі», «справа від границі»! Є лише значення границі одного класу і іншого. Ось так:

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

  1. кінцеве значення першого класу;
  2. початкове значення наступного класу.

Легковайті Тестущенко: Хм... Так, тепер я бачу, що весь час робив зайві перевірки.

Я: А скажи-но мені ось що. Тепер, розуміючи дійсні граничні значення, до чого ж тоді буде відноситись число 2, яке нам так радили брати для перевірки?

Легковайті Тестущенко: Очевидно, що число 2 вже буде належати множині чисел класу еквівалентності, а не до граничних значень.

Я: Вірно. І поглянь, якби нам було потрібно протестувати цю вимогу з використанням аналізу класів еквівалентності та граничних значень, то ми, вже як досвідчені спеціалісти, робили б 4 перевірки (дві на перевірку граничних значень, дві на перевірку двох класів еквівалентності) замість 5, які нам так непрофесійно навʼязували.

Ця різниця здається нікчемною на такому простому прикладі, 4 проти 5, але коли в реальному житті доводиться тестувати складні і розгалужені застосунки — це може суттєво скоротити тестування і не марнувати час на безглузді перевірки.

Легковайті Тестущенко: Згоден з тобою. Шкода, що раніше про це не замислювався [перед очима промайнуло все життя].

Замість висновку

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

P.S. Заради справедливості все ж додам, що обидва ці підходи тестування граничних значень (з використанням двох і трьох значень) описані в стандарті ISO/IEC/IEEE 29119-4. Але і Rex Black, і Dorothy Graham, і більшість професіоналів зі сфери тестування погоджуються, що ефективнішим і доцільнішим підходом є саме тестування двох, а не трьох значень на границі. І навіть в самому стандарті використання трьох значень звучить більше як виключення аніж правило:



Two-value boundary value testing is typically adequate in most situations; however, three-value boundary testing could be required for certain circumstances (e.g. for rigorous testing to check that no errors were made in determining the boundaries of variables in the test item by both testers and developers).

Дякую за увагу. В наступній статті поговоримо про використання попарного тестування (Pairwise testing).

👍ПодобаєтьсяСподобалось8
До обраногоВ обраному5
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Цікаво, але розробник може як включити так і виключити граничне значення. Наприклад: Знижка діє до 12 одиниц товару. А якщо 12? Воно ще по знижці, чи ні? А де вимоги? Якщо вимог нема, то треба дивитись, якщо у вимогах не написано корректно, то питання постає, а куди саме 12 подіти?! Тож мені треба тестувати 11, 12, 13. Бо не ясно, як працює на 11, куди 12, і чи не випадає 13! А якщо я просунутий КуА, я можу пойти у код, і просто подивитись, не тестуючи, і побачити, які з цих варіантів куди попадуть.
А якщо брати якісь математичні функції, а не прості умови, то може виявитись, що десь в середині можуть бути особливі умови — значення функії, які випадають за межі, чи декілька рішень.

Тут дуже дискусійне питання.
По суті, значення в серидині діапазону, які не входять до граничних значень- також окремий класс еквівалентності який треба перевіряти. Тому роблять 5 перевірок, а не 6 :)
P.S. Приклад підібраний не дуже вдало.
Якщо взяти наприклад дисконтну систему, де дається більша знижка після певної суми покупки, то це краще б проілюструвало ідею автора

Мені здається переклад «Межові значення» є більш коректним 😉

И снова так, да не так...
Ошибка — в Вашем неумении использовать equivalence partitioning, на которое я уже указывал в предыдущей статье. Я бы рекомендовал Вам найти хорошего ментора, иначе — чему же Вы свою команду научите-то?
Давайте ещё раз рассмотрим приведенное условие:

Якщо користувач ввів число менше 1, то система повинна вивести «Х»,
якщо 1 і більше — вивести «Y».

Сколько Вы тут насчитали классов эквивалентности? 2? Шикарно. А как насчёт 0.9? Это куда? А 0.999999999999?
Итого, поехали:
1. Отрицательные числа от минимально возможного до 0;
2. 0 (да, 0 — это отдельный класс эквивалентности, поскольку он может интерпретироваться системой по-разному);
3. Положительные числа между 0 и 1;
4. Положительные числа больше 1 до максимального значения типа переменной, используемой для репрезентации данных (int, float, double) или до максимального значения, обусловленного максимальной длиной вводимой строки (аналог 1, но для отрицательной числовой полуоси);
5. Non-numberic values (включая спецсимволы).

Итого, используя BVA, получим следующие границы:
1. −3.402823466 E + 38 (я сейчас использовал для float, просто чтоб иметь конкретное значение);
2. 0;
3. 1;
4. 3.402823466 E + 38 (аналогично).

Используя техники EP + BVA, получаем следующие тест кейсы:
1. 3.402823466 E + 38 — 1;
2. −3.402823466 E + 38;
3. 3.402823466 E + 38 + 1;
4. −1000;
5. −0.0{max length}1;
6. 0;
7. 0.0{max length}1;
8. 0.9{max length}
9. 1;
10. 1.0{max length}1;
11. 1000;
12. 3.402823466 E + 38 — 1;
13. 3.402823466 E + 38
14. 3.402823466 E + 38 + 1;
15. ABC#12!

advanced-level памʼятаю на такому ловив на співбесідах працівників колишній лід

На собесах кандидаты зачастую такую дичь несут — уши вянут...
По факту, правильно применять EP умеют хорошо если треть кандидатов.
А больше половины, оказывается, в школе математику не учили ))
К примеру, −1/-1 у них получается −1 ))
Ну или то, SQRT (x) определена только при x>=0 — это, оказывается, знать не обязательно ))
За автоматизаторов вообще молчу. Те хорошо, если вообще слышали, что это такое. А написать в реалтайме нахождение чисел Фибоначчи — это рокет сайнс...

Тести заради тестів

1. 3.402823466 E + 38 — 1;
2. —3.402823466 E + 38;
3. 3.402823466 E + 38 + 1;
12. 3.402823466 E + 38 — 1;
13. 3.402823466 E + 38
14. 3.402823466 E + 38 + 1;

Та й інше теж, якщо є валідація вхідних даних і на бекенді все спирається в простий кондишн <1 та >=1

Клёво. Валидацию входящих данных проверять не надо? Поверим разрабу, что он её сделал. Ну, можно и так, пока прод не накроется )

Цікава подача інформації у вигляді діалогу ) Наразі я тільки опановую теорію, тому було корисно почитати статтю.

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

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

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

Відповідь з категорії «не подобається — не дивіться». А проблема залишається — українські QA-ліди з рівнем знань джуна.

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

Якщо користувач ввів число менше 1, то система повинна вивести «Х»,
якщо 1 і більше — вивести «Y».

я очікував сюжетний поворот, що замість границі 0-1, правильною поведінкою тестера буде спитати — а який тип даних і крок введення. Щоб границя виявилась 0.999-1

Авторе, я вірю, ви можете краще 😉

Очікував покращення після попереднього посту, але отримав чергову маніпуляцію типу «дати заздалегідь хибне твердження а потім його ж спростувати».
ISTQB чи банально Wikipedia дають досить чітку відповідь про те, як тестувати границі.
Але замість авторитетних джерел — скриншоти незрозумілою мовою 😯, і лише у висновку — посилання на стандарт і авторитетних авторів 🤔

Якщо користувач ввів число — і де сказано, яке це число? Натуральне, невід’ємне, ціле, дійсне?

читав і думав коли ж буде щось цікаве і нове )
а якщо 0 потрапив в один з класів еквівалентності?
ну нічого, більшість професіоналів же робить 2 перевірки )

Зазвичай, перевірки класів еквівалентності і граничних значень роблять послідовно, тому мені складно уявити ситуацію, коли хтось буде робити 5 перевірок, замість 4, якщо це не джун у якого руки трусяться. Чи у вас інший досвід?

І чому в математиці не допетрали досліджувати ломану функцію в точці стику різних неперервних функцій лише в ній самій і лише з одного з боків, менше же писати в зошиті. Чи тут не місце математиці?

А якщо припустити, що QC не бачить реалізацію функції і уявимо, що розробник планував реалізувати функцію наступним чином:

function getRelatedData(num) {
if (num >= 1) {
return «Y»;
} else {
return «X»;
}
}

але допустив помилку і замість >= написав тільки =, то чи буде достатньо 2 значень в цьому випадку?

тоді не скомпілиться через неявне приведення в булеан)

А якщо так?

program Hello;
var x : Integer;
begin
    writeln('Input a number: ');
    read(x);
    if (x = 1)
    then
        begin
                writeln('Yummy');
        end
    else
        begin
                writeln('Gummy');
        end;
end.

Дякую за статтю! Інформативно та з гумором.

З одного реального проєкту:

  • PM створює задачу
  • Розробник оцінює в N днів
  • PM хоче пояснень оцінки
  • Розробник розписує граничні умови
  • PM прибирає граничні умови
  • Розробник робить задачу за 1 день
  • Тестувальник заводить помилки по граничним умовам
  • Розробник виправляє за N днів

Коли ніхто не тестує вимоги, це одночасно і смішно, і не дуже)

Це погано. Значить, Вам потрібно буде їх якось зібрати.

Підписатись на коментарі