DevGang
Авторизоваться

Запуск тестов в контейнерах с помощью docker-compose

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

Ниже вы увидите, как настроить docker-compose для обычного приложения Ruby on Rails. В качестве бонуса вы сможете повторно использовать эти настройки во всех проектах без особых изменений.

Чего мы хотим достичь

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

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

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

Войдите в Docker

Использование Docker для запуска тестов может помочь вам решить эти проблемы. У всех разработчиков будет одинаковая изолированная тестовая среда, которую также можно использовать для запуска тестов в CI. Новым разработчикам не придется тратить полдня только на то, чтобы настроить все необходимое для запуска тестов.

Тесты будут запускаться внутри контейнера, поэтому вам необходимо его определить. Это делается в Dockerfile:

FROM cimg/ruby:2.7.1

ARG TINI_VERSION=v0.19.0

RUN sudo apt-get update -qq \
  && sudo apt-get install -yq --no-install-recommends \
      libxml2-dev libxslt-dev libtool pkg-config \
      libbz2-dev libglib2.0-dev libxml2-dev libxslt-dev cmake \
  && sudo apt-get clean \
  && sudo rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
  && sudo truncate -s 0 /var/log/*log

ENV BUNDLE_JOBS=4 BUNDLE_RETRY=3

RUN gem update --system && gem install rake bundler --no-document

ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /usr/local/bin/tini
RUN sudo chmod a+x /usr/local/bin/tini

ENTRYPOINT ["/usr/local/bin/tini", "--"]

Сначала определите базовый образ, здесь мы используем официальный образ CircleCI. Затем установите необходимые зависимости приложения и настройте владение и права на файлы с смонтированных томов (подробнее об этом позже). В конце определите точку входа в Tini.

Tini — это удобный инструмент, который помогает собирать любые процессы-зомби и пересылать сигналы командам, выполняемым в контейнере.

Подключение

Для выполнения задач приложения могут потребоваться дополнительные зависимости от служб. В этом примере для запуска тестов приложению необходим доступный экземпляр базы данных. Это можно сделать с помощью файла docker-compose.

version: "3.8"

services:
  app:
    build:
      context: .
      dockerfile: ./Dockerfile
    environment:
      DATABASE_URL: postgresql://root@db:5432/db_name
      DISABLE_SPRING: 1
      MALLOC_ARENA_MAX: 2
      PARALLEL_WORKERS: 1
      PGHOST: db
      PGUSER: root
      RAILS_ENV: ${RAILS_ENV:-test}
    networks:
      default:
    user: ${CURRENT_UID:?"Please run as follows 'CURRENT_UID=$(id -u):$(id -g) docker-compose up'"}

    volumes:
      - .:/home/circleci/project:cached
      - gems:/home/circleci/.rubygems
      - cache:/home/circleci/.cache

    depends_on:
      - db

  db:
    image: circleci/postgres:alpine
    restart: always
    environment:
      POSTGRES_USER: root
      POSTGRES_DB: db_name
    volumes:
      - pg:/var/lib/postgresql/data
volumes:
  gems:
  cache:
  pg:

Здесь мы определяем две службы: app и db. Служба приложений создается с использованием определенного Dockerfile, здесь также задаются все необходимые переменные среды.

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

Обратите внимание, что мы указываем пользователя для службы приложений, и этот пользователь должен быть передан вызывающей стороной команды docker-compose.

Это сделано для решения проблемы с разрешениями, которая может возникнуть, когда процессам необходимо изменить файлы внутри смонтированных томов или когда вам потребуется доступ к файлам (журналам, снимкам экрана и другим артефактам), сгенерированным внутри контейнера. Чтобы решить обе эти проблемы, вам необходимо передать текущий идентификатор пользователя командам docker-compose.

Конфигурация службы базы данных состоит из имени образа (предоставленного CircleCI), учетных данных доступа к БД в переменных среды и тома для хранения данных БД.

Применение: Docker и docker-compose сейчас проделывают большую работу, чтобы облегчить жизнь разработчикам, но нужно еще многое запомнить и набрать:  
  export CURRENT_UID=$(id -u):$(id -g)

    docker-compose up --remove-orphans -d db

    docker-compose build app

    docker-compose run app bin/bundle install

    docker-compose run app bin/rails db:prepare

    docker-compose run app bin/rails bin/rails db:schema:load

    docker-compose run app bin/rspec

Все это можно извлечь в несколько служебных скриптов:

#!/usr/bin/env bash

echo "=>  Install dependencies"
bin/bundle install

echo "=>  Prepare DB"
bin/rails db:prepare
bin/rails db:schema:load
#!/usr/bin/env bash

echo "=>  Build"

export CURRENT_UID=$(id -u):$(id -g)

docker-compose up --remove-orphans -d db
docker-compose build app

echo "=>  Setup"
docker-compose run app bin/ci-setup
#!/usr/bin/env bash

echo "=>  Run tests"

export CURRENT_UID=$(id -u):$(id -g)

docker-compose run app bin/rspec

Теперь настройка и запуск тестов внутри docker-контейнера достигается только запуском:

   bin/dc-setup

    bin/dc-test

Docker — мощный инструмент, который можно использовать в процессе разработки. Это может сделать запуск и переключение между проектами быстрым и легким, а также помочь гарантировать, что все будут в курсе используемых технологий.

Источник:

#Docker
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу