Skip to content

Tox

tox aims to automate and standardize testing in Python. It is part of a larger vision of easing the packaging, testing and release process of Python software.

Categories

Plugins

  • tox-wheel - A Tox plugin that builds and installs wheels instead of sdist.

What is tox?

tox is a generic virtualenv management and test command line tool you can use for:

  • checking that your package installs correctly with different Python versions and interpreters
  • running your tests in each of the environments, configuring your test tool of choice
  • acting as a frontend to Continuous Integration servers, greatly reducing boilerplate and merging CI and shell-based testing.

Configuration

환경변수 전달

[testenv:nosetests]
setenv =
    TEMPEST_CONFIG={env:TEMPEST_CONFIG:}
    TEMPEST_CONFIG_DIR={env:TEMPEST_CONFIG_DIR:}

with sphinx

[testenv:docs]
basepython=python
changedir=doc
deps=sphinx
commands=
    sphinx-build -W -b html -d {envtmpdir}/doctrees .  {envtmpdir}/html

또 다른 샘플:

[testenv:docs]
description = invoke sphinx-build to build the HTML docs
basepython = python3.7
deps = sphinx >= 1.7.5, < 2
commands = sphinx-build -d "{toxworkdir}/docs_doctree" doc "{toxworkdir}/docs_out" --color -W -bhtml {posargs}
           python -c 'import pathlib; print("documentation available under file://\{0\}".format(pathlib.Path(r"{toxworkdir}") / "docs_out" / "index.html"))'

recc example

# tox/pytest configuration.

# pytest-cov
# these values are generally used when running product code.
[run]
branch = True
data_file = .tox/coverage
source = test
source_pkgs = recc
omit =
    */__init__.py
    */__main__.py
    *recc/proto/api_pb2.py
    *recc/proto/api_pb2_grpc.py

# pytest-cov
# values common to many kinds of reporting.
[report]
exclude_lines =
    noqa
    nocov
    if __name__ == .__main__.:

# pytest-cov
# values particular to html reporting.
[html]
directory = .tox/_report/coverage

# pytest-cov
# values particular to xml reporting.
[xml]
output = .tox/_report/coverage.xml

# tox configuration
[tox]
minversion = 3.20.1
toxworkdir = .tox
distdir = {toxworkdir}/_dist
envlist =
    py37
    black
    wheel
    docs

[testenv]
setenv =
    RECC_TEST_HTTP_BIND={env:RECC_TEST_HTTP_BIND:0.0.0.0}
    RECC_TEST_HTTP_PORT={env:RECC_TEST_HTTP_PORT:10000}
    RECC_TEST_HTTP_TIMEOUT={env:RECC_TEST_HTTP_TIMEOUT:8.0}
    RECC_TEST_DB_HOST={env:RECC_TEST_DB_HOST:localhost}
    RECC_TEST_DB_PORT={env:RECC_TEST_DB_PORT:5432}
    RECC_TEST_DB_USER={env:RECC_TEST_DB_USER:recc}
    RECC_TEST_DB_PW={env:RECC_TEST_DB_PW:recc1234}
    RECC_TEST_DB_NAME={env:RECC_TEST_DB_NAME:testdb}
    RECC_TEST_DB_TYPE={env:RECC_TEST_DB_TYPE:postgres}
    RECC_TEST_ES_HOST={env:RECC_TEST_ES_HOST:localhost}
    RECC_TEST_ES_PORT={env:RECC_TEST_ES_PORT:9200}
    RECC_TEST_ES_INDEX={env:RECC_TEST_ES_INDEX:answer.test}
    RECC_TEST_CS_HOST={env:RECC_TEST_CS_HOST:localhost}
    RECC_TEST_CS_PORT={env:RECC_TEST_CS_PORT:6379}
    RECC_TEST_CS_PW={env:RECC_TEST_CS_PW:}
    RECC_TEST_CS_TYPE={env:RECC_TEST_CS_TYPE:redis}
deps =
    -rrequirements.setup.txt
    -rrequirements.main.txt
    -rrequirements.test.txt
install_command =
    python -m pip install --no-binary :all: {opts} {packages}
commands =
    python -c 'from recc.env.vars import print_test_variables; print_test_variables()'
    pytest -v --cov --cov-report=term-missing --cov-report=html --cov-report=xml --cov-config=tox.ini --flake8 --mypy

[testenv:black]
skip_install = true
deps =
    black
commands =
    black --check --diff --color --exclude '/(recc\/proto)/' recc

[testenv:wheel]
setenv =
    RECC_TEST_HTTP_BIND={env:RECC_TEST_HTTP_BIND:0.0.0.0}
    RECC_TEST_HTTP_PORT={env:RECC_TEST_HTTP_PORT:10000}
    RECC_TEST_HTTP_TIMEOUT={env:RECC_TEST_HTTP_TIMEOUT:8.0}
    RECC_TEST_DB_HOST={env:RECC_TEST_DB_HOST:localhost}
    RECC_TEST_DB_PORT={env:RECC_TEST_DB_PORT:5432}
    RECC_TEST_DB_USER={env:RECC_TEST_DB_USER:recc}
    RECC_TEST_DB_PW={env:RECC_TEST_DB_PW:recc1234}
    RECC_TEST_DB_NAME={env:RECC_TEST_DB_NAME:testdb}
    RECC_TEST_DB_TYPE={env:RECC_TEST_DB_TYPE:postgres}
    RECC_TEST_ES_HOST={env:RECC_TEST_ES_HOST:localhost}
    RECC_TEST_ES_PORT={env:RECC_TEST_ES_PORT:9200}
    RECC_TEST_ES_INDEX={env:RECC_TEST_ES_INDEX:answer.test}
    RECC_TEST_CS_HOST={env:RECC_TEST_CS_HOST:localhost}
    RECC_TEST_CS_PORT={env:RECC_TEST_CS_PORT:6379}
    RECC_TEST_CS_PW={env:RECC_TEST_CS_PW:}
    RECC_TEST_CS_TYPE={env:RECC_TEST_CS_TYPE:redis}
deps =
    -rrequirements.setup.txt
    -rrequirements.main.txt
    -rrequirements.test.txt
install_command =
    python -m pip install --only-binary wheel {opts} {packages}
commands =
    pytest

[testenv:docs]
deps =
    -rrequirements.setup.txt
    -rrequirements.main.txt
    -rrequirements.docs.txt
    # autodoc: failed to import module 'main' from module 'recc.core';
    # the following exception was raised: No module named 'google'
    protobuf
install_command =
    python -m pip install --only-binary wheel {opts} {packages}
commands=
    sphinx-build -W -b html -d "{envtmpdir}/doctrees" doc "{toxworkdir}/_docs/html"

Troubleshooting

setup.py에서 문서파일을 직접 읽은 경우 "No such file or directory" 에러 발생

setup.py 파일에서 문서파일을 직접 읽어, 추가할 경우 다음과 같은 에러가 발생될 수 있다.

ERROR: invocation failed (exit code 1), logfile: 
.tox/py36/log/py36-6.log
ERROR: actionid: py36
msg: installpkg
cmdargs: 
['.tox/py36/bin/pip', 'install', '-U', '--no-deps', '.tox/dist/package-0.1.0.zip']

Processing ./.tox/dist/package-0.1.0.zip
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "setup.py", line 10, in <module>
        version          = open(os.path.join(root, 'VERSION')).read().strip(),
    FileNotFoundError: [Errno 2] No such file or directory: 'VERSION'

이 경우 MANIFEST.in 파일을 추가해야 한다. 자세한 내용은 Setuptools#MANIFEST 항목 참조.

See also

Favorite site

Samples