Введение в технологию программирования

Тестирование, обеспечение качества


Для начала вспомним три аксиомы одного из самых первых советских программистов с несколько необычной фамилией Шура-Бура.

Аксиома 1. В каждой программе есть ошибка.

Аксиома 2. Если в программе нет ошибок, значит, в исходном алгоритме есть ошибка.

Аксиома 3. Если ни в программе, ни в алгоритме ошибок нет, то такая программа никому не нужна.

При всей шутливости этих аксиом в них отражена суровая правда жизни.

Исходные идеи тестирования абсолютно понятны [9].

Вы написали программу, хотите убедиться в правильности ее работы, поэтому пропускаете один или несколько тестов и смотрите, что получилось. Понятно, что тесты должны быть простыми настолько, чтобы можно было предсказать правильный ответ, иначе как вы определите, правильно ли программа сработала?

А что делать со сложными тестами и, вообще, сколько тестов нужно пропустить? Ответ очевиден – бесконечно много, поэтому с помощью теста можно доказать наличие ошибок (если тест был достаточно "зубастым"), но нельзя доказать их отсутствие.

Бесконечность тестов определяется наличием циклов, рекурсии, разнообразием значений данных. Ситуация обычна для нашей специальности. Теоретическая невозможность не снимает с нас ответственности за поиск практических способов проверки – пусть не полных, но дающих какую-то степень уверенности. Итак, что же можно сделать?

Еще 30 лет назад был популярен критерий полноты тестирования, при котором набор тестов гарантировал, что по каждому ребру графа управления программы исполнение программы хотя бы один раз пройдет. Такой набор тестов можно создать, часто даже автоматически.

Чтобы проверить цикл, нужно создать тест, гарантирующий прохождение цикла 0, 1 и 2 раза. 0 – вдруг условие входа в цикл сразу было ложным, 1 – нормальное прохождение, 2 – не столь очевидно. Возможно, в конце цикла есть присваивание переменной, которая в начале цикла только читается. Понятно, что однократный проход по циклу не даст возможности проверки важного и весьма вероятного варианта.

Изложенные критерии носят только эвристический характер, но весьма полезны.
Таким образом, мы видим, что программирование и тестирование – совершенно разные типы деятельности, требующие разных исполнителей.

Программирование – это конструктивный созидательный процесс, который требует высокой квалификации и определенного оптимизма (cм. аксиомы Шуры-Буры).

Тестирование – деструктивный процесс, который требует высокой дотошности, подозрительности, пессимистичности, но, вообще говоря, не требует высокой квалификации. Пусть не обижаются на меня настоящие системные программисты, которые создают инструментальные средства автоматизации тестирования, я говорю об обычных тестерах. В каждом коллективе есть люди с неуживчивым характером, любящие покритиковать коллег по работе. Цены им не будет в группе тестирования.

Еще раз повторим, что тестирование нужно вовсе не для того, чтобы показать, что программа работает правильно – это невозможно. Тестирование – это процесс исполнения программы с целью нахождения ошибок. Хороший тест – это тест, на котором с большой вероятностью ошибка найдется.

Теперь приведем несколько организационных и технологических соображений относительно тестирования.

Тестирование (не считая начальных отладочных тестов) не должно проводиться самими авторами программы. Наблюдается определенная "замыленность" взгляда автора на программу, поэтому он и тесты будет готовить на те варианты, которые предусмотрел в программе.

Должна быть конкуренция между программистами и тестировщиками, нужен дух соревнования: "Я все равно тебя поймаю" против "Врешь, не поймаешь".

Необходимо уметь оценивать вероятность и примерное количество оставшихся ошибок. Например, известен метод оценки количества рыб в пруду. Ловят, скажем, 100 рыбок, помечают их и выпускают обратно в пруд. Затем снова ловят 100 рыбок. Если почти все они мечены, значит, в пруду примерно 100 рыбок и есть, если же меченых попалось мало, то рыб, скорее всего, больше, причем в той же пропорции, какова доля непомеченных из 100 вновь пойманных. Во многих фирмах применяют тот же прием: специальные люди вставляют некоторое количество разнообразных ошибок в программы и возвращают их на доработку авторам с требованием обнаружить ровно столько же ошибок.По тому, какая часть найденных ошибок относится к специально вставленным, а какая – к вновь найденным ошибкам, можно судить о числе оставшихся ошибок. Еще проще – поручить тестирование одной и той же программы двум группам тестировщиков и оценить процент ошибок, найденных обеими группами.

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

Всегда должен быть четко оговорен конечный результат тестирования. В идеале еще до начала работ или на одной из ранних стадий (работа 2-10 из нашего примера) должен быть создан и согласован с заказчиком набор тестов, успешный пропуск которых свидетельствует об успешном окончании работы в целом. К сожалению, на практике такое встречается редко, поэтому сдача проекта – это всегда, скажем так, шумный процесс.


Содержание раздела