Стратегия очагового внедрения автотестов. Часть I: О роли тестирования

June 1, 2018
test xUnit главное

Вступление

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

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

Статья логически состоит из четырех частей. В первой части я вкратце пробегусь по основам, расскажу что такое тесты, для чего они и какие бывают; опишу собственные траблы при освоении тестов на фреймворке xUnit и уроки извлеченные из этого опыта. Во второй части описывается предлагаемая мною модель стратегии внедрения тестов, которую я назвал «очаговой моделью». В третьей части я попытаюсь на примере PHP показать, как можно писать тесты на легаси код, руководствуясь данной стратегией. В четвертой части (для самых терпеливых) я хочу рассмотреть возможные способы ускорения уже существующих тестов.

Статья может быть интересна как разработчикам, так и QA специалистам.

О тестах

Что такое тесты - Типы тестов - Пирамида Тестирования - О сложности внедрения тестов в существующую систему - Краткое описание xUnit - Описание первого неудачного опыта и выводы - Осмысление своего опыта - Что должна уметь система тестирования и из каких компонентов состоять.

Википедия дает несколько противоречивое определение автотестам:

Автотесты - это часть процесса тестирования на этапе контроля качества в процессе разработки программного обеспечения. Оно использует программные средства для выполнения тестов и проверки результатов выполнения, что помогает сократить время тестирования и упростить его процесс…

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

С другой стороны: "... в процессе разработки программного обеспечения". Здесь вроде бы тоже не возникает вопросов. Относительно недавно разработчики стали сами писать тесты на свой код, таким образом тесты превратились в неотъемлемую часть программы. В этом случае написание тестов - это встраивание качества в продукт.

Таким образом автотесты - это одновременно и механизм встраивания качества в разрабатываемый продукт и метрика измерения качества готового продукта. Для нас как разработчиков в первую очередь будет интересна часть: тесты как механизм встраивания качества.

Нельзя отрицать, что истинная ценность тестов для разработчика состоит в способности сковать функциональность тестируемой системы, и достижении уверенности в том, что заложенная изначально функциональность внезапно не изменится. Если говорить образно, и представить что программный продукт - это некая хрупкая скульптура, то тесты словно, наброшенная на данную скульптуру сеть, фиксируют положение всех ее частей. Развивая метафору сети дальше, можно так же представить тесты как страховочную сеть, которую совместно «ткут» разработчики для того, чтобы в случае, если кто-то из них допустит ошибку и “сорвется” она смогла его спасти от потерь. Используя слово “совместно”, я хочу подчеркнуть, что тесты - это коллективная ответственность всех разработчиков, работающих над продуктом. Если кто-то допустил брак и не написал тесты на свой код, то в ближайшей перспективе он может и не пострадать сам, но при этом случайно подставить своих коллег может.

Иллюстрация к метафоре: тесты как страховочная сеть

Разработчики не пишущие тесты подобны канатоходцам работающим без страховки.

О сложности внедрения тестов в существующую систему

В идеальном мире должно быть так: тесты обеспечивают идеальную обратную связь системы на внесенные изменения и разработчики запускают тесты каждые три минуты после любых правок в коде. И в случае ошибок оперативно их исправляют.

В реальном - неидеальном мире встречаются разные случаи, но в основном их можно разбить на следующие кейсы:

О рефакторинге легаси кода и приведении его к современным стандартам написано много книг. При этом об аналогичной задаче покрытия тестами существующей системы с легаси кодом написано не так уж и много, хотя зачастую эта задача намного сложнее рефакторинга легаси кода и даже создания системы с нуля. Из стоящих книг о написании тестов можно упомянуть разве что “xUnit Test Patterns: Refactoring Test Code” Gerard Meszaros.

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

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

Продолжение Часть II: Концепция очаговой модели внедрения тестов.