Пирамида тестирования

Автор: Мартин Фаулер

Дата публикации: 1 мая 2012
Оригинал: https://martinfowler.com/bliki/TestPyramid.html

Пирамида тестирования — это концепция того, как различные виды автоматизированных тестов должны использоваться должны использоваться для создания сбалансированного портфеля. Её основная идея заключается в том, что у вас должно быть гораздо больше низкоуровневых модульных тестов (unit tests), чем высокоуровневых сквозных тестов (broad-stack tests), выполняемых через графический интерфейс пользователя.

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

Но такой подход быстро приводил к проблемам, превращаясь в «рожок мороженого» (ice-cream cone). Тестирование через пользовательский интерфейс подобным образом происходит медленно, увеличивая время сборки. Часто это требует установленных лицензий на программное обеспечение для автоматизации тестирования, что означает, что тесты можно запускать только на определённых машинах. Обычно такие тесты невозможно легко запустить в режиме без графического интерфейса (headless mode), управляемом скриптами для включения в правильный пайплайн деплоя.

Что наиболее важно — такие тесты очень хрупкие. Улучшение системы может легко привести к поломке множества таких тестов, которые затем придётся перезаписывать. Вы можете уменьшить эту проблему, отказавшись от инструментов записи-воспроизведения, но это сделает написание тестов более сложным. Даже при соблюдении хороших практик написания, сквозные тесты более подвержены проблемам недетерминированности, что может подорвать доверие к ним. Короче говоря, тесты, которые выполняются сквозным образом через пользовательский интерфейс:

  • хрупкие
  • дорогие в написании
  • требуют много времени для выполнения

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

Пирамида также выступает за промежуточный уровень тестов, которые работают через слой сервисов приложения, что я называю подкожными тестами (subcutaneous tests). Они могут предоставить многие преимущества сквозных тестов, но избежать многих сложностей работы с UI-фреймворками. В веб-приложениях это соответствовало бы тестированию через слой API, в то время как верхняя UI-часть пирамиды соответствовала бы тестам, использующим что-то вроде Selenium или Sahi.

Пирамида тестирования часто всплывает в кругах Agile-тестирования, и хотя её основное послание верно, есть гораздо больше, что можно сказать о построении хорошо сбалансированного портфеля тестов. Распространённая проблема заключается в том, что команды смешивают концепции сквозных тестов, UI-тестов и клиентских тестов. Все это независимые (orthogonal) характеристики. Например, богатый JavaScript UI должен иметь большую часть своего UI-поведения протестированным с помощью модульных JavaScript-тестов, используя что-то вроде Jasmine. Сложный набор бизнес-правил может иметь тесты, представленные в клиентском виде, но выполняться только на соответствующем модуле, как это делают модульные тесты.

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

Дополнительное чтение

Google Testing Blog раскрывает, почему вам не следует полагаться на сквозные тесты.

Adrian Sutton объясняет опыт LMAX, который показывает, что сквозные тесты могут играть большую и ценную роль.

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

Благодарности

Кевин Дишман подал мне идею добавить стрелки стоимости и скорости на иллюстрацию.

Этимология

Большинство людей знают о пирамиде тестирования благодаря Майку Кону (Mike Cohn), который описал её в своей книге 2009 года “Succeeding with Agile”. В книге он называет её “пирамидой автоматизации тестирования” (Test Automation Pyramid), но на практике она обычно называется просто “пирамидой тестирования” (test pyramid). Он впервые нарисовал её в разговоре с Лизой Криспин (Lisa Crispin) в 2003-2004 годах и описал на scrum-встрече в 2004 году. Джейсон Хаггинс (Jason Huggins) независимо пришёл к той же идее около 2006 года.

Zend_Tool подключение кастомных провайдеров

1. Пишем кастомный провайдер (-ы) и манифест

class PS_Tool_RouteProvider extends Zend_Tool_Framework_Provider_Abstract

{

      ......

}

class PS_Tool_Manifest implements Zend_Tool_Framework_Manifest_Interface

{

    public function  getProviders()

    {

        return array(         
            new PS_Tool_RouteProvider         
        );

    }

}

Создаем конфиг для утилиты zf

zf --setup config-file

 3. Открываем создавшийся (скорее всего в домашней папке файл .zf.ini)

 4. Добавляем пути к библиотеке с провайдером в include_path

 php.include_path = "C:/xampp/php/pear;C:/xamp/phtdocs/shared;C:/xampp/htdocs/diclon/application/library;"

 5. Подключаем кастомный провайдер (добавляем строку в .zf.ini)

basicloader.classes.0 = PS_Tool_RouteProvider
basicloader.classes.1 = PS_Tool_Manifest

Всё, можно использовать.

Zend_Tool пакет в Zend Framework, который предназначен для программирования консольной утилиты zf.

По умолчанию в zf уже встроены ряд операций, но их модно расширять кастомным провайдером.

Формы в Laravel

Многие фреймворки имеют встроенную поддержку генерации форм. В Laravel так было изначально, но затем формы выделили в отдельный компонент laravelcollective/html. В самом Laravel осталось буквально несколько элементов: защита от CSRF и поддержка дополнительных методов HTTP в HTML-формах.

Для установки этого компонента выполните эту команду:

composer require "laravelcollective/html"

Фаулер о добавлении новой функциональности

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

Мартин Фаулер

GIT fatal: inflateInit: out of memory

На одном из серверов при попытке пушнуть взятый под git код возникла ошибка
Delta compression using up to 24 threads.
fatal: inflateInit: out of memory (no message)

Помогло сокращение трэдов упаковки

git config --global pack.threads 1

О преждевременной оптимизации

 . 

“Преждевременная оптимизация — корень всех зол”

Дональд Кнут

статья «Structured Programming with go to Statements» в сборнике «Computing Surveys» (Vol. 6, № 4, декабрь 1974, стр. 268)