Тестирование монорепозитории в Docker контейнере

—

от автора

Хочу поделиться своим опытом реализации тестирования в монорепозитории, без затрагивания написания самих тестов …

Допустим есть репозиторий с несколькими приложениями и папкой common, в которой находятся функционал, который используется в этих приложениях 

. ├── apps │   ├── app1 │   │   ├── cfg │   │   │   └── __init__.py │   │   ├── core │   │   │   └── __init__.py │   │   ├── docker-compose.yml │   │   ├── manage.py │   │   └── tests │   │       └── __init__.py │   ├── app2 │   └── app3 ├── common │   └── __init__.py ├── requirements-dev.txt └── requirements.txt 

При реализации тестов хотелось реализовать следующие задачи:

  • при реализации новых фич в приложениях, запускать тестирование приложений на нескольких версиях python

  • при добавлении нового функционала в common запускать тестирование всех приложений

  • при малейшем изменении в requirements.txt или requirements-dev.txt пересобирать окружение и так же запускать тестирование всех приложений

Эти задачи можно реализовать с помощью tox, добавляем файл ./tox.ini (актуально для tox==3.27.1):

[main] current_python_env_dir = {toxworkdir}{/}current_python_env_dir next_python_env_dir = {toxworkdir}{/}next_python_env_dir report_temp_dir = test{/}temp{/} pytest_flags = --tb=no  [tox] skipsdist = True envlist =     {next_python, current_python}-{app1, app2, app3}  [testenv] recreate = False sitepackages = False passenv =     FORCE_COLOR commands =     next_python-app1: {env:TOXBUILD:py.test apps{/}app1{/}tests --junitxml={[main]report_temp_dir}test_{envname}.xml {[main]pytest_flags}}     current_python-app1: {env:TOXBUILD:py.test apps{/}app1{/}tests{/}smoke --junitxml={[main]report_temp_dir}test_{envname}.xml {[main]pytest_flags}}      next_python-app2: {env:TOXBUILD:py.test apps{/}app2{/}tests --junitxml={[main]report_temp_dir}test_{envname}.xml {[main]pytest_flags}}     current_python-app2: {env:TOXBUILD:py.test apps{/}app2{/}tests{/}smoke --junitxml={[main]report_temp_dir}test_{envname}.xml {[main]pytest_flags}}      next_python-app3: {env:TOXBUILD:py.test apps{/}app3{/}tests --junitxml={[main]report_temp_dir}test_{envname}.xml {[main]pytest_flags}}     current_python-app3: {env:TOXBUILD:py.test apps{/}app3{/}tests{/}smoke --junitxml={[main]report_temp_dir}test_{envname}.xml {[main]pytest_flags}}  [testenv:next_python-{app1, app2, app3}] basepython = python3.7 envdir = {[main]next_python_env_dir} deps =     -Urrequirements-dev.txt  [testenv:current_python-{app1, app2, app3}] basepython = python3.8 envdir = {[main]next_python_env_dir} deps =     -Urrequirements-dev.txt

Добавляем докерфайл образа в котором у нас будут проходить тестирование ./test/test_tox.Dockerfile:

FROM python3.7  WORKDIR /tox_workdir COPY requirements*.txt tox.ini /tox_workdir/  #================================================================================== # Ставим необходимые зависимости #================================================================================== RUN apt-get update && apt-get -y --no-install-recommends install \     cabextract \     curl \     ......     && apt-get clean  #================================================================================== # Добавляем пользователя webui и далее делаем все через него #================================================================================== RUN addgroup --gid 1000 --system web && adduser --system --gid 1000 --uid 1000 web RUN chown -R web /tox_workdir USER web  #================================================================================== # Ставим pyenv, через него устанавливаем необходимые версии python #  и прописываем пути #================================================================================== RUN curl https://pyenv.run | bash \     && echo 'export PYENV_ROOT="/home/web/.pyenv"' >> ~/.bashrc \     && echo 'export PATH="/home/web/.local/bin:$PATH"' >> ~/.bashrc \     && echo 'export PATH="$PYENV_ROOT/shims:$PATH"' >> ~/.bashrc \ && echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc  RUN . ~/.bashrc && pyenv install 3.8 RUN . ~/.bashrc && pyenv global 3.8 RUN . ~/.bashrc && pip3.8 install --upgrade cython #================================================================================== # Установка tox и окружений #==================================================================================  RUN pip3 install tox==3.27.1 && pip3 install --upgrade cython RUN . ~/.bashrc && bash -c "export TOXBUILD=true && tox" 

