Тестування білої скриньки базується на внутрішній структурі об’єкта тестування. Методи тестування білої скриньки можна використовувати на всіх рівнях тестування. Існує велика кількість технік тестування білої скриньки. Зокрема і доволі комплексні техніки, які використовуються в деяких критично важливих для безпеки середовищах або середовищах із високим рівнем цілісності для досягнення більш повного покриття.
Техніки тестування білої скриньки часто використовуються паралельно з техніками статичного аналізу і доповнюють одна одну.
Structure-based or White-box
В англомовній літературі терміни structure-based та white-box є синонімами, тому якщо зустрічаєте їх, то мова йде про тестування білої скриньки.
Тестування на основі структури або білої скриньки базується на визначеній структурі програмного забезпечення або системи і включає наступні техніки:
- Тестування операторів, заяв і покриття (Statement testing)
- Тестування рішень і покриття (Decision Tetsing)
- Тестування умов (Condition Testing)
- Тестування множинних умов (Multiple Condition Testing)
- Тестування шляхів та покриття (Path Coverage)
Тестування операторів
Тестування операторів (Statement testing) перевіряє потенційні виконувані оператори в коді.
Покриття вимірюється як кількість операторів, виконаних тестами, поділена на загальну кількість виконуваних операторів у тестовому об’єкті, зазвичай виражається у відсотках.
Тестування рішень
Тестування рішень перевіряє рішення в коді та перевіряє код, який виконується на основі результатів рішень. Для цього тестові випадки слідують за потоками керування, які відбуваються з точки прийняття рішення (наприклад, для оператора IF, один для істинного результату та один для помилкового результату; для оператора CASE тестові випадки будуть потрібні для всіх можливих результатів, включаючи результат за замовчуванням).
Покриття вимірюється як кількість результатів рішень, виконаних тестами, поділена на загальну кількість результатів рішень в об’єкті тестування, зазвичай виражається у відсотках.
Приклад 1
Нижче наводиться приклад коду і потрібно визначити скільки тестів забезпечить 100% покриття операторів (statements), а скільки відповідно – рішень (decisions).
- Disc = 0 //statement буде зображуватися у вигляді прямокутника
- Order –qty = 0 //statement буде зображуватися у вигляді прямокутника
- Read Order-qty //statement буде зображуватися у вигляді прямокутника
- If Order-qty >= 20 then //condition буде зображуватися у вигляді ромба
- Disc = 0.05 //statement буде зображуватися у вигляді прямокутника
- If Order-qty>=100 then //condition буде зображуватися у вигляді ромба
- Disc = 0.1 //statement буде зображуватися у вигляді прямокутника
- End If //закінчення блоку буде зображуватися у вигляді малого прямокутника
- End If //закінчення блоку буде зображуватися у вигляді малого прямокутника
З прикладу видно, що для покриття операторів знадобиться лише один тест кейс, який слід спроєктувати таким чином, щоб він пройшов в обох випадках по гілках true і таким чином пройшов через усі оператори (statements) в даному прикладі коду. А от для покриття рішень знадобиться 3 тест кейси: 1 тест кейс у в першій умові обере true і в другій умові також true, 2 тест кейс у в першій умові обере true, а в другій умові обере false, 1 тест кейс у в першій умові обере false. Таким чином будуть виконані всі гілки, тобто рішення в даному прикладі.
Приклад 2
Нижче наводиться приклад коду і аналогічно до попереднього прикладу потрібно визначити скільки тестів забезпечить 100% покриття операторів (statements), а скільки відповідно – рішень (decisions).
- Ask: “What type of ticket do you require, single or return?” //statement буде зображуватися у вигляді прямокутника
- If the customer wants ‘return’ //condition буде зображуватися у вигляді ромба
- Ask: “What rate, Standard or Cheap-day”? //statement буде зображуватися у вигляді прямокутника
- If the customer replies ‘Cheap-day’ //condition буде зображуватися у вигляді ромба
- Say: “That will be $11.20” //statement буде зображуватися у вигляді прямокутника
- Else // блок else для найближчого if означає, що гілка false матиме вміст
- Say: “That will be $19.50” //statement буде зображуватися у вигляді прямокутника
- Endif //закінчення блоку буде зображуватися у вигляді малого прямокутника
- Say: ”That will be $9.75” //statement буде зображуватися у вигляді прямокутника
- Endif //закінчення блоку буде зображуватися у вигляді малого прямокутника
З прикладу видно що для покриття операторів і рішень знадобиться однакова кількість тест кейсів, а саме три. Це особливий випадок, оскільки частіше для покриття операторів потрібно менше тест кейсів ніж для покриття рішень. Для того, щою пройти через усі оператори доведеться спроєктувати три тест кейси: 1 тест кейс в першій умові пройде по гілці true і у вкладеній умові обере також true, 2 тест кейс в першій умові пройде по гілці true, а у вкладеній умові обере false, 3 тест кейс в першій умові піде по гілці false. Це забезпечить також і покриття рішень.
Приклад 3
Нижче наводиться приклад коду і знову потрібно визначити скільки тестів забезпечить 100% покриття операторів (statements), а скільки відповідно – рішень (decisions).
- If width>length //condition буде зображуватися у вигляді ромба
- Then biggest_dimension=width //statement буде зображуватися у вигляді прямокутника
- If height>width //condition буде зображуватися у вигляді ромба
- Then biggest_dimension=height //statement буде зображуватися у вигляді прямокутника
- End_if //закінчення блоку буде зображуватися у вигляді малого прямокутника
- Else biggest_dimension=length //statement буде зображуватися у вигляді прямокутника
- If height>length //condition буде зображуватися у вигляді ромба
- Then biggest_dimension=height //statement буде зображуватися у вигляді прямокутника
- End_if //закінчення блоку буде зображуватися у вигляді малого прямокутника
- End_if //закінчення блоку буде зображуватися у вигляді малого прямокутника
В цьому прикладі для покриття операторів знадобиться 2 тест кейси: 1 тест кейс пройде по гілці true у першій умові і далі у вкладеній умові обере також true, 2 тест кейс пройде по гілці false першої умови і далі у вкладеній умові обере true. Таким чином будуть виконані всі оператори statements. А от для покриття рішень знадобиться всього 4 тест кейси, оскільки потрібно покрити гілки false у вкладених умовах.
Цикломатична складність Маккейба
Цикломатична складність Маккейба — це максимальна кількість лінійних незалежних шляхів у програмі. Формула цикломатичної складності:
M = L – N + 2*P
Де L – кількість ребер/ланок у графі, N – кількість вузлів у графі, P – кількість з’єднаних компонентів.
Наведемо приколад розрахунку цього показника за допомогою зразка коду нижче.
- IF A=575 //condition буде зображуватися у вигляді ромба
- THEN IF B>C //condition буде зображуватися у вигляді ромба
- THEN A=B //statement буде зображуватися у вигляді прямокутника
- ELSE A=C //statement буде зображуватися у вигляді прямокутника
- ENDIF //закінчення блоку буде зображуватися у вигляді малого прямокутника
- ENDIF //закінчення блоку буде зображуватися у вигляді малого прямокутника
- Print A //statement буде зображуватися у вигляді прямокутника
Потік керування показує сім вузлів (фігур) і вісім ребер (лінії), таким чином, використовуючи формальну формулу, цикломатична складність становить 8-7 + 2*1=3.
Цінність White Box
Фундаментальна сильна сторона всіх методів білої скриньки полягає в тому, що під час тестування враховується вся реалізація програмного забезпечення, що полегшує виявлення дефектів, навіть якщо специфікація програмного забезпечення розпливчаста, застаріла або неповна. Відповідна слабкість полягає в тому, що якщо програмне забезпечення не реалізує одну або більше вимог, тестування білої скриньки може не виявити дефекти в результаті таких упущень (Watson 1996).
Методи білого ящика можна використовувати у статичному тестуванні (наприклад, під час пробних прогонів). Вони добре підходять для перегляду коду, який ще не готовий до виконання (Hetzel 1988), а також псевдокоду та іншої логіки високого рівня або низхідної логіки, яку можна моделювати за допомогою графа потоку керування.
Виконання лише тестування чорної скриньки не забезпечує вимірювання фактичного покриття коду. Показники покриття білої скриньки забезпечують об’єктивне вимірювання покриття та надають необхідну інформацію, щоб дозволити створити додаткові тести для збільшення цього покриття та згодом підвищити довіру до коду.
Коли досягнуто 100% охоплення операторів (statements), це гарантує, що всі виконувані оператори в коді були протестовані принаймні один раз, але це не гарантує, що перевірено всю логіку прийняття рішень. З двох методів білої скриньки, які розглядалися, тестування операторів може забезпечити менше покриття, ніж тестування рішень.
Коли досягнуто 100% покриття рішень, то виконуються всі результати рішення, що включає перевірку справжнього результату, а також хибного результату, навіть якщо немає явного хибного оператора (наприклад, у випадку оператора IF без else в коді).
Покриття операторів допомагає знайти дефекти в коді, які не перевірялися іншими тестами. Покриття рішень допомагає знаходити дефекти в коді, де інші тести не приймають ні істинних, ні хибних результатів.
Досягнення 100% покриття рішень гарантує 100% покриття заяв (але не навпаки).
В цьому відео поговоримо про тестування білої скриньки:
00:05 Тестування білої скриньки
10:22 Structure-based or White-box
16:42 Тестування операторів (Statement Testing)
17:28 Тестування рішень (Decision testing)
18:52 Приклад 1 Statement and Decision Testing
26:38 Приклад 2 Statement and Decision Testing
34:51 Приклад 3 Statement and Decision Testing
43:00 Цикломатична складність Маккейба
48:20 Цінність White Box