Данный материал представляет собой своего рода путевые заметки человека, только постигающего всю эзотерическую глубину тестирования. По мере накопления информации и критики я буду пополнять данный раздел. Все размышления носят печать глубокого IMHO и не претендуют на истинность.
По мере роста приложения возникает необходимость в тестировании. Конечно, желательно строить процесс разработки таким образом, чтобы тестирование предшествовало выходу релизов, а не последние выступали в роли тестовой платформы(sic бывает очень часто:)). Сразу оговорюсь, речь идет об автоматическом тестировании на основе планов, а не о так называемом UAT – User Acceptance Testing. Это отдельная тема разговора, такое тестирование проводят люди с железными нервами, которым, как я слышал, в одной из отечественных контор даже разрешается пить пиво на работе.
Автоматические тесты предназначены более для выявления дефектов в запросах, поиска просчетов в алгоритмах(бейте граничными значениями по входам – узнаете много нового о своих функциях), нахождении мелких неточностей и упущений. Что представляет собой тест? Это последовательность действий, которая включает в себя проверку загрузки модулей в память, их инициализацию и выполнение некоторых действий с последующим сравнением результатов. Теоретически, подобными тестами можно покрыть все приложение, однако делать это смысла нет, так как даже тотальное авто-тестирование не дает 100% гарантии, что приложение и в жизни будет работать столь же успешно, как и на тестах.
Как мне кажется, одно из основных предназначений тестирования состоит в том, что дает возможность разработчику проверить, а будет ли работать данный метода/класс после внесения некоторых изменений и как эти изменения повлияют на работу других частей приложения, которые используют модифицированный код. Буду судить по себе – я достаточно часто возвращаюсь к уже написанным модулям, когда меня посещает очередная ИДЕЯ. Мне нравится делать рефакторинг уже созданного кода, но далеко не всегда изменения носят сугубо косметический характер и потом превращаются в головную боль. Когда же тесты готовы заранее, можно относительно безопасно работать с кодом. Так что – тесты поощряют разработчика заниматься рефакторингом.
Еще одним полезным моментом является то, что тестировать лучше маленькие порции кода, что уже подразумевает наличие хотя бы какого-то дизайна у приложения:)
Итак, с чего начать? Как же проводить тестирование? Как ни странно, начинается все с бумаги. Перед тем, как что-либо писать, нужно разработать тестовый план. Если необходимо тестировать бизнес-логику – не слезайте с заказчика, пока он не предоставит его, в случае же низкоуровневого взаимодействия полагайтесь только на свою фантазию, будьте максимально пессимистичны относительно входных данных, что почти соответствует тому, что придет в приложение, когда за дело возьмутся реальные пользователи. Давайте представим модуль который подлежит тестированию, как черный ящик, своего рода передаточную функцию, у которой есть входные и выходные сигналы. Хороший тестовый план должен включать в себя описание входных параметров и соответствующих им выходных значений. Так же неплохо включать в тестовый план ошибочные данные, чтобы проверить работу функции в таких вот ситуациях.
Наконец, план разработан, был выписан набор параметров и просчитаны выходные значения. Давайте подумаем, каким образом данные будут попадать на вход тестируемой функции. Хорошим тоном будет загружать тестовый сценарий из файла, нежели жестко кодировать граничные условия. Таким образом тест получается более гибкий и адаптируемый. Думаю, у каждого есть свои собственные излюбленные методы загрузки данных. Лично мне очень понравилось использовать для этого YAML(мы вернемся к этой теме чуть позже), ввиду простоты и формата файла, который можно редактировать вручную.
Идем дальше. Предположим, приложение активно использует какой-то источник данных. Довольно часто в его роли выступает СУБД. В принципе, можно сделать копию реальной рабочей базы с продакшн-сервера и гонять на ней тесты, но этот вариант имеет ряд недостатков. Во-первых, нет детерминированности данных – вы не знаете достоверно, что сейчас находится в таблице/таблицах. Во-вторых, тесты могут менять данные, так что в следующий раз придется иметь дело не только с настоящими данными, но и с синтетическими, попавшими туда в результате тестов(которые, кстати, не все могут закончиться успешно). Как мне кажется, достаточно удобно иметь заранее подготовленный дамп тестовой базы данных, который можно загружать в начале процедуры. Такой дамп можно сделать из реальной базы, удалив 80% информации, оставив лишь пару-тройку записей. Так же неплохо иметь описание этих данных – сколько и что содержится в таблицах, так что если запрос с INNER JOIN вернет 10 строк вместо содержащихся 2 в таблице – это повод серьезно призадуматься.
Подведем краткий итог. Для проведения тестирования нужно:
- подробный план, описывающий максимальное количество ситуаций
- удобный механизм доставки тестовых данных
To be continue

