Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Запуск тестов с tox и Docker

Запуск тестов с tox и Docker

Александр Кошелев (Яндекс) @ MoscowPython Meetup 48
"Многие Python-библиотеки используют tox для тестирования на разных версиях интерпретатора и зависимостей. Зависимости можно сложить в отдельные виртуальные окружения. Но что делать с разными интерпретаторами? Не ставить же их все в систему. Конечно, можно воспользоваться Travis CI. Но что делать, если такая опция недоступна или если хочется прогнать тесты локально? Я расскажу, как решить эту задачу с помощью Docker".
Видео: http://www.moscowpython.ru/meetup/48/tox-docker-tests/

Moscow Python Meetup
PRO

August 21, 2017
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. View Slide

  2. Александр Кошелев
    Moscow Python Meetup #48, 21 августа 2017
    Запуск тестов с tox и
    Docker

    View Slide

  3. Задача, проблема и
    решение
    Запуск тестов с tox и Docker

    View Slide

  4. Задача
    4
    〉Запускать тесты для разных интерпретаторов и зависимостей
    〉Быстрый фидбек при разработке

    View Slide

  5. Проблема
    5
    〉Настроить среду запуска тестов
    〉Прогон тестов по ходу разработки

    View Slide

  6. Решение
    6
    Запускаем тесты в Docker, а внутри него tox
    › Docker даёт возможность сделать среду с несколькими
    интерпретаторами
    › tox позволяет тестировать разный набор зависимостей

    View Slide

  7. Готовый базовый Docker-oбраз
    7
    themattrix/tox от Matthew Tardiff
    › https://hub.docker.com/r/themattrix/tox/
    › https://github.com/themattrix/docker-tox
    〉Ubuntu 16.04 (Xenial Xerus)
    〉Содержит в себе все актуальные интерпретаторы:
    Python 2.6, 2.7, 3.3, 3.4, 3.5, 3.6, PyPy и PyPy3

    View Slide

  8. Пример:
    django_replicated
    Запуск тестов с tox и Docker

    View Slide

  9. View Slide

  10. Dockerfile
    FROM themattrix/tox
    MAINTAINER Alexander Koshelev

    View Slide

  11. Dockerfile из themattrix/tox
    FROM themattrix/tox-base
    MAINTAINER Matthew Tardiff
    ONBUILD COPY install-prereqs*.sh requirements*.txt tox.ini /app/
    ONBUILD ARG SKIP_TOX=false
    ONBUILD RUN bash -c " \
    if [ -f '/app/install-prereqs.sh' ]; then \
    bash /app/install-prereqs.sh; \
    fi && \
    if [ $SKIP_TOX == false ]; then \
    TOXBUILD=true tox; \
    fi"

    View Slide

  12. ONBUILD [INSTRUCTION]
    12
    〉Может содержать почти любую Dockerfile-инструкцию
    〉Выполняется при сборка образа-наследника
    〉Записывается в виде триггера в мета-информацию образа

    View Slide

  13. tox.ini
    [tox]
    envlist = {py27}-{django16,django18,django19},{py35}-{django18,django19},
    {pypy}-{django18,django19}
    skipsdist = {env:TOXBUILD:false}
    [testenv]
    sitepackages = False
    deps =
    pytest==2.8.7
    pytest-django==2.9.1
    mock==1.3.0
    django16: Django>=1.6,<1.7

    View Slide

  14. django18: Django>=1.8,<1.9
    django19: Django>=1.9,<1.10
    commands = {env:TOXBUILD:py.test tests}

    View Slide

  15. docker-compose.yaml
    tox:
    build: .
    volumes:
    - ".:/src:ro"

    View Slide

  16. Сборка образа
    $ docker-compose build tox
    Building tox
    Step 1 : FROM themattrix/tox
    # Executing 3 build triggers...
    Step 1 : COPY install-prereqs*.sh requirements*.txt tox.ini /app/
    Step 1 : ARG SKIP_TOX=false
    ---> Running in f9e38f0923f7
    Step 1 : RUN bash -c " if [ -f '/app/install-prereqs.sh' ]; then
    bash /app/install-prereqs.sh; fi && if [ $SKIP_TOX == false ]; then
    TOXBUILD=true tox; fi"
    ---> Running in 22d0be8c1efa
    py27-django16 create: /app/.tox/py27-django16

    View Slide

  17. py27-django16 installdeps: pytest==2.8.7, pytest-django==2.9.1, mock==1.3.0,
    Django>=1.6,<1.7
    py27-django16 installed:
    Django==1.6.11,funcsigs==1.0.2,mock==1.3.0,pbr==3.1.1,py==1.4.34,pytest==2.8.7
    ,pytest-django==2.9.1,six==1.10.0
    py27-django16 runtests: PYTHONHASHSEED='4047276611'
    py27-django16 runtests: commands[0] | true
    WARNING:test command found but not installed in testenv
    cmd: /bin/true
    env: /app/.tox/py27-django16
    Maybe you forgot to specify a dependency? See also the whitelist_externals
    envconfig setting.
    py27-django18 create: /app/.tox/py27-django18
    ...
    py27-django19 create: /app/.tox/py27-django19
    ...

    View Slide

  18. py35-django18 create: /app/.tox/py35-django18
    ...
    py35-django19 create: /app/.tox/py35-django19
    ...
    pypy-django18 create: /app/.tox/pypy-django18
    ...
    pypy-django19 create: /app/.tox/pypy-django19
    ...
    ___________________________________ summary ____________________________________
    py27-django16: commands succeeded
    py27-django18: commands succeeded
    py27-django19: commands succeeded
    py35-django18: commands succeeded
    py35-django19: commands succeeded
    pypy-django18: commands succeeded
    pypy-django19: commands succeeded
    congratulations :)

    View Slide

  19. ---> 1aa69980a30e
    Step 2 : MAINTAINER Alexander Koshelev
    ---> Running in 659b45a37d1f
    ---> 10065777bc77
    Successfully built 10065777bc77

    View Slide

  20. Запуск тестов
    $ docker-compose run tox
    GLOB sdist-make: /app/setup.py
    py27-django16 inst-nodeps: /app/.tox/dist/django_replicated-2.1.zip
    py27-django16 installed: Django==1.6.11,django-
    replicated==2.1,funcsigs==1.0.2,mock==1.3.0,pbr==3.1.1,py==1.4.34,pytest==2.8.
    7,pytest-django==2.9.1,six==1.10.0
    py27-django16 runtests: PYTHONHASHSEED='2897087153'
    py27-django16 runtests: commands[0] | py.test tests
    ========================== test session starts ============================
    platform linux2 -- Python 2.7.13, pytest-2.8.7, py-1.4.34, pluggy-0.3.1
    rootdir: /app, inifile: pytest.ini
    plugins: django-2.9.1
    collected 25 items

    View Slide

  21. tests/test_dbchecker.py .......
    tests/test_decorators.py .
    tests/test_middleware.py ............
    tests/test_router.py .....
    ========================== 25 passed in 0.77 seconds ======================
    ...
    __________________________________ summary ________________________________
    py27-django16: commands succeeded
    py27-django18: commands succeeded
    py27-django19: commands succeeded
    py35-django18: commands succeeded
    py35-django19: commands succeeded
    pypy-django18: commands succeeded
    ERROR: pypy-django19: commands failed

    View Slide

  22. Запуск теста отдельного окружения
    $ docker-compose run tox tox -e pypy-django19
    ...
    pypy-django19 runtests: commands[0] | py.test tests
    INTERNALERROR> Traceback (most recent call last):
    ...
    INTERNALERROR> from django.utils.module_loading import module_has_submodule
    INTERNALERROR> File "/app/.tox/pypy-django19/site-packages/django/utils/
    module_loading.py", line 67, in
    INTERNALERROR> from importlib.util import find_spec as importlib_find
    INTERNALERROR> ImportError: cannot import name 'find_spec'
    ERROR: InvocationError: '/app/.tox/pypy-django19/bin/py.test tests'
    ____________________________ summary ___________________________________
    ERROR: pypy-django19: commands failed

    View Slide

  23. Выводы
    Запуск тестов с tox и Docker

    View Slide

  24. Выводы
    24
    Плюсы
    › Удобство и быстрая настройка
    › Готовая среда со всеми интерпретаторами
    › Минимум кода
    Минусы
    › Более долгое выполнение тестов из-за старта контейнера
    › Нужно использовать Docker :-)

    View Slide

  25. Спасибо!
    Александр Кошелев
    Руководитель службы разработки
    [email protected]
    @alexkoshelev
    daevaorn

    View Slide