НОУ ІНТУІТ, Лекція, Тестування програмного коду (покриття)

6.3. Покриття програмного коду

6.3.1. Поняття покриття

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

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

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

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

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

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

6.3.2. Рівні покриття

6.3.3. По рядках програмного коду (Statement Coverage)

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

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

Наприклад, для повного покриття всіх рядків наступної ділянки програмного коду мовою C достатньо одного тестового прикладу:

Навіть якщо до складу тестів не входитиме тестовий приклад, що перевіряє роботу фрагмента при значенні condition = false, код буде покритий. Однак, у разі condition = false виконання фрагмента викликає помилку.

Аналогічні проблеми виникають при перевірці циклів do … while - при даному рівні покриття достатньо виконання циклу лише один раз, при цьому метод абсолютно нечутливий до логічних операторів та &&

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

Якщо functionA() містить 99 операторів, а functionB() - один оператор, то єдиного тестового прикладу, що встановлює condition в true , буде достатньо досягнення необхідного рівня покриття. При цьому аналогічний тестовий приклад, що встановлює значення condition false, дасть занадто низький рівень покриття.

6.3.3.1. За гілками умовних операторів (Decision Coverage)

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

Також даний метод називають: branch coverage, all-edges coverage, basis path coverage, DC, C2, decision-decision-path.

На відміну від попереднього рівня покриття, цей метод враховує покриття умовних операторів з порожніми гілками. Так, для покриття по гілках ділянки програмного коду

необхідні два тестові приклади:

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

повне покриття по гілках може бути досягнуто за допомогою двох тестових прикладів:

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

6.3.3.2. За компонентами логічних умов

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

6.3.3.3. Покриття за умовами (Condition Coverage)

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

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

При цьому значення логічної умови прийматиме значення тільки true, таким чином, при повному покритті за умовами не буде досягатися покриття по гілках.

6.3.3.4. Покриття за гілками/умовами (Condition/Decision Coverage)

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

Для покриття розглянутого вище фрагмента з умовою condition1 condition2 потрібно 2 тестових приклади:

Однак ці два тестових приклади не дозволять протестувати правильність логічної функції - замість OR в програмному коді могла бути помилково записана операція AND.

6.3.3.5. Покриття за всіма умовами (Multiple Condition Coverage)

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

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

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

знадобиться різна кількість тестових прикладів. Для першого випадку для повного покриття потрібно 6 тестів, для другого – 11.