"Сначала пишуться тесты, а потом модуль" (с)
"Сначала пишуться тесты, а потом модуль" (с) - это я гдето встречал... за точность выражения не ручаюсь, но смысл понятен...
Ну и естественно я сам абсолютно согласен с этим высказыванием, потому как это позволяет, или заставляет, кроме собственно самого тестирования, сразу осознанно подойти к дизайну модуля, осмыслить весь его функционал. Ну по крайней мере попытаться :) Чем жестче мы опишем внешний интерфейс, а ранние тесты именно его специфицируют в первую очередь, тем четче и стройней будет внутренняя архитектура компонента...
А за статью спасибо... немного другой взгляд на некоторыек вещи, интересно :)
----
Чтобы правильно задать вопрос, нужно знать больше половины ответа...
Интересно, на
Интересно, на какие вещи другой взгляд:)?
Да нет я в
Да нет я в принципе со всем согласен, просто учитывая что я потихоньку осваиваю UML. То понятие "вариантов использования" в нем, и определяет все возможные ситуации с граничными значениями, что позволяет строить тесты автоматически на основе указанных спецификаций. Да и вообще то что я рассуждаю об этих вещах, не значит что я их хорошо освоил, для меня на данном этапе это тоже в процессе первичного применеия, и некоторые вещи не столько иные, сколько просто новые.
Тесты для своих модулей я естественно пишу. Но как правило на время активной разработки, или когда схема достаточно сложная и состоит из нескольких компонентов, работоспособность которых должна проверяться в сумме. Тогда пишуться зачастую простые тестовые заглушки, чтобы быть уверенными в работоспособности одного из компонентов перед написанием второго, который будет тестироваться уже как сумма взаимодействий между ними...
Думаю планомерный подход к комплексному тестированию мне еще предстоит выработать :)
----
Чтобы правильно задать вопрос, нужно знать больше половины ответа...
Коротко напишу,
Коротко напишу, как постепенно вводиться автоматизированное тестирование в серьезных проектах + добавлю немного теории (в упрощенном виде), поскольку некоторые ошибки в статье допущены из-за подлога понятий.
Итак начнём немного теории
White Box Testing: Testing based on an analysis of internal workings and structure of a piece of software. Contrast with Black Box Testing.
Black Box Testing: Testing based on an analysis of the specification of a piece of software without reference to its internal workings. The goal is to test how well the component conforms to the published requirements for the component.
User Acceptance Testing: A formal product evaluation performed by a customer as a condition of purchase.
Unit Testing:Testing of individual software components.
Regression Testing: Retesting a previously tested program following modification to ensure that faults have not been introduced or uncovered as a result of the changes made.
Тестирование делиться на 2-ва основных вида:
Также есть куча подвидов, если интересно спрашивайте, расскажу.
Теперь сам процесс:
Все, что было описано в статье, как я понимаю, относиться к Unit тестированию. При котором действительно правильным подходом является вначале создание Unit теста на функцию или модуль, а потом уже написание кода.
Но в реальных проектах с Unit тестирования все начинается, а заканчивается в паре с прогонкой Regression Test Set ( набор Test Case-ов) – эта пара и есть реальное комплексное автоматизированное тестирование ( смесь WhiteBox-a и BlackBox-а).
Unit тесты – разрабатывают девелоперы на основе будущего кода, особо сильно не заморачиваясь, например, проверяя только что “1+1 = 2”, а не “3” или что функция возвращает “unsigned int”, a не “double”
Test Cases – пишут тестеры, которые покрывают маленький кусок функционала (BlackBox). Test Cases, которые покрывают один функционал объединяют в Test Set.
А Regression Set - это набор Test Set-ов :)
К сожалению, нет много времени много писать, будут вопросы рад буду ответить
А зачем
А зачем коротко:)? Я буду не в обиде(и не только я), если ты исправишь/дополнишь данный раздел.
Не помню, писал я или нет, мой опыт в тестировании имеет крайне поверхностный характер, и все вышесказанное является глубочайшим IMHO:) А вот получить описание, да еще от опытного специалиста, да еще и на русском языке, да еще и с комментариями - это было бы просто отлично! Так что надеюсь на помощь:)
Automated Testing with Perl
http://petdance.com/perl/automated-testing/
С уважением, Одуван.
Так и не нашел,
Так и не нашел, как связаться с автором. Было бы неплохо сделать перевод.
автор
http://petdance.com/
там же есть вся инфа про него. Почта и т.д.