И снова здравствуйте. Сегодня хотим поделиться с вами переводом третьей части статьи «Паттерны и анти-паттерны CI/CD», предыдущие части которой можно прочитать здесь и здесь. Напомним, данная серия публикаций приурочена к запуску нового потока по курсу «DevOps практики и инструменты», набор на который закроется уже в ближайшие дни.

1.3.5.1 Недостатки Сквозного Тестирования

“Любое преимущество от общения с настоящей системой затмевается необходимостью искоренять недетерминизм” Мартин Фаулер (Martin Fowler).

Сквозное Тестирование — практика, при которой большое число автоматизированных сквозных и ручных регрессионных тестов используются во время сборки вместе с малым количеством автоматизированных модульных и приемочных тестов. Соотношение тестов в Сквозном Тестировании можно визуализировать в виде Рожка Мороженого.



Сквозное Тестирование часто кажется привлекательным из-за субъективных преимуществ сквозных тестов:

  1. Сквозной тест максимизирует System Under Tests, что предполагает высокую степень покрытия тестами;
  2. Сквозной тест использует саму систему в качестве тестового клиента, что предполагает низкие затраты на тестовую инфраструктуру.

Учитывая вышесказанное, можно понять, почему многие организации внедряют Сквозное Тестирование. Как заметил Дон Рейнертсен (Don Reinertsen): “Такая комбинация низких затрат и высокой достоверности создает иллюзию экономичности подобных системных тестов”. Однако, ценностное предложение Сквозного Тестирования абсолютно ложно в силу неверности обоих утверждений:

  1. Сама идея того, что тестирование целой системы включает в себя проверку составных частей — Ошибка Декомпозиции. Проверка реализации на соответствие требованиям — не то же самое, что проверка реализации на соответствие целям. Это значит, что сквозной тест проверит взаимодействия между путями кода, но не само поведение этих путей.
  2. Сама идея того, что тестирование целой системы окажется дешевле, чем тестирование ее составных частей — Ошибка Дешевых Инвестиций. Время выполнения тестов и недетерминированность прямо пропорциональны объему SUT. Это значит, что сквозной тест будет медленным и склонным к недетерминированности.

Мартин Фаулер ранее предупреждал, что “недетерминированные тесты могут полностью разрушить ценность автоматизированного регрессионного набора”, а Циклы Контроля, Влияния и Обеспокоенности Стивена Кови подчеркивают, как множество факторов сквозного теста усложняют поиск и решение недетерминированности. Если бы разные команды в одной организации Companies R Us владели Company Accounts и Paтyments сервисом, команда Company Accounts контролировала бы свой сервис в сквозном тесте, но это влияло бы только на Payments сервис.

Время, необходимое на улучшение сквозного теста, зависит от расположения изменения в SUT. Команде Company Accounts необходимо проанализировать и реализовать это изменение в сервисе за короткие сроки. Однако, время, необходимое для внесения изменений в Payments сервис, не может быть меньше, чем срок, необходимый команде Company Accounts на убеждение команды Payments сервиса приступить к делу.

В другом случае, если бы отдельная организация Payments R Us владела Payments сервисом, она была бы просто сторонней службой и не проблемой команды Company Accounts.
В таком случае изменение Payments сервиса потребует гораздо больше времени, ведь команда Company Accounts никак не влияет на организацию Payments R Us. Более того, Payments сервис может быть неожиданно обновлен, что усилит недетерминированность в сквозных тестах Company Accounts и сделает невозможным установление предсказуемого исхода прогона тестов.

Опора на Сквозное Тестирование часто является симптомом длительного недофинансирования, что делает систему хрупкой, неспособной меняться, увеличивает ее время поставки и оптимизирует под Средние Наработки На Отказ, а не Среднее Время на Восстановление. В такой системе невозможно точно спрогнозировать пользовательский опыт и операционную производительность из-за изменений, вызванных внешними факторами, а сосредоточение внимания на вероятности сбоя вместо стоимости сбоя, создает подверженность крайне маловероятным но, очень дорогостоящим событиям, известным как Черные лебеди, например Knights Capital потеряли $440 миллионов за 45 минут. Так если Payments дата-центр пострадает от катастрофического сбоя, все платежи клиентов, совершенные сервисом Company Accounts, не будут выполнены.

