Стоит ли включать тесты в образ Docker?


19

Когда дело доходит до тестов, я могу придумать два варианта:

  1. Поместите и тест и приложение в одном изображении.
  2. Включите только код приложения в изображение. Создайте специальный тестовый контейнер, который создается после основного изображения и добавляет к нему несколько слоев (тестовый код, зависимости и т. Д.).

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

При втором варианте отправляемое изображение не совсем совпадает с проверяемым.

Оба выглядят как плохие стратегии. Есть ли третья, лучшая стратегия?


1
Вы в основном ответили сами. Оба плохая идея. Вы отправите уже протестированные запущенные процессы в контейнер, размер которого настроен в соответствии с вашими потребностями. Вам не нужны ни dev-зависимости, ни код src. В производстве это считается риском.
Laiv

1
Тестирование перед контейнеризацией означает, что среда не тестируется, а только код. Вы будете тестировать только часть того, что вы отправляете, а не все.
1851

Ответы:


10

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

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


1
Так что это в значительной степени вариант 2 - я запускаю тесты в среде / контейнере, которые очень похожи на производство, но не совсем то же самое. Это правильно?
lfk

9

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

TL; DR;

Короче, нужно отделить:

  • ваш код от
  • конфигурация приложения, от
  • конфигурация системной среды.

Каждый должен быть независимым друг от друга и соответственно:

  • контролируемая версия
  • проверенный
  • развертываемых

Более длинная версия

Во-первых, у вас есть приложение, состоящее из кода и (отдельных наборов) конфигурации. Это необходимо проверить как для функции сборки, так и для преднамеренной функции - это называется непрерывной интеграцией (CI). Существует много провайдеров этой услуги как онлайн, так и локально - например, CircleCI для облачного провайдера, который связывается с вашим репозиторием и создает и тестирует каждый раз, когда вы фиксируете. Если ваш репозиторий локальный и не может использовать облачного провайдера, что-то вроде Jenkinsбыл бы эквивалент. Если ваше приложение достаточно стандартное, вероятно, существует существующий образ Docker, который может использовать служба CI. Если нет, вам придется создать один или такой кластер, чтобы можно было развернуть код и конфигурацию вашего приложения. При правильной настройке у вас будет множество статистических данных о качестве кода вашего приложения.

Затем, как только вы будете удовлетворены функциональностью и правильностью вашего приложения, кодовая база должна быть соответствующим образом помечена для конкретной версии. Затем эта сборка должна быть развернута в тестовой среде. Обратите внимание, что код будет таким же, как проверенный в вашем CI (возможно, если вы сделали это правильно), но ваша конфигурация может отличаться. Опять же, некоторые поставщики CI могут предложить этот шаг, чтобы вы могли проверить развертывание упакованного приложения и дискретную конфигурацию. Этот этап обычно включает пользовательское функциональное тестирование (для новой функциональности), а также автоматическое тестирование (для известной функциональности). Если выпуск проходит этот этап, у вас есть кандидат на выпуск для интеграционного тестирования. Вы можете запустить тесты автоматизации из другого контейнера Docker,некоторые показатели, которые указывают на усилия по тестированию, составляют 1: 1 к усилиям по кодированию (хотя я сам не уверен в этом).

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

Наконец, у вас есть выпуск, который должен быть готов к работе, с небольшим набором различий конфигурации от тестов интеграции (IP-адреса, URI базы данных, пароли и т. Д.). Точка и большинство системной конфигурации хотя бы один раз.


Значит ли это, что ваш КИ вообще не будет тестировать ваши файлы Dockerfiles? Например, если в вашем Dockerfile отсутствует зависимость, тесты все равно пройдут?
LFK

1
Не за что. Сначала проверьте код, затем проверьте конфигурацию приложения, затем проверьте систему. Что я говорю, так это то, что это отдельные действия. Самое замечательное в контейнеризации заключается в том, что мечта о разработке в среде, аналогичной prod, очень близка. Но затвердевание сделало бы развитие слишком трудным.
avastmick

0

Я думаю, что вы смешиваете разные виды тестов. По сути, вы должны спросить себя: что за тестируемое устройство здесь?

Наиболее распространенный сценарий, когда вы работаете разработчиком, - это написание модульных / интеграционных тестов для некоторого фрагмента кода, над которым вы работаете, где этот фрагмент кода является тестируемым модулем. Вы запускаете эти тесты локально и / или в CI.

Когда вы создали новый образ докера, он становится новым модулем, который вы можете проверить. Какие вещи вы хотели бы проверить для этого изображения? Какой API он предоставляет? Как вы это тестируете?

Если это веб-приложение, вы можете запустить контейнер на основе изображения и выполнить несколько HTTP-запросов и убедиться, что ответы соответствуют вашим ожиданиям. Я думаю, что проблема, с которой вы столкнулись, заключается в том, что вы очень привыкли к тому, что тестовая среда связана с кодом приложения. Это хорошо во время разработки, но теперь вы хотите протестировать образ докера, и поэтому вам нужен новый вид тестовой среды, которая может это сделать и не привязана к коду приложения.

Поэтому я думаю, что третий вариант, который вы ищете, это:

  • Запустите ваши модульные / интеграционные тесты перед созданием образа докера.
  • Создайте образ докера, содержащий только приложение, которое вы хотите распространять.
  • Вместо добавления дополнительных слоев поверх изображения приложения, вы проверяете его как есть, запуская его с некоторыми заданными параметрами и утверждая ожидаемые результаты.

Таким образом, шаги CI / CD будут:

Настройка среды разработки -> Запуск тестов на коде -> Создание окончательного образа -> Запуск тестов на образе -> Развертывание образа.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.