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
환경변수 전달
- tox configuration specification # setenv
- Stackoverflow - How to import all the environment variables in tox
[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
- Welcome to the tox automation project — tox 3.20.2.dev22 documentation
- 파이썬 Tox · Hyun 블로그
- pyenv와 tox를 이용하여 여러 환경에서 테스트하기