Тестування програмних продуктів
I. ВСТУП.
ЗАГАЛЬНІ ПОНЯТТЯ.
b>
Багато організацій, що займаються створенням програмного забезпечення, до 50% коштів, виділених на розробку програм, витрачають на тестування, що становить мільярди доларів по всьому світу в цілому. І все ж, незважаючи на величезні капіталовкладення, знань про суть тестування явно не вистачає і більшість програмних продуктів неприйнятно ненадійно навіть після "грунтовного тестування".
Про стан справ найкраще свідчить той факт, що більшість людей, що працюють в області обробки даних, навіть не може правильно визначити слово "тестування", і це насправді головна причина невдач.
"Тестування - процес, що підтверджує правильність програми і демонструє, що помилок в програмі немає." Основний недолік такого визначення полягає в тому, що воно зовсім неправильно; фактично це майже визначення антоніма слова "тестування". Читач з деяким досвідом програмування вже, мабуть, розуміє, що неможливо продемонструвати відсутність помилок в програмі. Тому визначення описує нездійсненне завдання, а так як тестування найчастіше все ж виконується з успіхом, принаймні з деяким успіхом, то таке визначення логічно некоректно. Правильне визначення тестування таке: Тестування - процес виконання програми з наміром знайти помилки.
b>
Неможливо гарантувати відсутність помилок в нетривіальною програмі; в кращому випадку можна спробувати показати наявність помилок. Якщо програма правильно поводиться для солідного набору тестів, немає підставі стверджувати, що в ній немає помилок; з усією певністю можна лише стверджувати, що не відомо, коли ця програма не працює. Звичайно, якщо є причини вважати даний набір тестів здатним з великою ймовірністю виявити всі можливі помилки, то можна говорити про деяке рівні впевненості в правильності програми, що встановлюється цими тестами.
Психологічні експерименти показують, що більшість людей, поставивши собі за мету (наприклад, показати, що помилок немає), орієнтується у своїй діяльності на досягнення цієї мети. Тестовік підсвідомо не дозволить собі діяти проти мети, тобто підготувати тест, який виявив би одну з залишилися в програмі помилок. Оскільки ми всі визнаємо, що досконалість у проектуванні та кодування будь-якої програми недосяжно і тому кожна програма містить деяку кількість помилок, найбільш плідним застосуванням тестування буде знайти деякі з них. Якщо ми хочемо добитися цього і уникнути психологічного бар'єру, що заважає нам діяти проти поставленої мети, наша мета повинна полягати в тому, щоб знайти як можна більше помилок. Сформулюємо основний висновок:
Якщо ваша мета - показати відсутність помилок, ви. їх знайдете не дуже багато. Якщо ж ваша мета - показати наявність помилок, ви знайдете значну їх частину.
Надійність неможливо внести в програму в результаті тестування, вона визначається правильністю етапів проектування. Найкраще рішення проблеми надійності - з самого початку не допускати помилок у програмі. Однак імовірність того, що вдасться бездоганно спроектувати велику програму, нескінченно мала. Роль тестування полягає саме в тому, щоб визначити місцезнаходження нечисленних помилок, які залишилися в добре спроектованої програмі. Спроби за допомогою тестування досягти надійності погано спроектованої програми абсолютно безплідні.
Тестування виявляється досить незвичайним процесом (ось чому воно і вважається важким), так як цей процес руйнівний. Адже мета перевіряючого (тестовіка) - змусити програму збитися. Він задоволений, якщо це йому вдається, коли ж програма на його тесті не збивається, він не задоволений.
Ще одна причина, з якої важко говорити про тестування - це той факт, що про нього відомо дуже небагато. Якщо сьогодні ми маємо в своєму розпорядженні 5% тих знанні про проектування та власне програмуванні (кодуванні), які будуть у нас до 2000 р., то про тестування нам відомо менше 1%.
b>
ОСНОВНІ ВИЗНАЧЕННЯ.
b>
Хоча у тестуванні можна виділити кілька різних процесів, такі терміни, як тестування, налагодження, доказ, контроль та випробування, часто використовуються як синоніми і, на жаль, для різних людей мають різне значення. Хоча стандартних, загальноприйнятих визначень цих термінів немає, спроба сформулювати їх була зроблена на симпозіумі з тестування програм. Нашу класифікацію різних форм тестування ми почнемо з того, що дамо ці визначення, злегка їх дописавши та розширивши їх список.
Тестування (testing) b>, як ми вже з'ясували,-процес виконання програми (або частини програми) з наміром (або метою) знайти помилки.
Доказ (proof) b> - спроба знайти помилки в програмі безвідносно до зовнішнього для програми середовищі. Більшість методів доказу передбачає формулювання тверджень про поведінку програми і потім висновок і доведення математичних теорем про правильність програми. Докази можуть розглядатися як форма тестування, хоча вони й не передбачають прямого виконання програми. Багато дослідників вважають доказ альтернативою тестування - погляд багато в чому помилковий; більш докладно це обговорюється в гол. 17.
Контроль (verification) b> - спроба знайти помилки, виконуючи програму в тестовій, або моделюється, середовищі.
Випробування (validation) b> - спроба знайти помилки, виконуючи програму в заданій реальному середовищі.
Атестація (certification) b> - авторитетне підтвердження правильності програми, аналогічне атестації електротехнічного обладнання Underwriters Laboratories. Під час тестування з метою атестації виконується порівняння з деяким наперед визначеним стандартом.
Налагодження (debugging) b> не є різновидом тестування. Хоча слова "налагодження" і "тестування" часто використовуються як синоніми, під ними маються на увазі різні види діяльності. Тестування - діяльність, спрямована на виявлення помилок; налагодження спрямована на встановлення точної природи відомої помилки, а потім - на виправлення цієї помилки. Ці два види діяльності пов'язані - результати тестування є вихідними даними для налагодження.
Тестування модуля, або автономне тестування (module testing, unit testing) b> - контроль окремого програмного модуля, зазвичай в ізольованому середовищі (тобто ізольовано від усіх інших модулів). Тестування модуля іноді включає також математичне доказ.
Тестування сполученні (integration testing) b> - контроль сполученні між частинами системи (модулями, компонентами, підсистемами).
Тестування зовнішніх функцій (external function testing) b> - контроль зовнішнього поводження системи, визначеного зовнішніми специфікаціями.
Комплексне тестування (system testing) b> - контроль та/або випробування системи по відношенню до початкових цілей. Комплексне тестування є процесом контролю, якщо воно виконується в моделюється середовищі, і процесом випробування, якщо виконується в середовищі реальної, життєвої.
Тестування прийнятності (acceptance testing) b> - перевірка відповідності вимогам програми користувача.
Тестування налаштування (installation testing) b> - перевірка відповідності кожного конкретного варіанту установки системи з метою виявити будь-які помилки, що виникли в процесі налаштування системи.
Відносини між цими типами тестів і проектною документацією, на якій грунтується тест, показані на рис.3,
Рис. 2. Спектр підходів до проектування тестів,
Рис. 3. Процеси тестування та їх зв'язок з процесами проектування.
II. Основна частина.
ФІЛОСОФІЯ ТЕСТУВАННЯ
b>
Тестування програмного забезпечення охоплює цілий ряд видів діяльності, дуже аналогічний послідовності процесів розробки програмного забезпечення. Сюди входять постановка завдання для тесту, проектування, написання тестів, тестування тестів і, нарешті, виконання тестів і вивчення результатів тестування. Вирішальну роль відіграє проектування тесту. Можливий цілий спектр підходів до вироблення філософії, або стратегії проектування тестів, зображений на рис.2. Щоб орієнтуватися у стратегіях проектування тестів, варто розглянути два крайніх підходу, що знаходяться на кордонах спектру. Слід також зазначити, що багато хто з тих, хто працює в цій області, часто впадають в одну чи іншу крайність.
Прихильник (або прихильниця) підходу, що відповідає лівій межі спектру, проектує свої тести, досліджуючи зовнішні специфікації або специфікації сполучення програми або модулі, які він тестує. Програму він розглядає як чорний ящик. Позиція така: "Меня не цікавить, як виглядає ця програма і чи виконав я всі команди або всі шляхи. Я буду задоволений, якщо програма буде вести себе так, як зазначено в специфікаціях ". Його ідеал - перевірити всі можливі комбінації і значення на вході.
Прихильник підходу, що відповідає другому кінця спектру, проектує свої тести, вивчаючи логіку програми. Він починає з того, що прагне підготувати достатню кількість тестів для того, щоб кожна команда була виконана принаймні один раз. Якщо він трохи більш досвідчений, то проектує тести так, щоб кожна команда умовного переходу виконувалася в кожному напрямку хоча б раз. Його ідеал - перевірити кожен шлях, кожну гілку алгоритму. При цьому його зовсім (або майже зовсім) не цікавлять специфікації.
Жодна з цих крайнощів не є доброю стратегією. Читач, проте, вже, мабуть, зауважив, що перша з них, а саме та, відповідно до якої програма розглядається як чорний ящик, краще. На жаль, вона страждає тим недоліком, що зовсім нездійсненна. Розглянемо спробу тестування тривіальної програми, що одержує на вході три числа і обчислювати їх середнє арифметичне. Тестування цієї програми для всіх значень вхідних даних неможливо. Навіть для машини з відносно низькою точністю обчислень кількість тестів обчислювалося б мільярдами. Навіть якби ми обчислювальну потужність, достатню для виконання всіх тестів у розумний час, ми витратили б на кілька порядків більше часу для того, щоб ці тести підготувати, а потім перевірити. Такі програми, як системи реального часу, операційні системи і програми керування даними, які зберігають "пам'ять" про попередні вхідних даних, ще гірше. Нам треба було б тестувати програму не тільки для кожного вхідного значення, але й для кожної послідовності, кожній комбінації вхідних даних. Тому вичерпне тестування для всіх вхідних даних будь-якої розумної програми нездійсненно.
Ці міркування приводять до другого фундаментального принципу тестування: тестування - проблема в значній мірі економічна b>. Оскільки вичерпне тестування неможливо, ми повинні обмежитися чимось меншим. Кожен тест повинен давати максимальну віддачу порівняно з нашими витратами. Ця віддача вимірюється ймовірністю тою, що тест виявить не виявлений перш за помилку. Витрати вимірюються часом і вартістю підготовки, виконання та перевірки результатів тесту. Вважаючи, що витрати обмежені бюджетом та графіком, можна стверджувати, що мистецтво тестування, по суті, є мистецтвом відбору тестів з максимальною віддачею. Більш того, кожен тест повинен бути представником деякого класу вхідних значень, так щоб його правильне виконання створювало у нас деяку переконаність в тому, що для певного класу вхідних даних програма буде виконуватися правильно. Це звичайно вимагає деякого знання алгоритму та структури програми, і ми, таким чином, зміщується до правого кінця спектру.
ІНТЕГРАЦІЯ МОДУЛІВ.
b>
Другим за важливістю аспектом тестування (після проектування тестів) є послідовність злиття всіх модулів в систему або програму. Ця сторона питання зазвичай не отримує достатньої уваги і часто розглядається занадто пізно. Вибір цієї послідовності, однак, є одним з найбільш життєво важливих рішення, що приймаються на етапі тестування, оскільки він визначає форму, в якій записуються тести, типи необхідних інструментів тестування, послідовність програмування модулів, а також ретельність і економічність усього етапу тестування. З цієї причини таке рішення має прийматися на рівні проекту в цілому і на досить ранній його стадії.
Є великий вибір можливих підходів, які можуть бути використані для злиття модулів в більші одиниці. Здебільшого вони можуть розглядатися як варіанти шести основних підходів, описаних в наступних шести розділах. Відразу ж за ними йде розділ, де запропоновані підходи порівнюються по їх впливу на надійність програмного забезпечення.
Висхідна ТЕСТУВАННЯ.
b>
При висхідному підході програма збирається і тестується знизу вгору. Тільки модулі самого нижнього рівня ( "термінальні" модулі; модулі, які не викликають інших модулів) тестуються ізольовано, автономно. Після того як тестування цих модулів завершено, виклик їх має бути так само надійний, як виклик вбудованої функції мови або оператор присвоєння. Потім тестуються модулі, безпосередньо викликають вже перевірені. Ці модулі більш високого рівня тестуються не автономної, а разом з уже перевіреними модулями більш низького рівня. Процес повторюється до тих пір, поки не буде досягнута вершина. Тут завершуються і тестування модулів, і тестування сполученні програми.
При висхідному тестуванні для кожного модуля необхідний драйвер: потрібно подавати тести відповідно до сполученням тестового модуля. Одне з можливих рішенні - написати для кожного модуля невелику провідну програму. Тестові дані представляються як "вбудовані" безпосередньо в цю програму змінні та структури даних, і вона часто викликає тестовий модуль, з кожним викликом передаючи йому нові тестові дані. Є і краще рішення: скористатися програмою тестування модулів - це інструмент тестування, що дозволяє описувати тести на спеціальній мові що рятує від необхідності писати драйвери.
Низхідна ТЕСТУВАННЯ.
b>
спадний тестування (зване також низхідній розробкою не є повною протилежністю сходу, але в першому наближенні може розглядатися як таке, При низхідному підході програма збирається і тестується зверху вниз. ізольовано тестується тільки головний модуль. Після того як тестування цього модуля завершено, з ним з'єднуються (наприклад, редактором зв'язків) один за одним модулі, безпосередньо викликаються їм, та тестується отримана комбінація. Процес повторюється до тих пір, поки не будуть зібрані і перевірені всі модулі.
При цьому підході негайно виникає два питання: що робити, коли тестовий модуль викликає модуль більш низького рівня (якого в даний момент ще не існує), і як подаються тестові дані. Відповідь на перше питання полягає в тому, що для імітації функцій відсутніх модулів програмуються модулі-заглушки ", які моделюють функції відсутніх модулів. Фраза "просто напишіть заглушку" часто зустрічається в описі цього підходу, але вона здатна ввести в оману, оскільки завдання написання заглушки "може виявитися важким. Адже заглушка рідко зводиться просто до оператора RETURN, оскільки викликає модуль зазвичай очікує від неї вихідних параметрів. У таких випадках в заглушку вбудовують фіксовані вихідні дані, які вона завжди і повертає. Це іноді виявляється неприйнятним, тому що викликає модуль може розраховувати, що результат виклику залежить від вхідних даних. Тому в деяких випадках заглушка повинна бути досить гострою, наближаючись за складністю до модуля, який вона намагається моделювати.
Цікавий і друге питання: в якій формі готуються тестові дані і як вони передаються програмі? Якби головний модуль містив всі потрібні операції введення/виводу, відповідь була б проста:
Тести пишуться у вигляді звичайних для користувачів зовнішніх даних і передаються програмі через виділені їй пристрої введення. Так, проте, слу?? ается рідко. У добре спроектованої програмі фізичні операції вводу-виводу виконуються на нижніх рівнях структури, оскільки фізичний ввід-висновок - абстракція досить низького рівня. Тому для того, щоб вирішити проблему економічно ефективно, модулі додаються не в строго спадної послідовності (всі модулі одного горизонтального рівня, потім модулі наступного рівня), а таким чином, щоб забезпечити функціонування операцій фізичного введення-виведення як можна швидше. Коли ця мета досягнута, що сходить тестування отримує значну перевагу: всі подальші тести готуються в тій же формі, яка розрахована на користувача.
Залишається ще одне питання: в якій формі пишуться тести до тих пір, поки не буде досягнута ця мета? Відповідь: вони включаються до деяких з заглушок.
Спадний метод має як переваги, так і недоліки в порівнянні з висхідним. Найбільш значне достоїнство - в тому, що цей метод поєднує тестування модуля, тестування сполученні і частково тестування зовнішніх функцій. З цим же пов'язане інше його переваг - це коли модулі вводу-виводу вже підключені, тести можна готувати в зручному вигляді. Спадний підхід вигідний також в тому випадку, коли є сумніви щодо здійсненності програми в цілому або якщо в проекті програми можуть виявитися серйозні дефекти.
Перевагою спадного підходу дуже часто вважають відсутність необхідності в драйверах; замість драйверів вам просто слід написати "заглушки". Як читач зараз вже, мабуть, розуміє, це перевага спірно.
Спадний метод тестування має, на жаль, деякі недоліки. Основним з них є той, що модуль рідко тестується досконально відразу після його підключення. Справа в тому, що грунтовне тестування деяких модулів може зажадати вкрай витончених заглушок. Програміст часто вирішує не витрачати багато часу на їх програмування, а натомість пише прості заглушки і перевіряє лише частину умов у модулі. Він, звичайно, збирається повернутися і закінчити тестування розглянутого модуля пізніше, коли прибере заглушки. Такий план тестування безумовно не найкраще рішення, оскільки про відкладених умовах часто забувають.
Другий тонкий недолік спадного підходу полягає в тому, що він може породити віру в можливість почати програмування і тестування верхнього рівня програми до того, як вся програма буде цілком спроектована. Ця ідея на перший погляд здається економічною, але зазвичай справа йде зовсім навпаки. Більшість досвідчених проектувальників визнає, що проектування програми - процес ітеративний. Рідко перший проект виявляється досконалим. Нормальний стиль проектування структури програми передбачає після закінчення проектування нижніх рівнів повернутися назад і підправити верхній рівень, внісши до нього деякі удосконалення чи виправляючи помилки, або іноді навіть викинути проект і почати все спочатку, тому що розробник раптово побачив кращий підхід. Якщо ж головна частина програми вже запрограмована й відтестовані, то виникає серйозний опір будь-яким поліпшенням її структури. У кінцевому підсумку за рахунок таких поліпшень зазвичай можна заощадити більше, ніж ті кілька днів або тижнів, які розраховує виграти проектувальник, приступаючи до програмування занадто рано.
МОДИФІКОВАНІ Низхідна МЕТОД
b>
Спадний підхід має ще один істотний недолік, що стосується повноти тестування. Припустимо, що є велика програма і десь ближче до нижнього її рівня знаходиться модуль, призначений для обчислення коренів квадратного рівняння. Для заданих вхідних змінних А, В і С він вирішує рівняння .
При проектуванні і програмуванні модуля з такою функцією завжди слід розуміти, що квадратне рівняння може мати як дійсні, так і комплексні корені. Для повної реалізації цієї функції необхідно, щоб результати могли бути дійсними або комплексними числами (або, якщо додаткові витрати на знаходження комплексних коренів не виправдані, модуль повинен принаймні повертати код помилки у випадку, коли вхідні коефіцієнти задають рівняння з комплексними коренями). Припустимо, що конкретний контекст, в якому використовується модуль, виключає комплексні корені (тобто викликають модулі ніколи не задають вхідних параметрів, які призвели б до комплексних коренів). При суворо низхідному методі іноді буває неможливо тестувати модуль для випадку комплексних коренів (або тестувати помилкові умови). Можна спробувати виправдовувати це тим, що, оскільки таке рівняння ніколи не буде дано модулю, нікого не повинно турбувати, чи працює він і в цих випадках. Так, це байдуже зараз, але виявиться важливим у майбутньому, коли хтось спробує використовувати модуль у новій програмі або модифіковані стару програму так, що стануть можливими і комплексні корені.
Ця проблема проявляється в різноманітних формах. Застосовуючи спадний тестування в точній відповідності з попереднім розділом, часто неможливо тестувати певні логічні умови, наприклад помилкові ситуації або захисні перевірки. Спадний метод, крім того, робить складною або взагалі неможливою перевірку виняткових ситуацій в деякому модулі, якщо програма працює з ним лише в обмеженому контексті (це означає, що модуль ніколи не отримає достатньо повний набір вхідних значень). Навіть якщо тестування такої ситуації в принципі можливо, часто буває важко визначити, які саме потрібні тести, якщо вони вводяться в точці програми, віддаленій від місця перевірки відповідної умови.
Метод, який називається модифікованим низхідним підходом, вирішує ці проблеми: потрібно, щоб кожен модуль пройшов автономне тестування перед підключенням до програми. Хоча це дійсно вирішує всі перераховані проблеми, тут потрібні і драйвери, і заглушки для кожного модуля.
МЕТОД Великого стрибка.
b>
Ймовірно, найпоширеніший підхід до інтеграції модулів - метод "великого стрибка". Згідно з цим методом кожен модуль тестується автономно. Після закінчення тестування модулів вони інтегруються в систему все відразу.
Метод великого стрибка в порівнянні з іншими підходами має багато недоліків і мало достоїнств. Заглушки і драйвери необхідні для кожного модуля. Модулі не інтегруються до самого останнього моменту, а це означає, що протягом довгого часу серйозні помилки в сполученнях можуть залишитися невиявленими. Метод великого стрибка значно ускладнює налагодження.
І все-таки великий стрибок не завжди небажаний. Якщо програма мала і добре спроектована, він може виявитися прийнятним. Однак для великих програм метод великого стрибка звичайно згубний.
МЕТОД Сандвіч
b>
Тестування методом сандвіча представляє собою компроміс між висхідним і спадним підходами. Тут робиться спроба скористатися перевагами обох методів, уникнувши їх недоліків.
При використанні цього методу одночасно починають висхідний і спадний тестування, збираючи програму як знизу, так і зверху і зустрічаючись в кінці кінців десь в середині. Точка зустрічі залежить від конкретної тестованої програми і повинна бути заздалегідь визначена при вивченні її структури. Наприклад, якщо розробник може представити свою систему у вигляді рівня прикладних модулів, потім рівня модулів обробки запитів, потім рівня примітивних функцій, то він може вирішувати, чи застосовувати спадний метод на рівні прикладних модулів (програмуючи заглушки замість модулів обробки запитів), а на інших рівнях застосувати висхідний метод.
Застосування методу сандвіча - це розумний підхід до інтеграції великих програм, таких, як операційна система або пакет прикладних програм.
Метод сандвіча зберігає таке гідність спадного і висхідного підходів, як початок інтеграції системи на ранньому етапі. Оскільки вершина програми вступає в дію рано, ми, як у спадному методі, вже на ранньому етапі отримуємо працює каркас програми. Оскільки нижні рівні програми створюються висхідним методом, знімаються ті проблеми спадного методу, які були пов'язані з неможливістю тестувати деякі умови в глибині програми.
модифікований метод сандвіч.
b>
Під час тестування методом сандвіча виникає та ж проблема, що й при низхідному підході, хоча тут вона стоїть не так гостро. Проблема ця в тому, що неможливо досконально тестувати окремі модулі. Висхідний етап тестування за методом сандвіча вирішує цю проблему для модулів нижніх рівнів, але вона може як і раніше залишатися відкритою для нижньої половини верхньої частини програми. В модифікованому методі сандвіча нижні рівні також тестуються суворо знизу вгору. А модулі верхніх рівнів спочатку тестуються ізольовано, а потім збираються низхідним методом. Таким чином, модифікований метод сандвіча також представляє собою компроміс між висхідним і спадним підходами.
ПОРІВНЯЛЬНА ХАРАКТЕРИСТИКА МЕТОДІВ ТЕСТУВАННЯ.
b>
З точки зору надійності програмного забезпечення ці стратегії можна оцінити за вісьмома критеріями, як показано на рис. 10.7. Перший критерій - час до моменту складання модулів, оскільки це важливо для виявлення помилок в сполученнях і припущеннях модулів про властивості один одного. Другий критерій - час до моменту створення перших працюючих "скелетних" версій програми, оскільки тут можуть проявитися головні дефекти проектування. Третій і четвертий критерії стосуються питання про те, чи необхідні заглушки, драйвери та інші інструменти тестування. П'ятий критерій-мера паралелізму, який можливий на початку або на ранніх стадіях тестування. Це цікаве питання, оскільки необхідність у ресурсах (тобто програмістів) зазвичай досягає піку на етапах проектування і програмування модулів.
Висхідний
Спадний
Модифікований спадний
Метод великого стрибка
Метод сандвіча
Модифікований метод сандвіча
Збірка
Рано
Рано
Рано
Пізно
Рано
Рано
Час до появи працюючого варіанту програми
Пізно
Рано
Рано
Пізно
Рано
Рано
Чи потрібні драйвери (нові програми або готові інструменти)?
Так
Ні
Так
Так
Частково
Так
Чи потрібні заглушки
Ні
Так
Так
Так
Частково
Частково
Паралелізм на початку роботи
Середній
Слабкий
Середній
Високий
Середній
Високий
Можливість тестувати окремі колії
Легко
Важко
Легко
Важко
Може бути
Легко
Можливість планувати і контролювати послідовність
Легко
Важко
Важко
Легко
Важко
Важко
Рис. 10.7. Кількісна оцінка підхід до збірки.
Тому важливо, щоб можливість паралельного тестування з'явилася ближче до початку, а не кінця циклу тестування.
Шостий критерій пов'язаний з відповіддю на який обговорювався раніше питання: чи можливо перевірити будь-який конкретний шлях і будь-яка умова у програмі? Сьомий критерій характеризує складність планування, нагляду і управління в процесі тестування. Це пов'язано з усвідомленням того факту, що тестування, яким важко керувати, часто веде до недогляд і упущень. Час від часу лунають заперечення проти спадного підходу у зв'язку з тим, що тестування нижніх модулів вимагає багаторазових зайвих прогонів головних модулів. Однак цей критерій відзначений як несуттєвий. Хоча зайві прогони дійсно бувають необхідні, можливо також, що в багатьох випадках, які здаються зайвими, в дійсності відтворюються дещо різні умови. Ці прогони можуть розкрити нові помилки, перетворюючи таким чином недолік в гідність. Оскільки цей ефект недостатньо усвідомлена, ми ним нехтуємо.
Тепер оцінимо наші шість підходів за допомогою перерахованих восьми критеріїв. Як уже говорилося, така оцінка залежить від конкретного проекту. В якості вихідного наближення для виконання ваших власних оцінок наведено варіант дуже грубої оцінки. Перш за все слід зважити відносний вплив кожного з восьми критеріїв на надійність програмного забезпечення. Рання збірка і раннє отримання працюючого каркаса програми, а також можливість тестувати будь-які конкретні умови представляються найбільш важливими, тому їм дається коефіцієнт 3. Складність підготовки заглушок, а також складність планування та управління послідовністю тестів також важливі, тому вони отримують вага 2. Третій критерій, необхідність драйверів, вага 1 зважаючи доступності загальних інструментів тестування. Критерій, пов'язаний з паралелізмом роботи, також має вагу 1, тому що, хоча він, можливо, і важливий з інших причин, на надійність сильно не впливає. Восьмий критерій отримує коефіцієнт нуль.
На рис. 10.8 показані результати цієї оцінки. У кожній графі таблиці вага береться зі знаком плюс або мінус або не враховується, в залежності від того, сприятливо, несприятливо або байдуже проявляється відповідний фактор при розглянутому підході. Модифікований метод сандвіча і висхідний метод виявляються найкращими підходами, а метод великого стрибка-найгіршим. Якщо спосіб оцінки виявляється близьким до вашої конкретної ситуації, слід рекомендувати модифікований метод сандвіча для тестування великих систем або програм і висхідний підхід для тестування програм малих і середніх.
Вага
Висхідний
Спадний
Модифікований спадний
Метод великого стрибка
Метод сандвіча
Модифікований метод сандвіча
3
Збірка
Рано +
Рано +
Рано +
Пізно --
Рано +
Рано +
3
Час до появи працюючого варіанту програми
Пізно --
Рано +
Рано +
Пізно --
Рано +
Рано +
1
Чи потрібні драйвера (нові програми u/uлі готові інструменти)?
Так --
Ні +
Д а --
Так --
Частково
Так --
2
Потрібні заглушки?
Ні +
Так --
Так --
Так --
Частково
Частково
1
Паралелізм на початку роботи
Середній
Слабкий -
Середній
Високий +
Середній
Високий +
3
Можливість тестувати окремі колії
Легко +
Важко --
Лягло +
Легко +
Може бути
Легко +
2
Можливість планувати і контролювати послідовність
Легко +
Важко --
Важко --
Легко +
Важко --
Важко --
0
Неефективність
Всього
6
-1
4
-3
4
7
Рис. 10.8. Зважена оцінка підходів до збірки.
III. ВИПРОБУВАННЯ ПРОГРАМНИХ ПРОДУКТІВ (АНАЛІЗ).
b>
МЕТА І ОСОБЛИВОСТІ Випробування.
Випробування є найважливішим елементом управління якістю продукції. Відповідно до ГОСТ 16504-81 під випробуванням промислової продукції розуміють експериментальне визначення кількісних та/або якісних характеристик об'єкта випробування як результату впливу на нього; при його функціонування; при моделюванні об'єкта та/або впливу. Під випробуванням програмної продукції b> слід розуміти експериментальне визначення кількісних та/або якісних характеристик властивостей продукції при її функціонування в реальному середовищі та/або моделюванні середовища функціонування.
Метою випробування b> є експериментальне визначення фактичних (досягнутих) характеристик властивостей випробовується ПІ. Ці характеристики можуть бути як кількісними, так і якісними. Важливо, щоб на їх основі можна було зробити висновок про придатність даного ПІ до використання за своїм призначенням. Якщо висновок негативний, то зразок ПІ повертається на доопрацювання. Таким чином перекривається доступ недоброякісної продукції до користувача, Безпосередньо у ході випробувань якість ПІ може й не змінитися, тому що локалізація помилок не є метою випробування. Разом з тим деякі дефекти в програмах і документації можуть усуватися по ходу випробування.
Випробування є завершальним етапом розробки. Йому передує етап статичної та динамічної налагодження програм. Основним методом динамічної налагодження є тестування. У вузькому сенсі мета тестування полягає у виявленні помилок, мета ж налагодження-не тільки у виявленні, але і в усуненні помилок. Проте обмежитися тільки налагодженням програми, якщо євпевненість в тому, що всі помилки в ній усунуті, не можна. Цілі у налагодження й випробування різні. Повністю налагоджена програма може не володіти певними споживчими властивостями і тим самим бути непридатною до використання за своїм призначенням. Не може служити альтернативою випробування та перевірка працездатності програми на контрольному прикладі, так як програма, працездатна в умовах контрольного прикладу, може виявитися непрацездатною в інших умовах застосування. Спроби охопити контрольним прикладом всі передбачувані умови функціонування зводяться в кінцевому рахунку до тих же випробувань.
Відповідно до ДСТ 19,004-80 під випробуванням програм b> розуміють встановлення відповідності програми заданим вимогам і програмних документів. Це визначення базується на припущенні, що в технічному завданні на розробку програми визначені всі вимоги (характеристики), забезпечення яких гарантує придатність програми до використання за своїм призначенням. Але така вимога рідко дотримуються на практиці. У деяких випадках, особливо в автоматизованих системах, ТЗ на ПС або взагалі не пишуть, або в яких перераховують лише функції, які покладаються на ПС, без зазначення вимог до інших споживчими властивостями. При відсутності ТЗ на розробку ПС або повного і обгрунтованого переліку вимог до характеристик розробляється ПС завдання випробування ПС стає невизначеною і неконструктивною. Що значить встановити відповідність програми заданим вимогам, якщо ці вимоги формально не задані? Яка користь від встановлення такої відповідності, якщо ці вимоги свідомо "усечено" і не відображають основних споживчих властивостей програми? Користувачеві буде не легше, якщо програма функціонує погано, але це в явному вигляді не суперечить вимогам ТЗ.
За наявності в ТЗ необхідних характеристик основних споживчих властивостей ПІ наведені визначення терміну "випробування" за метою випробування практично збігаються. Однак і в цьому випадку перший визначення є більш конструктивним, тому що воно формулює не тільки мету, але й основний метод проведення випробування - перевірка ПІ, яке функціонує в реальній або моделюється, але близької до реальної середовищі,
У закордонній літературі, у тому числі в стандартах на програмне забезпечення, поняття "випробування" часто ототожнюють з поняттям "тестування". Наприклад, у Std IEEE 829-1983 "Документація тестів програмного забезпечення" (США) дано наступне визначення тестування: "... процес активного аналізу ПЗ на предмет виявлення розбіжності між реальними і необхідними нормами ПЗ (тобто наявності помилок в програмах) та з метою оцінки характеристик елементів ПЗ ". Дане визначення об'єднує два наведених визначення терміну "випробування" з тією лише різницею, що при прийнятій (див. визначення) концепції пошук і локалізація помилок на є явно вираженими цілями випробування. З урахуванням висловлених міркувань термін "тестування", що використовується в зарубіжній літературі, будемо інтерпретувати як іс