Але навіть якщо передбачити, що вдалося досягнути повного структурного тестування деякої програми, в ній проте можуть міститися помилки, так як
1) програма може не відповідати своїй зовнішній специфікації, що зокрема, може привести до того, що в її керуючому графові виявляться пропущеними деякі необхідні шляхи;
2) не будуть виявлені помилки, поява яких залежить від даних (, що обробляються тобто на одних початкових даних програма працює правильно, а на інших - з помилкою).
Таким чином, ні структурне, ні функціональне тестування не може бути вичерпним. Розглянемо детальніше основні етапи тестування програмних комплексів.
У тестування багатомодульных програмних комплексів можна виділити чотири етапи:
1) тестування окремих модулів;
2) спільне тестування модулів;
3) тестування функцій програмного комплексу (тобто пошук відмінностей між розробленою програмою і її зовнішньою специфікацією );
4) тестування всього комплексу загалом (тобто пошук невідповідності створеного програмного продукту сформульованим раніше цілям проектування, відображеним звичайно в технічному завданні).
На перших двох етапах використовуються передусім методи структурного тестування, так як
на подальших етапах тестування ці методи використати складніше через великі розміри програмного забезпечення, що перевіряється;
подальші етапи тестування орієнтовані на виявлення помилок різного типу, які не обов'язково пов'язані з логікою програми.
При тестуванні як окремих модулів, так і їх комплексів повинні бути вирішені дві задачі:
1) побудова ефективної безлічі тестів;
2) вибір способу комбінування (збирання) модулів при створенні трестируємого варіанту програми.
СТРУКТУРНЕ ТЕСТУВАННЯ
Оскільки вичерпне структурне тестування неможливе, необхідно вибрати такі критерії його повноти, які допускали б їх просту перевірку і полегшували б цілеспрямований підбір тестів.
Найбільш слабою з критеріїв повноти структурного тестування є вимога хоч би однократного виконання (покриття) кожного оператора програми.
Більш сильним критерієм є так званий критерій С1: кожна гілка алгоритму (кожний перехід) повинна бути пройдена (виконана) хоч би один раз. Для більшості мов програмування покриття переходів забезпечує і покриття операторів, але, наприклад, для програм на мові ПЛ/1 додатково до покриття всіх гілок потрібно всіх додаткових точок входу в процедуру (що задаються операторами ENTRY) і всіх ON - одиниць.
Використання критерію покриття умов може викликати підбір тестів, що забезпечують перехід в програмі, який пропускається при використанні критерію С1 (наприклад, в програмі на мові Паськаль, що використовує конструкцію циклу WHILE х AND у DO ., застосування критерію покриття умов вимагає перевірки обох варіантів виходу з циклу: NOT х і NOT у ).
З іншого боку покриття умов може не забезпечувати покриття всіх переходів. Наприклад, конструкція IF А AND В THEN . вимагає по критерію покриття умов двох тестів (наприклад, А=true, В=false і А=false, В=true ), при яких може не виконуватися оператор, розташований в then - гілки оператора if.
Практично єдиним засобом, що надається сучасними системами програмування, є можливість визначення частоти виконання різних операторів програми (її профілізації). Але за допомогою цього інструмента підтримки тестування можна перевірити виконання тільки найслабішого з критеріїв повноти - покриття всіх операторів.
Правда, за допомогою цього ж інструмента можна перевірити і виконання критерію С1. Але для цього заздалегідь текст програми повинен бути перетворений таким чином, щоб всі конструкції умовного вибору (IF і CASE
10
або SWITCH ) містили гілки ELSE або DEFAULT, хоч би і пусті. У цьому випадку всі гілки алгоритму, ті, що не виконувалися на даному тесті будуть “видимі" з таблиці частоти виконання операторів перетвореної програми.
Актуальною залишається задача створення інструментальних засобів, що дозволяють:
1) нагромаджувати інформації про покриті і непокриті гілки для всіх використаних тестів;
2) виділяти розробнику ще не покриті при тестуванні дільниці програми, полегшуючи вибір наступних тестів;
3) підтримувати більш могутні критерії повноти структурного тестування.
СПІЛЬНЕ ТЕСТУВАННЯ МОДУЛІВ.
Відомі два підходи до спільного тестування модулів: покрокове і монолітне тестування.
При монолітному тестуванні спочатку по окремості тестуються всі модулі програмного комплексу, а потім всі вони об'єднуються в робочу програму для комплексного тестування.
При покроковому тестуванні кожний модуль для свого тестування підключається до набору вже перевірених модулів.
У першому випадку для автономного тестування кожного модуля потрібний модуль - драйвер ( тобто допоміжний модуль, що імітує виклик модуля, що тестується ) і один або декілька модулів - заглушок ( тобто допоміжних модулів, що імітують роботу модулів, що викликаються з того, що тестується). При покроковому тестуванні модулі перевіряються не ізольовано один від одного, тому потрібні або тільки драйвери, або тільки заглушки.
А
B C D
E F
мал. 1
При порівнянні покрокового і монолітного тестування можна відмітити наступні переваги першого підходу:
1) менша трудомісткість (для прикладу на мал. 1 при монолітному тестуванні потрібно 5 драйверів і 5 заглушок; при покроковому тестуванні потрібні або тільки 5 драйверів - якщо модулі підключаються “знизу вгору ", - або тільки 5 заглушок - якщо модулі підключаються “зверху вниз");
2) більш раннє виявлення помилок в інтерфейсах між модулями (їх збирання починається раніше, ніж при монолітному тестуванні );
3) легше відладка, тобто локалізація помилок (вони в основному пов'язані з останнім з підключених модулів );