Г. Майерс. Искусство тестирования программ

Oct 31, 2012 11:48


Если кто-то скажет, что Майерс устарел - он, скорее всего, даже не открывал автора, потому что "а что может быть интересного в книге, изданной больше тридцати лет назад?"
Интересного может быть все. Классика тестирования. Все остальные, кто за ним - разрабатывали идеи Майерса, исправляли, уточняли, но основа осталась.

"Тестирование - это процесс исполнения программы с целью обнаружения ошибок", а "удачный" прогон теста - это если ошибка найдена. Значит, тест составлен хорошо, и ошибку ловит.
Тестирование стоит денег, желательно возвратить затраченныую сумму путем увеличения стоимости программы. А чтобы ее при этом продолжали покупать, она должна быть надежнее и качественнее.
Роль тестирования состоит в том, чтобы определить местонахождение немногочисленных ошибок, оставшихся в хорошо спроектированной программе.
Попытки с помощью тестирования достичь надежности плохо спроектированной программы - совершенно бесплодны.

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

Инспекции исходного кода - да, это больше для программистов нынче, чем для тестеров.

Проектирование тестов.
"Следует представлять себе, что тестирование программы - чрезвычайно сложная задача. Если вы думаете, что разработка и кодирование программы - вещь трудная, то вы еще ничего не видели".
Методы:
Эквивалентное разбиение.
Сначала выделяют классы эквивалентности: выбирают входное условие, и разбивают его на две или более групп, которые могут быть как правильными классами, так и не правильными.
Правила выделения классов:
Если область значений (целое число от 1 до 99), то один правильный класс (1<=значение<=99) и два неправильных (<1), (>99).
Если число (от 1 до 6), то один класс правильный, и два неправильных (0), (>6).
Если условие "должно быть", то два класса - правильный как должно быть, и не правильный.
Если множество значений, возможно, разных - то каждое значение - это правильный класс, плюс один неправильный.
Если в классе можно выделить подкласс - то его нужно выделить в отдельный класс.
Потом строят тесты.
Каждому классу присваивается номер.
Планируется тесты, каждый покрывает как можно больше правильных классов.
Потом - по одному и только одному тесту на каждый неправильный класс.
Анализ граничных значений.
Граничные условия - это ситуации на, выше или ниже границ входных (и выходных!) классов эквивалентности.
Элемент в классе выбирают так, чтобы проверить каждую границу класса.
Проверяют не только вход - но и выход тоже.
Функциональные диаграммы.
Это надо читать :)
Предположение об ошибке.
Процедуры как таковой нет. Использовать опыт и интуицию.

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

Эта стратегия не гарантирует, что все ошибки будут найдены, но ее применение обеспечивает приемлемый компромисс. Реализация подобной стратегии весьма трудоемка, но ведь никто и никогда не утверждал, что тестировать программы - легко.

Как тестировать модули?
Можно монолитно - если программа небольшая, то собрать сразу все и сразу все тестировать.
Можно по нисходящей - то есть, сначала собирается некая главная штука, а потом от нее строятся дополнительные модули вниз. Плохо тем, что если станет понятно, что "главная штука" работает плохо, изменить ее уже будет крайне сложно, да и заглушки нужны, по идее.
Можно по восходящей - то есть, сначала результативные модули, получают значение на вход - дают результат, потом предыдущий модуль, который выдает это самое значение на вход, получая в свою очередь свои входные данные, и только потом - главная часть. Но тут программы как целого нету до конца.
На практике обычно используют комбинации - типа "гамбургера", когда собирают скелет главного и на него насаживают "снизу".

Процесс разработки:
Пользователь пишет требования. (почему нужна программа?)
Они анализируются, оцениваются, и на основе пишутся цели. (что она должна делать?)
На основе целей пишется подробная и точная спека, по методу черного ящика, - внешняя. (представление программы)
Система проектируется - вся целиком, структура. (как построена)
Проектируется каждый модуль.

Ошибки часто возникают при переходе от шага к шагу, поэтому желательно тестировать в конце каждого шага и начале следующего - не возникает ли недоразумений?
Плюс система тестов:
Требования - приемо-сдаточное тестирование.
Цели - тестирование системы.
Спека - тестирование функций (см. методы и принципы тестирования).
Модули - тестирование результатов сборки.

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

Планирование тестов
Основной просчет в планировании - при составлении графика предполагается, что ошибок не будет.
Как понять, что тестирование завершено?
- Тесты не находят ошибки (но они могут быть плохими просто)
- Время закончилось (а кто-то что-то вообще тестировал?)
Майерс предлагает три других:
- тесты, написанные по методам, не находят ошибок (проблемы те же);
- найдено предположительное число ошибок - или закончилось время на тестирование;
- график найденных ошибок в неделю пошел вниз, и идет вниз стабильно. Тут, конечно, тоже - что за ошибки, но все же.

Хорошо бы анализировать ошибки - но слишком уж велика опасность начала "охоты на ведьм".

testing, прочитанное

Previous post Next post
Up