Недоступность Payments сервиса на лету заблокирует платежи клиентов Company Accounts, а медленное восстановление сервиса заставит недовольных клиентов обратиться к другим фирмам. Если какие-то платежи окажутся потеряны и об этом станет известно публично, то это приведет к значительной потере клиентского доверия.

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

1.3.5.2 Преимущества Непрерывного Тестирования

“Покончите с зависимостью от массового контроля. Уничтожьте потребность в массовой проверке, изначально сделав качество частью продукта” Др. В. Эдвардс Деминг .

Для Непрерывной Поставки требуется Непрерывное Тестирование — стратегия, при которой большое количество автоматизированных модульных и приемочных тестов дополняется небольшим количеством автоматизированных сквозных и целенаправленных исследовательских тестов. Соотношение тестов в Непрерывном Тестировании можно визуализировать в виде Пирамиды — своеобразной антитезы Рожка Мороженого.

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

  1. Модульный или приемочный тест минимизирует SUT, что предполагает низкую степень охвата тестирования;
  2. Модульный или приемочный тест использует собственный тестовый клиент, что предполагает высокие затраты на тестовую инфраструктуру.

Многие пользуются Сквозным Тестированием из неверного предположения о высоком тестовом покрытии и низких затратах на поддержку, и при этом думают, что Непрерывное Тестирование дает низкое тестовое покрытие и дорого в поддержке:

  1. Модульный тест проверяет соответствие реализации цели, а приемочный тест проверяет соответствие реализации требованиям. Значит все пути исполнения и их взаимодействие друг с другом могут быть проверены.
  2. Модульный тест ограничивает объем SUT до единственного пути исполнения, а приемочный тест ограничивается до единственного сервиса. Значит оба могут иметь минимальное время выполнения и детерминированные результаты.

Недетерминированный приемочный тест можно исправить гораздо быстрее, чем сквозной тест, благодаря единственному владельцу SUT. Если бы Companies R Us владела сервисом Company Accounts, а Payments R Us — Payments сервисом, то приемочный тест Company Accounts использовал бы только сервисы, контролируемые их командой.

Если команда Company Accounts попытается выявить и решить недетерминированность в приемочном тесте, им удастся внедрить необходимые изменения в краткие сроки. Также не придется бояться неожиданных изменений в Payments сервисе, которые могут помешать приемочному тесту последнего кода Company Accounts. Это позволит создать прогнозируемый уровень тестирования.

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

В Непрерывной Доставке признается, что оптимизация под Среднее Время на восстановление важнее, чем оптимизация под Среднее Время между Сбоями, так как оно позволяет организации минимизировать влияние производственных дефектов и проще в достижении. Стоимость дефектов можно контролировать, так как по Закону Литтла короткие релизы сокращают период устранения дефектов, а Непрерывное Тестирование обеспечивает необходимую инфраструктуру для уменьшения циклов обратной связи для частых релизов. Сочетание методов Непрерывного Тестирования и Непрерывной Доставки, таких как Blue Green Releases и Canary Releases, позволяет организации создать надежную систему, способную нейтрализовать непредвиденные события, а продвинутые практики вроде Dark Launching и Chaos Engineering могут привести к антихрупким системам, получающим выгоду от Black Swans. Например, если Chaos Engineering обнаруживает проблемы с Payments сервисом, команда Company Accounts может сделать Dark Launch своего Payments Стаба в производство и использовать его в непредвиденных случаях выхода из строя Payments дата-центра.

