Психология и экономика тестирования программ

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

Поначалу может показаться тривиальным жизненно важный вопрос определения термина «тестирование». Необходимость обсуждения этого термина связана с тем, что большинство специалистов используют его неверно, а это, в свою очередь, приводит к плохому тестированию. Таковы, например, следующие определения: «Тестирование представляет собой процесс, демонстрирующий отсутствие ошибок в программе», «цель тестирования — показать, что программа корректно исполняет предусмотренные функции», «тестирование — это процесс, позволяющий убедиться в том, что программа выполняет свое назначение».

Эти определения описывают нечто противоположное тому, что следует понимать под тестированием, поэтому они неверны. Оставив на время определения, предположим, что если мы тестируем программу, то нам нужно добавить к ней некоторую новую стоимость (т.е. тестирование стоит денег и нам желательно возвратить затраченную сумму путем увеличения стоимости программы). Увеличение стоимости означает повышение качества или возрастание надежности программы. Пос­лед­нее связано с обнаружением и удалением из нее ошибок. Следовательно, программа тестируется не для того, чтобы показать, что она работает, а скорее наоборот — тестирование начинается с предположения, что в ней есть ошибки (это предположение справедливо практически для любой программы), а затем уже обнаруживается их максимально возможное число. Таким образом, сформулируем наиболее приемлемое определение:

Тестирование — это процесс исполнения программы с целью обнаружения ошибок.

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

Из приведенного определения тестирования вытекает несколько следствий. Например, одно из них состоит в том, что тестирование — процесс деструктивный (т.е. обратный со­зи­да­тель­но­му, конструктивному). Именно этим и объясняется, почему многие считают его трудным. Большинство людей склонны к конструктивному процессу созидания объектов и в меньшей степени — к деструктивному процессу разделения на части. Из определения следует также то, как нужно строить набор тестовых данных и кто должен (а кто не должен) тестировать данную программу.

Для усиления определения тестирования проанализируем два понятия «удачный» и «неудачный» и, в частности, их использование руководителями проектов при оценке результатов тестирования. Большинство руководителей проектов называют тестовый прогон неудачным, если обнаружена ошибка, и, наоборот, удачным, если он прошел без ошибок. Чаще всего это является следствием ошибочного понимания термина «тестирование», так как, по существу, слово «удачный» означает «результативный», а слово «неудачный» — «нежелательный», «нерезультативный». Но если тест не обнаружил ошибки, его выполнение связано с потерей времени и денег, и термин «удачный» никак не может быть применен к нему.

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

Проведем аналогию с посещением больным врача. Если рекомендованное врачом лабораторное исследование не обнаружило причины болезни, не назовем же мы такое исследование удачным — оно неудачно: ведь деньги пациент заплатил, а он все так же болен. Если же исследование показало, что у больного язва желудка, то оно является удачным, поскольку врач может прописать необходимый курс лечения. Следовательно, медики используют эти термины в нужном нам смысле (аналогия здесь, конечно, заключается в том, что программа, которую предстоит тестировать, подобна больному пациенту).

Определения типа «тестирование представляет собой процесс демонстрации отсутствия ошибок» порождают еще одну проблему: они ставят цель, которая не может быть достигнута ни для одной программы, даже весьма тривиальной. Результаты психологических исследований показывают, что если перед человеком ставится невыполнимая задача, то он работает хуже. Иными словами, определение тестирования как процесса обнаружения ошибок переводит его в разряд решаемых задач и, таким образом, преодолевается психологическая трудность.

Другая проблема возникает в том случае, когда для тестирования используется следующее определение:

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

Подводя итог, можно сказать, что тестирование представляется деструктивным процессом попыток обнаружения ошибок в программе (наличие которых предполагается). Набор тестов, способствующий обнаружению ошибки, считается удачным. Естественно, в конечном счете, каждый с помощью тестирования хочет добиться определенной степени уверенности в том, что его программа соответствует своему назначению и не делает того, для чего она не предназначена, но лучшим средством для достижения этой цели является непосредственный поиск ошибок. Допустим, кто-то обращается к вам с заявлением: «Моя программа великолепна» (т.е. не содержит ошибок). Лучший способ доказать справедливость подобного утверждения — попытаться его опровергнуть, обнаружить неточности, нежели просто согласиться с тем, что программа на определенном наборе входных данных работает корректно.