На этом шаге мы перечислим типы тестов.
Основным тестом мы будем называть тест, проверяющий основные функциональные возможности программы. Однако существует опасность, что после успешного окончания основного тестирования "на радостях" обычно забывают о необходимости дальнейшего, более тщательного контроля программы и отдельных ее участков, да и настроиться на такой контроль становится уже психологически трудно. Поэтому помимо основного теста необходимо применить следуюшие типы тестов.
Вырожденный тест. Этот тест затрагивает работу отлаживаемой программы в самой минимальной степени. Обычно тест служит для проверки правильности выполнения самых внешних функций программы, например обращения к ней и выхода из нее.
Тест граничных значений, или "стрессовый тест" (High-Low Bias Checking, Twin Check). Тест проверяет работу программы для граничных значений параметров, определяющих вычислительный процесс. Часто для граничных значений параметра работа программы носит особый характер, который тем самым требует и особого контроля.
Если в качестве примера рассмотреть тестирование подпрограммы сортировки, то нужно исследовать следующие ситуации:
Л.Питер приводит следующий поучительный пример. Компьютер одной компании по страхованию автомобилей выслал проживающему в Сент-Луисе клиенту счет на сумму 0.00 долларов. Когда же компьютер направил ему "последнее уведомление" с угрозой расторгнуть договор, этот челевек обратился за помощью к своему финансовому агенту. Тот пришел к выводу, что лучший способ уладить дело - отправить компьютеру чек на 0.00 долларов. Это было сделано, и в ответ пришло подтверждение с благодарностью и заверением, что договор остается в силе!
Аварийный тест. Тест проверяет реакцию программы на возникновение разного рода аварийных ситуаций в программе, в частности вызванных неправильными исходными данными, то есть проверяется диагностика, выдаваемая программой, а также окончание ее работы или, может быть, попытка исправления неверных исходных данных (разработчики реальных программ знают, что пользователи подобны шаловливому ребенку, играющему в отсутствие старших с телевизором или магнитофоном).
Поэтому в реальных программах, спроектированных с достаточной надежностью, совокупности приказов, которые должны работать только в особых аварийных ситуациях, занимают порой более 90% общего объема программы. Эти совокупности приказов называют иногда блоками защиты от дурака (Fool Proof). Такие системы, обладая достаточной надежностью, устойчиво функционируют даже при самых неподходящих действиях работающих с ними людей.
В журнале "Компьютерный мир" рассказывалось об одной довольно дорого обошедшейся ошибке. При вводе данных палец оператора случайно задел не ту клавишу, и автомобиль "Форд", принадлежащий одному из граждан, стал стоить не 950, а 7000950 долларов! А если обладаешь таким дорогим имуществом, нужно платить большой налог. Налог составил 290000 долларов. Когда ошибка обнаружилась, эта сумма была уже включена в бюджет города. Владелец автомобиля получил счет на 290 тыс.долларов, но платить не стал. Причиной ошибки следует считать, конечно, не неверно нажатую клавишу, а плохую программу, автор которой не позаботился о достаточно мощных процедурах контроля входных данных.
Процветающие фирмы, занятые разработкой программного обеспечения, специально нанимают профессионально неподготовленных людей, чтобы они поработали с вновь созданными программами. В их задачу входит за короткое время сделать столько неправильных обращений к программе, сколько пользователь не сделает и за долгий период.
Например, когда программа запрашивает цену товара, оператор набирает на клавиатуре слово "Почему?" вместо числа и т.д.
Одним из свойств хорошей программы является, как говорят специалисты, ее дружественность. Это означает, что в случае ошибки пользователя программа выдаст на экран сообщение, направленное на оказание помощи в выполнении поставленной задачи. Это может быть подсказка, наводящий вопрос, разъяснение противоречивости или иной ошибки в требованиях пользователя.
В лучших образцах таких программ вместо сообщения "треугольника с такими сторонами не бывает" на экране выдаются тексты вида: "Вероятно, Вы ошиблись. На плоскости невозможно построить треугольник со сторонами, имеющими длины 1, 1, 100. Попытайтесь изменить значения длин сторон."
Существуют программы, которые не только обнаруживают, но и исправляют ошибки. Например, при проектировании какого-то прибора инженер за дисплеем подбирает параметры его деталей и вводит приказ запомнить величину сопротивления 150 кОм. Тогда компьютер может ответить: "Вероятно, Вы ошиблись. К сожалению, известны только данные о выпускаемых сопротивлениях с номиналами 160 и 180 кОм. Попытайтесь изменить значение номинала сопротивления. Если Вам подходит значение 180 кОм, нажмите клавишу "ВВОД". Программа лишь предложила один из возможных вариантов взамен явно неосуществимого. Окончательное решение осталось за пользователем.
Однако дружественность программ должна иметь четкие границы, иначе автоматическое исправление ошибок превратится в медвежью услугу пользователю. Одно из свойств хороших программ состоит в том, что пользователь не должен при работе с ними удивляться, они не должны делать ничего неожиданного, так как эти неожиданности редко бывают приятными и полезными.
В связи с этим интересны рекомендации по проектированию программ ведения диалога[1], где автор вообще выступает против какого-либо очеловечивания вычислительных систем. При создании вычислительных систем, которые будут вести себя как инструменты, следует избегать построения диалога по следующему принципу: "Привет, я Бетси 307, назови свое имя".
Старайтесь не давать человеческих имен или признаков программам и системам. Не приписывайте вычислительным системам свободы воли или поведения, напоминающего живое существо.
Если что-то происходит неправильно, не обвиняйте в этом ЭВМ или программу. Помните, что инструменты не делают ошибок, они или отказывают или ломаются.
На следующем шаге мы рассмотрим методы локализации ошибок.