Статьи

Интегрированные тесты плохо себя чувствуют — да здравствует дизайн

Отвезите меня в большой город Rails / где тесты зеленые, и они занимают 10 минут

Я проверил дату во второй половине дня:

$ date

Ср. 23 апреля 14:38:08 CEST 2014
и, видимо, это 2014, но все еще широко распространено мнение (
в некоторых кругах ), что интегрированные (или сквозные
) тесты следует отдавать предпочтение прошли юнит-тесты. Убеждение, что разработка через тестирование не оказывает положительного влияния на качество ваших тестов и кода.

Поэтому сегодня я повторяю несколько вещей, о которых я писал в последние годы.

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

Несколько свойств юнит-тестов

Модульные тесты предназначены для одного или нескольких объектов одновременно, не обращаясь к ресурсам, отличным от ЦП и памяти текущего процесса. Что касается комплексных испытаний, они:

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

Слушай свои тесты

Сколько утверждений должен записать мужчина / прежде чем называть его мужчиной?

Это не значит, что интегрированные тесты бесполезны:
на phpDay идет речь, в которой я объясню, как работает наш набор тестов Behat, и какие оптимизации мы сделали, чтобы он продолжался менее 5 минут. Некоторые проблемы, связанные с интеграционными тестами, заключаются в том, чтобы системы, созданные разными командами, работали вместе, осуществляли рефакторинг устаревшего кода и тесты на приемочном уровне, написанные на языке заказчика.

Однако отношение юнит-тестов к интегрированным тестам должно быть в диапазоне от 10 до 1 или даже от 50 до 1. Если в проекте действует сила, которая требует более интегрированных тестов, чем юнит-тесты, вы попадаете в порочный круг, где вместо записи:

assertEquals("1.00", new Money(100).toString());
you're writing, more often than not:
createSubscription();
assertEquals(
  "<span class="money">1.00</span>",
    findPriceTag(get("/subscription/" + id))
);

и продвижение связи между объектами Money, Subscription и PageTemplate.

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

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

Возьми меня в волшебство момента / в ночь славы / где мечтают объекты завтрашнего дня / в ветре перемен

Ресурсы

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

И, наконец, стиль этого поста вдохновлен «
Позвони мне, может быть»: MongoDB .