добавляем скрипт для сборки этого образа ./test/build.sh:

#!/bin/bash docker build -f test_tox.Dockerfile -t test_tox:latest .

таким образом, после сборки этого образа у нас в контейнере будут установлены 2 версии python и 2 папки с окружениями (с разными версиями python) в которых будут установлены все пакеты из requirements-dev.txt При запуске тестирования из контейнера, окружения пересобираться не будут

Далее для запуска тестов создадим файл ./test/docker-compose.yaml :

version: "2"  services:   db:     image: postgres     environment:       - POSTGRES_USER=root       - POSTGRES_HOST_AUTH_METHOD=trust     volumes:       # инит скрипт для создания баз данных для приложений, можно положить       # рядом, в ./test/create_databases.sql       - ./create_databases.sql:/docker-entrypoint-initdb.d/init.sql   cache:     image: memcached:alpine   test_tox:     image: test_tox     volumes:       - ../:/test       # это нужно для того, чтобы локальные конфиги заменялись конфигами,       # которые подойдут для запуска в контейнере, можно так же положить        # рядом в ./test/container_cfg       - ./container_cfg:/test/apps/app1/cfg       - ./container_cfg:/test/apps/app2/cfg       - ./container_cfg:/test/apps/app3/cfg volumes:   media: 

файл ./test/create_databases.sql :

CREATE DATABASE app1_test; CREATE DATABASE app2_test; CREATE DATABASE app3_test;

теперь можно запускать тестирование через docker-compose, для удобства создадим файл ./test/Makefile :

# You can set these variables from the command line. TOX_WORK_DIR=/tox_workdir/.tox APP1_ENV=-e current_python-app1,next_python-app1 APP2_ENV=-e current_python-app2,next_python-app2 APP3_ENV=-e current_python-app3,next_python-app3 ALL_ENVS=$(APP1_ENV) $(APP2_ENV) $(APP3_ENV)  define run-test docker-compose rm --all docker-compose up -d db docker-compose up -d cache docker-compose run --rm test_tox /bin/bash -c ". ~/.bashrc && cd /test/ && tox $1 --workdir $(TOX_WORK_DIR) -q --result-json .tox-result.json" || : docker-compose down docker-compose rm --all endef  build: ./build_local.sh  app1_test: $(call run-test, $(APP1_ENV))  app2_test: $(call run-test, $(APP2_ENV))  app3_test: $(call run-test, $(APP3_ENV))  tests: $(call run-test, $(ALL_ENVS))  all: build tests  .DEFAULT_GOAL := all 

через Makefile мы можем пересобрать тестовый контейнер и запустить тестирование интересующих нас приложений, например:

cd test make build make app1_test make tests

Дерево проекта выглядит следующим образом:

. ├── apps │   ├── app1 │   │   ├── cfg │   │   │   └── __init__.py │   │   ├── core │   │   │   └── __init__.py │   │   ├── docker-compose.yml │   │   ├── manage.py │   │   └── tests │   │       └── __init__.py │   ├── app2 │   └── app3 ├── common │   └── __init__.py ├── requirements-dev.txt ├── requirements.txt └── test     ├── Makefile     ├── build.sh     ├── container_cfg     │   └── __init__.py     ├── create_databases.sql     ├── docker-compose.yaml     └── test_tox.Dockerfile

Плюсы такой реализации:

  • Все тестирование выполняется в отдельном контейнере, который уже содержит все необходимое для запуска тестов

  • Можно очень быстро проверить работоспособность приложений, при изменении common, не переходя в папки тестов отдельных подсистем

  • Тестирование приложений с несколькими окружениями (так же можно тестировать с разными версиями определенных пакетов)

  • Наработки из папки ./test/ можно легко прикрутить в CI/CD при запуске тестирования в пайплайне

Минусы:

  • Костыльное вкорячивание 2 версии python в один контейнер

  • Долгая пересборка контейнера за счет установки второй версии python

  • Невозможность запуска тестирования с дополнительными флагами (например —pdb)

P.S. При написании статьи постарался максимально обезличить проект, так что возможны некоторые неточности, главное было донести суть.


ссылка на оригинал статьи https://habr.com/ru/articles/807549/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *