python tox 任务自动化工具使用方法

  1. 基础例子
  2. 高级例子

tox 是对任务进行自动化的工具。

平常测试的时候,如果只是单一的测试,比如只有pytest,这样还好。
但是如果涉及到多python版本,多个测试内容,比如涉及 black、 flake8、 yamllint 这些,那么一次次的测试就会很麻烦了。

这时就要用到tox

tox依赖于项目文件夹中的tox.ini配置文件运行, tox config

基础例子

[tox]
isolated_build = True
envlist = py38,black,flake8,yamllint
skip_missing_interpreters = true
download = true

[testenv] passenv = TRAVIS TRAVIS_* whitelist_externals = poetry deps = poetry commands = poetry install python -m pytest {posargs}
[testenv:black] deps = black commands = black ./ --diff --check
[testenv:flake8] deps = flake8 commands = flake8 ./
[testenv:yamllint] deps = yamllint commands = yamllint ./
[flake8] # Line length managed by black ignore = E501 exclude = .git,.tox,.venv,venv

Action:

name: Check Templates

on: [push, pull_request]
jobs: check: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v2 - name: Setup Python uses: actions/setup-python@v2 with: python-version: '3.8' - name: Install Dependencies run: | python -m pip install --upgrade pip pip install poetry poetry install - name: Run Scripts run: | poetry run tox

高级例子

[tox]
envlist =
    fix_lint
    py310
    py39
    py38
    py37
    py36
    py35
    py27
    pypy3
    pypy
    coverage
    docs
    readme
isolated_build = true
skip_missing_interpreters = true
minversion = 3.12

[testenv] description = run the tests with pytest under {basepython} passenv = CURL_CA_BUNDLE PIP_CACHE_DIR PYTEST_* REQUESTS_CA_BUNDLE SSL_CERT_FILE setenv = COVERAGE_FILE = {env:COVERAGE_FILE:{toxworkdir}/.coverage.{envname}} PIP_DISABLE_PIP_VERSION_CHECK = 1 {py27,pypy}: PYTHONWARNINGS = ignore:DEPRECATION::pip._internal.cli.base_command extras = testing commands = pytest \ --cov "{envsitepackagesdir}/tox" \ --cov-config "{toxinidir}/tox.ini" \ --junitxml {toxworkdir}/junit.{envname}.xml \ {posargs:.}
[testenv:fix_lint] description = format the code base to adhere to our styles, and complain about what we cannot do automatically passenv = {[testenv]passenv} PRE_COMMIT_HOME PROGRAMDATA basepython = python3.10 skip_install = true deps = pre-commit>=2.16 extras = lint commands = pre-commit run --all-files --show-diff-on-failure {posargs} python -c 'import pathlib; print("hint: run \{\} install to add checks as pre-commit hook".format(pathlib.Path(r"{envdir}") / "bin" / "pre-commit"))'
[testenv:coverage] description = [run locally after tests]: combine coverage data and create report; generates a diff coverage against origin/master (can be changed by setting DIFF_AGAINST env var) passenv = {[testenv]passenv} DIFF_AGAINST setenv = COVERAGE_FILE = {toxworkdir}/.coverage skip_install = true deps = coverage>=6.2 diff-cover>=6.4 parallel_show_output = true commands = coverage combine coverage report -m coverage xml -o {toxworkdir}/coverage.xml coverage html -d {toxworkdir}/htmlcov diff-cover --compare-branch {env:DIFF_AGAINST:origin/master} {toxworkdir}/coverage.xml depends = py27, py35, py36, py37, py38, py39, py310, pypy, pypy3
[testenv:docs] description = invoke sphinx-build to build the HTML docs basepython = python3.10 extras = docs commands = sphinx-build -d "{toxworkdir}/docs_doctree" docs "{toxworkdir}/docs_out" --color -W --keep-going -n -bhtml {posargs} python -c 'import pathlib; print("documentation available under file://\{0\}".format(pathlib.Path(r"{toxworkdir}") / "docs_out" / "index.html"))'
[testenv:readme] description = check that the long description is valid basepython = python3.9 skip_install = true deps = twine>=3.7.1 extras = commands = pip wheel -w {envtmpdir}/build --no-deps . twine check {envtmpdir}/build/*
[testenv:exit_code] description = commands with several exit codes basepython = python3.10 skip_install = true commands = python3.10 -c "import sys; sys.exit(139)"
[testenv:X] description = print the positional arguments passed in with echo commands = echo {posargs}
[testenv:release] description = do a release, required posarg of the version number passenv = * basepython = python3.10 deps = gitpython>=3.1.24 packaging>=21.3 towncrier>=21.3 commands = python {toxinidir}/tasks/release.py --version {posargs}
[testenv:dev] description = dev environment with all deps at {envdir} usedevelop = true deps = {[testenv:release]deps} extras = docs testing commands = python -m pip list --format=columns python -c "print(r'{envpython}')"
[flake8] max-complexity = 22 max-line-length = 99 ignore = E203, W503, C901, E402, B011
[pep8] max-line-length = 99
[coverage:run] branch = true parallel = true
[coverage:report] skip_covered = True show_missing = True exclude_lines = \#\s*pragma: no cover ^\s*raise AssertionError\b ^\s*raise NotImplementedError\b ^\s*return NotImplemented\b ^\s*raise$ ^if __name__ == ['"]__main__['"]:$
[coverage:paths] source = src/tox */.tox/*/lib/python*/site-packages/tox */.tox/pypy*/site-packages/tox */.tox\*\Lib\site-packages\tox */src/tox *\src\tox
[pytest] addopts = -ra --showlocals --no-success-flaky-report testpaths = tests xfail_strict = True markers = git network
[isort] profile = black line_length = 99 known_first_party = tox,tests