Пока Payments дата-центр будет оффлайн, сервис Company Accounts изящно перейдет к сбору платежей покупателей в Payments Стабе до тех пор, пока Payments сервис не начнет работать. Этот инцидент не затронет клиентов, а если от того же стороннего Payments сервиса зависят и конкуренты, то это может оказаться стратегическим преимуществом на рынке. Избыточные операционные возможности могут показаться излишними, но Непрерывное Тестирование продвигает операционное совершенство, и, как отметил Нассим Николас Талеб (Nassim Nicholas Taleb), “все необычное обычно случается”.

Непрерывное Тестирование может быть комплексной и недорогой тестовой стратегией. По словам Дэйва Фарли (Dave Farley) и Джеза Хамбла (Jez Humble) “встраивание качества означает написание автоматизированных тестов на нескольких уровнях”, а тестовый набор, состоящий по большей части из модульных и приемочных тестов, содержит тщательно проверенные сценарии с высокой степенью охвата тестов, низким временем выполнения и предсказуемыми результатами тестирования. Так сквозные тесты можно оставить для дымового тестирования и мониторинга производства, а тестеры вместо ручного регрессионного тестирования смогут заняться более ценными вещами, например, исследовательским тестированием. Это приведет к уменьшению количества дефектов производства, быстрой и надежной обратной связи, сокращению времени подготовки к выходу на рынок и новым возможностям роста доходов.

1.3.5.3 От Сквозного Тестирования к Непрерывному

“Тестируйте как можно глубже ради максимальной отдачи инвестиций и самой быстрой обратной связи” Джанет Грегори (Janet Gregory) и Лиза Криспин (Lisa Crispin).

Переход от Сквозного Тестирования к Непрерывному — долгосрочная инвестиция, основанная на представлении, что сквозные тесты могут быть внизу Пирамиды Тестирования, если обозначить их зоны ответственности следующим образом:

  • Связь — могут ли сервисы соединяться друг с другом;
  • Диалог — могут ли сервисы общаться друг с другом;
  • Поведение — могут ли сервисы реагировать друг на друга.

Предположим, сервис Company Accounts зависит от эндпоинта Pay сервиса Payments, который принимает id компании и размер платежа, а затем выдает код подтверждения и количество дней до совершения платежа. Сервис Company Accounts отправляет поля запроса id и размера платежа и зависит от полей ответа.

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

Диалог между сервисами можно проверить модульно с помощью Consumer Driven Contracts, которые позволят сервису Company Accounts непрерывно проверять свои взаимодействия сервисом Payments. Сервис Payments выдаст Provider Contract, описывающий API Pay во время сборки, а сервис Company Accounts вернет Consumer Contract, описывающий использование. Payments сервис создаст Consumer Driven Contract, который будет проверяться во время каждой сборки.

Так как сервис Company Accounts не использует поле для дней, оно будут исключено из Consumer Contract и Consumer Driven Contract. Поэтому сборка Payments сервиса, с удалением дней или добавлением нового поля для ответных комментариев будет успешна. А если будет удалено поле кода ответа, то Consumer Driven Contract даст сбой, и команде Payments придется договориться с командой Company Accounts о другом подходе.

Поведение сервисов можно протестировать модульно с помощью API Examples, что позволит сервису Company Accounts проверить изменения поведения в новых релизах сервиса Payments. Каждый его релиз будет сопровождаться артефактом, содержащим примеры API запросов и ответов для конечной точки Pay, которая подключена к модульным тестам Company Accounts в роли репрезентативных тестовых данных и для предупреждения об изменении поведения.

Если новая версия Payments сервиса изменит формат поля кода ответа с буквенно-цифрового на числовой, произойдет сбой сервиса Company Accounts во время сборки, указывая на изменение поведения внутри Payments сервиса и необходимость обсудить этот вопрос обеим командам.

1.3.5.4 Вывод

“Системное Тестирование не только не обнаружит все баги, но и потребует больше времени и денег — больше, чем вы могли бы сэкономить, пропустив эффективное приемочное тестирование” — Джерри Вайнберг (Jerry Weinberg).

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

Комментарии (0)