Action:

name: check
on:
  push:
    branches: [master, 'test-me-*']
    tags:
  pull_request:
  schedule:
    - cron: "0 8 * * *"

concurrency: group: check-${{ github.ref }} cancel-in-progress: true
jobs: test: name: test ${{ matrix.py }} - ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: py: - "3.10" - "pypy-3.7-v7.3.7" # ahead to start it earlier because takes longer - "pypy-2.7-v7.3.6" # ahead to start it earlier because takes longer - "3.9" - "3.8" - "3.7" - "3.6" - "3.5" - "2.7" os: - ubuntu-20.04 - windows-2022 - macos-10.15
steps: - name: Setup python for tox uses: actions/setup-python@v2 with: python-version: "3.10" - name: Install tox run: python -m pip install tox - uses: actions/checkout@v2 with: fetch-depth: 0 - name: Setup python for test ${{ matrix.py }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.py }} - name: Pick environment to run run: | import codecs import os import platform import sys cpy = platform.python_implementation() == "CPython" base =("{}{}{}" if cpy else "{}{}").format("py" if cpy else "pypy", *sys.version_info[0:2]) env = "TOXENV={}\n".format(base) print("Picked:\n{}for{}".format(env, sys.version)) with codecs.open(os.environ["GITHUB_ENV"], "a", "utf-8") as file_handler: file_handler.write(env) shell: python - name: Setup test suite run: tox -vv --notest - name: Run test suite run: tox --skip-pkg-install env: PYTEST_ADDOPTS: "-vv --durations=20" CI_RUN: "yes" DIFF_AGAINST: HEAD - name: Rename coverage report file run: import os; import sys; os.rename(".tox/.coverage.{}".format(os.environ['TOXENV']), ".tox/.coverage.{}-{}.format(os.environ['TOXENV'], sys.platform)") shell: python - name: Upload coverage data uses: actions/upload-artifact@v2 with: name: coverage-data path: ".tox/.coverage.*"
coverage: name: Combine coverage runs-on: ubuntu-latest needs: test steps: - uses: actions/checkout@v2 with: fetch-depth: 0 - uses: actions/setup-python@v2 with: python-version: "3.10" - name: Install tox run: python -m pip install tox - name: Setup coverage tool run: tox -e coverage --notest - name: Install package builder run: python -m pip install build - name: Build package run: pyproject-build --wheel . - name: Download coverage data uses: actions/download-artifact@v2 with: name: coverage-data path: .tox - name: Combine and report coverage run: tox -e coverage - name: Upload HTML report uses: actions/upload-artifact@v2 with: name: html-report path: .tox/htmlcov
check: name: ${{ matrix.tox_env }} - ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: - ubuntu-20.04 - windows-2022 tox_env: - dev - docs - readme exclude: - { os: windows-2022, tox_env: readme } steps: - uses: actions/checkout@v2 with: fetch-depth: 0 - name: Setup Python "3.10" uses: actions/setup-python@v2 with: python-version: "3.10" - name: Install tox run: python -m pip install tox - name: Setup test suite run: tox -vv --notest -e ${{ matrix.tox_env }} - name: Run test suite run: tox --skip-pkg-install -e ${{ matrix.tox_env }}
publish: if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') needs: [ check, coverage ] runs-on: ubuntu-20.04 steps: - name: Setup python to build package uses: actions/setup-python@v2 with: python-version: "3.10" - name: Install build run: python -m pip install build - uses: actions/checkout@v2 with: fetch-depth: 0 - name: Build sdist and wheel run: python -m build -s -w . -o dist - name: Publish to PyPi uses: pypa/gh-action-pypi-publish@master with: skip_existing: true user: __token__ password: ${{ secrets.pypi_password }}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 365433079@qq.com