Command line driven CI frontend and development task automation tool.

Overview

PyPI Supported Python versions Azure Pipelines build status Documentation status Code style: black Downloads

tox logo

tox automation project

Command line driven CI frontend and development task automation tool

At its core tox provides a convenient way to run arbitrary commands in isolated environments to serve as a single entry point for build, test and release activities.

tox is highly configurable and pluggable.

Example: run tests with Python 3.7 and Python 3.8

tox is mainly used as a command line tool and needs a tox.ini or a tool.tox section in pyproject.toml containing the configuration.

To test a simple project that has some tests, here is an example with a tox.ini in the root of the project:

[tox]
envlist = py37,py38

[testenv]
deps = pytest
commands = pytest
$ tox

[lots of output from what tox does]
[lots of output from commands that were run]

__________________ summary _________________
  py37: commands succeeded
  py38: commands succeeded
  congratulations :)

tox created two testenvs - one based on Python3.7 and one based on Python3.8, it installed pytest in them and ran the tests. The report at the end summarizes which testenvs have failed and which have succeeded.

Note: To learn more about what you can do with tox, have a look at the collection of examples in the documentation or existing projects using tox.

How it works

tox creates virtual environments for all configured so called testenvs, it then installs the project and other necessary dependencies and runs the configured set of commands. See system overview for more details.

tox flow

tox can be used for ...

  • creating development environments
  • running static code analysis and test tools
  • automating package builds
  • running tests against the package build by tox
  • checking that packages install correctly with different Python versions/interpreters
  • unifying Continuous Integration and command line based testing
  • building and deploying project documentation
  • releasing a package to PyPI or any other platform
  • limit: your imagination

Documentation

Documentation for tox can be found at Read The Docs.

Communication and questions

For the fastest and interactive feedback please join our Discord server. If you have questions or suggestions you can first check if they have already been answered or discussed on our issue tracker. On Stack Overflow (tagged with tox).

Contributing

Contributions are welcome. See contributing and our Contributor Covenant Code of Conduct.

Currently the code and the issues are hosted on Github.

The project is licensed under MIT.

Comments
  • virtualenv is not recreated when deps change if '-r' is used

    virtualenv is not recreated when deps change if '-r' is used

    • Bitbucket: https://bitbucket.org/hpk42/tox/issue/149
    • Originally reported by: @gavrie
    • Originally created at: 2014-01-28T15:36:07.365

    In my tox.ini, I have the following deps:

    deps = -rpackaging/requirements.txt
    

    Normally, when deps change, the virtualenv is recreated by tox. However, when the contents of requirements.txt change, tox does not notice this and the environment is reused.

    A workaround would be to list the deps directly in tox.ini, but that would require duplicating the contents of the existing requirements.txt that is used by other tools.

    bug:normal area:testenv-creation level:hard fixed-by-tox4 
    opened by pytoxbot 96
  • automate release

    automate release

    We should automate the release process via a role account. When a maintainer tags a commit with a version, the CI should kick in and if all tests succeed automatically release the package.

    type:internal type:organization needs:work level:medium help:wanted 
    opened by gaborbernat 53
  • show all defined enviroments for listenv, not just what's in envlist

    show all defined enviroments for listenv, not just what's in envlist

    fixes #271

    first list the automatically running environments, all other environments are printed in alphabetical order (attached to the end)

    If we want to differentiate between them I would recommend having some kind of separator, e.g:

    py27-windows run py.test on Python 2.7 on Windows platform
    py27-linux   run py.test on Python 2.7 on Linux platform
    py36-windows run py.test on Python 3.6 on Windows platform
    py36-linux   run py.test on Python 3.6 on Linux platform
    ------------------------- other env ----------------------
    notincluded  something else
    
    opened by gaborbernat 46
  • Preparing 3.0 release

    Preparing 3.0 release

    Looking at what is going on here, I think it is high time to get a new release out :)

    It would be great if we could coordinate here what needs to be done, before we can cut the next release.

    The one thing that is on my radar is the question of the logo and the docs. There were several people that think that the middle part of the logo looks a bit too much like the male gender sign. Maybe we can find a solution for that, before the next release?

    What else needs to be done before we can make a first rc?

    I'll read my way into what happened over the last months and update https://github.com/tox-dev/tox/projects/7

    type:organization 
    opened by obestwalter 39
  • Allow parametrization of any testenv

    Allow parametrization of any testenv

    • Bitbucket: https://bitbucket.org/hpk42/tox/issue/189
    • Originally reported by: @DasIch
    • Originally created at: 2014-09-23T18:50:25.391

    As discussed on IRC with @hpk42, I would like the ability to parametrize any testenv and not just the normal [testenv] one. One use case I have is a testenv for testing doctests on different Python interpreters, so basically I would like the following to work:

    #!ini
    [tox]
    envlist = docs-examples-{py27,py33,py34}
    
    [testenv:docs-examples]
    changedir = docs
    deps = sphinx
    commands = sphinx-build -W -b doctest -d {envtmpdir}/doctrees . {envtmpdir}/doctest
    

    /cc @suor

    feature:change area:configuration help:wanted 
    opened by pytoxbot 38
  • Allow `setup.cfg` as an alternative configuration file

    Allow `setup.cfg` as an alternative configuration file

    • Bitbucket: https://bitbucket.org/hpk42/tox/issue/297
    • Originally reported by: @bittner
    • Originally created at: 2015-12-16T17:01:01.612

    (This issue comes from a comment in issue #185.) I'd love to see the tox configuration living in setup.cfg too in general, as an alternative.

    It would allow a more elegant Python package configuration for developers: You could put configuration of all your tools into a single file. The ini-style allows for separate sections. I've described some considerations in a comment on issue 13.

    A few projects already look into setup.cfg. flake8, behave, py.test, among others. Pylint is a prominent exception (its maintainer considers this idea harmful; declined PR; discussion).

    opened by pytoxbot 36
  • No module named `pip`

    No module named `pip`

    tox was installed inside a virtual environement created from python 3.8.0, compile from source.

    I am having the error on py36 and py37 only, so here is the tox -rvv from py36 inside my 3.8 virtual env

    (potodo) ➜  potodo git:(json) tox -rvv -e py36
    using tox.ini: /Users/seluj78/Projects/potodo/tox.ini (pid 80569)
      removing /Users/seluj78/Projects/potodo/.tox/log
    using tox-3.14.2 from /Users/seluj78/Projects/potodo/venv/lib/python3.8/site-packages/tox/__init__.py (pid 80569)
    GLOB start: packaging 
    GLOB sdist-make: /Users/seluj78/Projects/potodo/setup.py
      removing /Users/seluj78/Projects/potodo/.tox/dist
    [80576] /Users/seluj78/Projects/potodo$ /Users/seluj78/Projects/potodo/venv/bin/python3.8 setup.py sdist --formats=zip --dist-dir .tox/dist >.tox/log/GLOB-0.log
    running sdist
    running egg_info
    writing potodo.egg-info/PKG-INFO
    writing dependency_links to potodo.egg-info/dependency_links.txt
    writing entry points to potodo.egg-info/entry_points.txt
    writing requirements to potodo.egg-info/requires.txt
    writing top-level names to potodo.egg-info/top_level.txt
    reading manifest file 'potodo.egg-info/SOURCES.txt'
    writing manifest file 'potodo.egg-info/SOURCES.txt'
    running check
    creating potodo-0.4.0
    creating potodo-0.4.0/potodo
    creating potodo-0.4.0/potodo.egg-info
    copying files to potodo-0.4.0...
    copying README.md -> potodo-0.4.0
    copying setup.py -> potodo-0.4.0
    copying potodo/__init__.py -> potodo-0.4.0/potodo
    copying potodo/__main__.py -> potodo-0.4.0/potodo
    copying potodo/_github.py -> potodo-0.4.0/potodo
    copying potodo/_po_file.py -> potodo-0.4.0/potodo
    copying potodo/potodo.py -> potodo-0.4.0/potodo
    copying potodo.egg-info/PKG-INFO -> potodo-0.4.0/potodo.egg-info
    copying potodo.egg-info/SOURCES.txt -> potodo-0.4.0/potodo.egg-info
    copying potodo.egg-info/dependency_links.txt -> potodo-0.4.0/potodo.egg-info
    copying potodo.egg-info/entry_points.txt -> potodo-0.4.0/potodo.egg-info
    copying potodo.egg-info/not-zip-safe -> potodo-0.4.0/potodo.egg-info
    copying potodo.egg-info/requires.txt -> potodo-0.4.0/potodo.egg-info
    copying potodo.egg-info/top_level.txt -> potodo-0.4.0/potodo.egg-info
    Writing potodo-0.4.0/setup.cfg
    creating '.tox/dist/potodo-0.4.0.zip' and adding 'potodo-0.4.0' to it
    adding 'potodo-0.4.0'
    adding 'potodo-0.4.0/potodo.egg-info'
    adding 'potodo-0.4.0/potodo'
    adding 'potodo-0.4.0/PKG-INFO'
    adding 'potodo-0.4.0/README.md'
    adding 'potodo-0.4.0/setup.py'
    adding 'potodo-0.4.0/setup.cfg'
    adding 'potodo-0.4.0/potodo.egg-info/PKG-INFO'
    adding 'potodo-0.4.0/potodo.egg-info/not-zip-safe'
    adding 'potodo-0.4.0/potodo.egg-info/SOURCES.txt'
    adding 'potodo-0.4.0/potodo.egg-info/entry_points.txt'
    adding 'potodo-0.4.0/potodo.egg-info/requires.txt'
    adding 'potodo-0.4.0/potodo.egg-info/top_level.txt'
    adding 'potodo-0.4.0/potodo.egg-info/dependency_links.txt'
    adding 'potodo-0.4.0/potodo/potodo.py'
    adding 'potodo-0.4.0/potodo/_github.py'
    adding 'potodo-0.4.0/potodo/__init__.py'
    adding 'potodo-0.4.0/potodo/_po_file.py'
    adding 'potodo-0.4.0/potodo/__main__.py'
    removing 'potodo-0.4.0' (and everything under it)
    
    GLOB finish: packaging  after 0.36 seconds
    copying new sdistfile to '/Users/seluj78/.tox/distshare/potodo-0.4.0.zip'
    package .tmp/package/1/potodo-0.4.0.zip links to dist/potodo-0.4.0.zip (/Users/seluj78/Projects/potodo/.tox)
    py36 start: getenv /Users/seluj78/Projects/potodo/.tox/py36
    py36 cannot reuse: -r flag
    py36 recreate: /Users/seluj78/Projects/potodo/.tox/py36
    python3.6 (/usr/local/bin/python3.6) is {'executable': '/usr/local/bin/python3.6', 'name': 'python', 'version_info': [3, 6, 8, 'final', 0], 'version': '3.6.8 (v3.6.8:3c6b436a57, Dec 24 2018, 02:04:31) \n[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]', 'is_64': True, 'sysplatform': 'darwin'}
    py36 uses /usr/local/bin/python3.6
      removing /Users/seluj78/Projects/potodo/.tox/py36
    setting PATH=/Users/seluj78/Projects/potodo/.tox/py36/bin:/Users/seluj78/Projects/potodo/venv/bin:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/usr/local/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Library/Apple/bin:/opt/X11/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Wireshark.app/Contents/MacOS:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin
    [80579] /Users/seluj78/Projects/potodo/.tox$ /Users/seluj78/Projects/potodo/venv/bin/python3.8 -m virtualenv --no-download --python /usr/local/bin/python3.6 py36
    Running virtualenv with interpreter /usr/local/bin/python3.6
    Already using interpreter /usr/local/bin/python3.6
    Using base prefix '/Library/Frameworks/Python.framework/Versions/3.6'
    New python executable in /Users/seluj78/Projects/potodo/.tox/py36/bin/python3.6
    Also creating executable in /Users/seluj78/Projects/potodo/.tox/py36/bin/python
    Installing setuptools, pip, wheel...
    done.
    py36 installdeps: pytest
    setting PATH=/Users/seluj78/Projects/potodo/.tox/py36/bin:/Users/seluj78/Projects/potodo/venv/bin:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/usr/local/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Library/Apple/bin:/opt/X11/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Wireshark.app/Contents/MacOS:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin
    [80586] /Users/seluj78/Projects/potodo$ /Users/seluj78/Projects/potodo/.tox/py36/bin/python -m pip install pytest
    Looking in indexes: https://pypi.python.org/simple, https://pypi.apple.com/simple
    Collecting pytest
      Using cached https://files.pythonhosted.org/packages/19/cf/711f1d887cb92c5155c9a1eb338f1b5d2411b50e4492a3b20e4a188a22b2/pytest-5.3.2-py3-none-any.whl
    Collecting packaging
      Using cached https://files.pythonhosted.org/packages/cf/94/9672c2d4b126e74c4496c6b3c58a8b51d6419267be9e70660ba23374c875/packaging-19.2-py2.py3-none-any.whl
    Collecting more-itertools>=4.0.0
      Using cached https://files.pythonhosted.org/packages/68/03/0604cec1ea13c9f063dd50f900d1a36160334dd3cfb01fd0e638f61b46ba/more_itertools-8.0.2-py3-none-any.whl
    Collecting attrs>=17.4.0
      Using cached https://files.pythonhosted.org/packages/a2/db/4313ab3be961f7a763066401fb77f7748373b6094076ae2bda2806988af6/attrs-19.3.0-py2.py3-none-any.whl
    Collecting pluggy<1.0,>=0.12
      Using cached https://files.pythonhosted.org/packages/a0/28/85c7aa31b80d150b772fbe4a229487bc6644da9ccb7e427dd8cc60cb8a62/pluggy-0.13.1-py2.py3-none-any.whl
    Collecting py>=1.5.0
      Using cached https://files.pythonhosted.org/packages/76/bc/394ad449851729244a97857ee14d7cba61ddb268dce3db538ba2f2ba1f0f/py-1.8.0-py2.py3-none-any.whl
    Collecting wcwidth
      Using cached https://files.pythonhosted.org/packages/7e/9f/526a6947247599b084ee5232e4f9190a38f398d7300d866af3ab571a5bfe/wcwidth-0.1.7-py2.py3-none-any.whl
    Collecting importlib-metadata>=0.12; python_version < "3.8"
      Using cached https://files.pythonhosted.org/packages/e9/71/1a1e0ed0981bb6a67bce55a210f168126b7ebd2065958673797ea66489ca/importlib_metadata-1.3.0-py2.py3-none-any.whl
    Collecting six
      Using cached https://files.pythonhosted.org/packages/65/26/32b8464df2a97e6dd1b656ed26b2c194606c16fe163c695a992b36c11cdf/six-1.13.0-py2.py3-none-any.whl
    Collecting pyparsing>=2.0.2
      Using cached https://files.pythonhosted.org/packages/c0/0c/fc2e007d9a992d997f04a80125b0f183da7fb554f1de701bbb70a8e7d479/pyparsing-2.4.5-py2.py3-none-any.whl
    Collecting zipp>=0.5
      Using cached https://files.pythonhosted.org/packages/74/3d/1ee25a26411ba0401b43c6376d2316a71addcc72ef8690b101b4ea56d76a/zipp-0.6.0-py2.py3-none-any.whl
    Installing collected packages: six, pyparsing, packaging, more-itertools, attrs, zipp, importlib-metadata, pluggy, py, wcwidth, pytest
    Successfully installed attrs-19.3.0 importlib-metadata-1.3.0 more-itertools-8.0.2 packaging-19.2 pluggy-0.13.1 py-1.8.0 pyparsing-2.4.5 pytest-5.3.2 six-1.13.0 wcwidth-0.1.7 zipp-0.6.0
    py36 finish: getenv /Users/seluj78/Projects/potodo/.tox/py36 after 6.32 seconds
    py36 start: installpkg /Users/seluj78/Projects/potodo/.tox/.tmp/package/1/potodo-0.4.0.zip
    py36 inst: /Users/seluj78/Projects/potodo/.tox/.tmp/package/1/potodo-0.4.0.zip
    write config to /Users/seluj78/Projects/potodo/.tox/py36/.tox-config1 as '26aeefd96897788c77f488126e45e6a6063c079af252e857b7045abd67bd3f75 /usr/local/bin/python3.6\n3.14.2 0 0 0\n00000000000000000000000000000000 pytest'
    setting PATH=/Users/seluj78/Projects/potodo/.tox/py36/bin:/Users/seluj78/Projects/potodo/venv/bin:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/usr/local/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Library/Apple/bin:/opt/X11/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Wireshark.app/Contents/MacOS:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin
    [80590] /Users/seluj78/Projects/potodo$ /Users/seluj78/Projects/potodo/.tox/py36/bin/python -m pip install --exists-action w .tox/.tmp/package/1/potodo-0.4.0.zip
    Looking in indexes: https://pypi.python.org/simple, https://pypi.apple.com/simple
    Processing ./.tox/.tmp/package/1/potodo-0.4.0.zip
    Collecting polib
      Using cached https://files.pythonhosted.org/packages/30/a2/e407c3b00cace3d7fc8df14d364deeecfeb96044e1a317de583bc26eae58/polib-1.1.0-py2.py3-none-any.whl
    Collecting requests
      Using cached https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl
    Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1
      Using cached https://files.pythonhosted.org/packages/b4/40/a9837291310ee1ccc242ceb6ebfd9eb21539649f193a7c8c86ba15b98539/urllib3-1.25.7-py2.py3-none-any.whl
    Collecting idna<2.9,>=2.5
      Using cached https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl
    Collecting chardet<3.1.0,>=3.0.2
      Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl
    Collecting certifi>=2017.4.17
      Using cached https://files.pythonhosted.org/packages/b9/63/df50cac98ea0d5b006c55a399c3bf1db9da7b5a24de7890bc9cfd5dd9e99/certifi-2019.11.28-py2.py3-none-any.whl
    Building wheels for collected packages: potodo
      Building wheel for potodo (setup.py) ... done
      Created wheel for potodo: filename=potodo-0.4.0-cp36-none-any.whl size=7609 sha256=0a1aac14e1a4bd4c40c13728a1f030e307b22728438fec7e4c756f6424f19b88
      Stored in directory: /Users/seluj78/Library/Caches/pip/wheels/c0/cd/ee/1dad18569e006002404c6c1a3939b65ec979a7c4b99c80e46c
    Successfully built potodo
    Installing collected packages: polib, urllib3, idna, chardet, certifi, requests, potodo
      Found existing installation: potodo 0.4.0
        Not uninstalling potodo at /Users/seluj78/Projects/potodo, outside environment /Users/seluj78/Projects/potodo/.tox/py36/bin/..
        Can't uninstall 'potodo'. No files were found to uninstall.
    Successfully installed certifi-2019.11.28 chardet-3.0.4 idna-2.8 polib-1.1.0 potodo-0.4.0 requests-2.22.0 urllib3-1.25.7
    py36 finish: installpkg /Users/seluj78/Projects/potodo/.tox/.tmp/package/1/potodo-0.4.0.zip after 2.63 seconds
    py36 start: envreport 
    setting PATH=/Users/seluj78/Projects/potodo/.tox/py36/bin:/Users/seluj78/Projects/potodo/venv/bin:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/usr/local/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Library/Apple/bin:/opt/X11/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Wireshark.app/Contents/MacOS:/usr/local/opt/[email protected]/bin:/Users/seluj78/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/Library/Frameworks/Python.framework/Versions/3.8/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin:/usr/local/opt/gettext/bin:/Users/seluj78/.local/bin
    [80599] /Users/seluj78/Projects/potodo$ /Users/seluj78/Projects/potodo/.tox/py36/bin/python -m pip freeze >.tox/py36/log/py36-0.log
    ERROR: invocation failed (exit code 1), logfile: /Users/seluj78/Projects/potodo/.tox/py36/log/py36-0.log
    ============================================================================================================== log start ==============================================================================================================
    /Users/seluj78/Projects/potodo/venv/bin/python3.8: No module named pip
    
    =============================================================================================================== log end ===============================================================================================================
    _______________________________________________________________________________________________________________ summary _______________________________________________________________________________________________________________
    ERROR:   py36: InvocationError for command /Users/seluj78/Projects/potodo/.tox/py36/bin/python -m pip freeze (exited with code 1)
    cleanup /Users/seluj78/Projects/potodo/.tox/.tmp/package/1/potodo-0.4.0.zip
    

    I could not find any logical explanation. All my python installations have pip installed, as well as tox's...

    bug:normal 
    opened by Seluj78 34
  • Do not assume all python installs come with virtualenv

    Do not assume all python installs come with virtualenv

    Currently, tox runs virtualenv via python -m virtualenv .... However, that assumes that virtualenv is installed with the python invoked, that is not always the case (for example: pythons installed via pyenv don't come with virutalenv). A trivial solution for this is to employ the same technique as virtualenv itself uses: invoke virtualenv via python path/to/virtualenv.py ...

    This change allows to package tox via tools like pex, and have a working standalone tox that does not assume all pythons come with virtualenv.

    Issue: https://github.com/tox-dev/tox/issues/928

    opened by zsimic 34
  • posargs configerror

    posargs configerror

    • Bitbucket: https://bitbucket.org/hpk42/tox/issue/150
    • Originally reported by: ehopemorley
    • Originally created at: 2014-01-31T15:42:29.801

    With tox version 1.7.0 I get the following error:

    tox.ConfigError: ConfigError: substitution key 'posargs' not found
    

    Which appears to be caused by the following line in my tox.ini:

    commands = python setup.py test --slowest --testr-args='{posargs}'

    This worked fine with the previous version of tox i.e. 1.6.1

    opened by pytoxbot 34
  • tox needs a logo

    tox needs a logo

    @hpk42 got the ball rolling last year and it is time that we bring this to a conclusion, so that we can get rid if that silly generic logo for our org :)

    I link to the relevant discussions on the mailing list and invite everyone interested in this to join into the discussion on the mailing list.

    Jad Sarout created some drafts and allowed us to build on them if we like, he has no time anymore to follow up on it himself. The discussion is here.

    Here are his drafts:

    img_20161030_193210

    Thank you Jad!

    Discussion round 2 is here. The drafts are by Gero (sorry do not have his full name yet) and are in this PDF: tox-2017-06-01.pdf (note: the writing would need to be adapted to spelling tox all lowercase).

    I also have an idea for a logo that is based on transpiling the flute from the pytest logo - for reference: pytest1 And here is my horrible sketch. If someone who is into graphics (Gero?) would want to create something concrete from that I'd be thrilled :)

    img_0930

    I also really liked the idea from Laura Creighton about that Jack in a box, but there is no draft for this:

    The first idea I had was for the 'box' to be a jack-in-the-box. And give the 'Jack' bouncing out of it a goat's head. Colour the box and dress the Jack the same cheerful colours that pytest uses.

    [relevant context]: tox is short for "testing out of the box" :)

    needs:discussion type:organization 
    opened by obestwalter 33
  • Spring cleaning

    Spring cleaning

    see commit messages for details. This might grow a bit more over the next days, as I have some time at my hands and want to tidy up the code base a bit.

    closes #797 closes #798 closes #799 closes #800 closes #801 closes #754

    Also (no extra issues for that):

    • removed all experimental markers from docstrings (most of them have been there for a few years already). If they turn out wrong/bad, we just have to deprecate them and remove them in a major release
    • hookimpl is instantiated twice - mark one of them as deprecated and get rid of it later
    • moved hookimpl to __init__.py - having a hookimpl object in the hookspecs module is unnecessary and confusing. Access to hookimpl should happen as module attribute of tox (clearer where it comes from) - also kept a deprecated reference there for compatibilty.
    • removed some redundant rst references in hookspecs. If they are initialized once in any namespace they are defined globally (I don't like it either but that is how it works in restructuredText and ignoring that and defining the same things several times is confusing)
    • move _dummy object to only class where it is needed and name it like the constant that it is
    • use six for py2/3 compatibility where noticed it and where it is cheap to do
    • remove dead code
    • move exception related code into its own module rather than having it hang around in a class looking like a module in __init__.py
    • there is no need to have an intermediate run_main - that is used everywhere only under the name tox.cmdline rename function and use it directly, just like client code is using it
    • add a fixture for working in a clean tmpdir
    opened by obestwalter 30
  • feature: split and install dependencies if a comma-space is in the deps line.

    feature: split and install dependencies if a comma-space is in the deps line.

    Description

    Implementation of feature request: #2506

    There are two failed tests, one failure I believe is due to this change, the other I believe to be pre-existing.

    I have modified the venv.py file's get_resolved_dependencies() function to split the dependency listed if a comma-space exists in the string. I found that comma's only or spaces only failed around 7 tests and given my unfamiliarity with the codebase, I opted for a more stringent syntax.

    I believe that a split on a 'comma only' would be more expected. If someone more familiar with the code might understand why a split on a comma only is problematic and could fix the additional tests, then it should probably be implemented with a split on a comma only.

    Giving a list on separate lines is also not supported, but additional work could make that possible.

    I have added import copy and used copy.copy to clone the dependency and I am unsure if this is problematic for python 2.7.

    I am unsure of backward compatibility issues this might introduce given my unfamiliarity with Tox in general and the code base. Please feel free to critique what I have proposed, alternate solutions would be welcome.

    Todo's

    TODO: Fix 2 failing tests. TODO: Multi-line dependency spec TODO: comma only dependency spec.

    Contribution checklist:

    (also see CONTRIBUTING.rst for details)

    • [x] wrote descriptive pull request text
    • [ ] added/updated test(s)
    • [x] updated/extended the documentation
    • [x] added relevant issue keyword in message body
    • [x] added news fragment in changelog folder
      • fragment name: <issue number>.<type>.rst for example (588.bugfix.rst)
      • <type> is must be one of bugfix, feature, deprecation, breaking, doc, misc
      • if PR has no issue: consider creating one first or change it to the PR number after creating the PR
      • "sign" fragment with -- by :user:`<your username>`.
      • please, use full sentences with correct case and punctuation, for example:
        Fixed an issue with non-ascii contents in doctest text files -- by :user:`superuser`.
        
      • also see examples
    • [x] added yourself to CONTRIBUTORS (preserving alphabetical order)
    bot:chronographer:provided 
    opened by robblovell 0
  • Ability to specify more than one dependency in scoped

    Ability to specify more than one dependency in scoped "deps" config section

    In a project, to run the mypy static analyzer, I need to install both mypy and types-requests. While I could specify a separate requirements.txt for this, I would rather just put it as a list in the deps section:

    [tox]
    envlist   =
        tests
        dev
        lint
        compile
    skipsdist = true
    allowlist_externals =
        tox-echo.sh
    
    [testenv]
    deps =
        dev: -r media_analysis/requirements-m1.txt
        tests: -r media_analysis/requirements-m1.txt
        lint: pyflakes
        compile: mypy, types-requests
    
    commands =
        dev: ./tox-echo.sh
        tests: python -m pytest media_analysis/
        lint: pyflakes media_analysis/
        compile: dmypy run --timeout 5 -- media_analysis
    

    tox -e compile yields an error with installing of the dependencies mypy and types-requests:

    ERROR: invocation failed (exit code 1), logfile: .../.tox/compile/log/compile-1.log
    =================================================================================================== log start ====================================================================================================
    ERROR: Invalid requirement: 'mypy, types-requests'
    
    ==================================================================================================== log end =====================================================================================================
    ERROR: could not install deps [mypy, types-requests]; 
    v = InvocationError(".../.tox/compile/bin/python -m pip install 'mypy, types-requests'", 1)
    ____________________________________________________________________________________________________ summary _____________________________________________________________________________________________________
    ERROR: compile: could not install deps [mypy, types-requests]; 
    v = InvocationError(".../.tox/compile/bin/python -m pip install 'mypy, types-requests'", 1)
    
    

    It appears the arguments are not split at the comma and passed as a full string to pip.

    python -m pip install 'mypy, types-requests'
    

    instead of

    python -m pip install 'mypy' 'types-requests'
    

    Note that specifying compile: mypy, types-requests with a space (compile: mypy types-requests) instead makes no difference. compile: mypy types-requests would also be more consistent with the way pip works and might be the right implementation if this feature is included.

    My workaround is to use a separate requirements.txt or to specify the extra dependency before the scoped ones:

    ...
    [testenv]
    deps =
        types-requests
        dev: -r media_analysis/requirements-m1.txt
        tests: -r media_analysis/requirements-m1.txt
        lint: pyflakes
        compile: mypy
    ...
    

    or

    ...
    [testenv]
    deps =
        dev: -r media_analysis/requirements-m1.txt
        tests: -r media_analysis/requirements-m1.txt
        lint: pyflakes
        compile: -r media_analysis/requirements-compile.txt
    ...
    

    I think the dependencies should be parsed and split at the comma so that multiple dependencies can be specified.

    feature:new 
    opened by robblovell 0
  • `get_python_info` didn't follow symlink

    `get_python_info` didn't follow symlink

    tox broke a few times when get_python_info was passed a path that was a symbolic link (symlink).

    https://github.com/tox-dev/tox/blob/717b7644a2376c0178ad293c41c76ff6631bdc46/src/tox/logs/env.py#L17

    https://github.com/tox-dev/tox/blob/7aa130318d168ccc476d856ff7b1531bdaf263cc/src/tox/interpreters/via_path.py#L57

    $ poetry run tox
    python_executable is /home/test/src/appmap-python/.tox/.package/bin/python
    {'executable': '/home/test/src/appmap-python/.tox/.package/bin/python', 'implementation': 'CPython', 'version_info': [3, 9, 14, 'final', 0], 'version': '3.9.14 (main, Sep 16 2022, 08:19:05) \n[GCC 9.4.0]', 'is_64': True, 'sysplatform': 'linux', 'os_sep': '/', 'extra_version_info': None}
    python_executable is /home/test/src/appmap-python/.tox/py39-django32/bin/python
    None
    ___________________________________________________________________________________ summary ____________________________________________________________________________________
      py39-django32: commands succeeded
      congratulations :)
    Traceback (most recent call last):
      File "/home/test/.pyenv/versions/3.9.14/bin/tox", line 8, in <module>
        sys.exit(cmdline())
      File "/home/test/.pyenv/versions/3.9.14/lib/python3.9/site-packages/tox/session/__init__.py", line 44, in cmdline
        main(args)
      File "/home/test/.pyenv/versions/3.9.14/lib/python3.9/site-packages/tox/session/__init__.py", line 69, in main
        exit_code = session.runcommand()
      File "/home/test/.pyenv/versions/3.9.14/lib/python3.9/site-packages/tox/session/__init__.py", line 197, in runcommand
        return self.subcommand_test()
      File "/home/test/.pyenv/versions/3.9.14/lib/python3.9/site-packages/tox/session/__init__.py", line 225, in subcommand_test
        run_sequential(self.config, self.venv_dict)
      File "/home/test/.pyenv/versions/3.9.14/lib/python3.9/site-packages/tox/session/commands/run/sequential.py", line 9, in run_sequential
        if venv.setupenv():
      File "/home/test/.pyenv/versions/3.9.14/lib/python3.9/site-packages/tox/venv.py", line 677, in setupenv
        envlog.set_python_info(command_path)
      File "/home/test/.pyenv/versions/3.9.14/lib/python3.9/site-packages/tox/logs/env.py", line 20, in set_python_info
        answer["executable"] = python_executable
    TypeError: 'NoneType' object does not support item assignment
    
    ls -la /home/test/src/appmap-python/.tox/.package/bin/python 
    lrwxrwxrwx 1 test test 47 Sep 20 12:28 /home/test/src/appmap-python/.tox/.package/bin/python -> /home/test/.pyenv/versions/3.9.14/bin/python3.9
    

    To work around it I edited set_python_info and hardcoded the value of python_executable to the executable /home/test/.pyenv/versions/3.9.14/bin/python3.9.

    bug:normal 
    opened by symwell 0
  • InvocationError on Windows 10

    InvocationError on Windows 10

    I'm triying to run tox in windows 10 to test a python library, when I run it in ubuntu it's everything ok, but in windows I get the next error:

    ERROR: InvocationError for command 'E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\Scripts\pytest.EXE' -vv -m 'not live' (exited with code 1)

    before that the error appears to be a missing module testapp

    Traceback (most recent call last):
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pytest_django\plugin.py", line 179, in _handle_import_error
        yield
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pytest_django\plugin.py", line 351, in pytest_load_initial_conftests
        dj_settings.DATABASES
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\django\conf\__init__.py", line 87, in __getattr__
        self._setup(name)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\django\conf\__init__.py", line 74, in _setup
        self._wrapped = Settings(settings_module)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\django\conf\__init__.py", line 183, in __init__
        mod = importlib.import_module(self.SETTINGS_MODULE)
      File "C:\Users\Machina\AppData\Local\Programs\Python\Python310\lib\importlib\__init__.py", line 126, in import_module
        return _bootstrap._gcd_import(name[level:], package, level)
      File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
      File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
      File "<frozen importlib._bootstrap>", line 992, in _find_and_load_unlocked
      File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
      File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
      File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
      File "<frozen importlib._bootstrap>", line 1004, in _find_and_load_unlocked
    ModuleNotFoundError: No module named 'testapp'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "C:\Users\Machina\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
        return _run_code(code, main_globals, None,
      File "C:\Users\Machina\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code
        exec(code, run_globals)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\Scripts\pytest.EXE\__main__.py", line 7, in <module>
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\_pytest\config\__init__.py", line 187, in console_main
        code = main()
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\_pytest\config\__init__.py", line 145, in main
        config = _prepareconfig(args, plugins)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\_pytest\config\__init__.py", line 324, in _prepareconfig
        config = pluginmanager.hook.pytest_cmdline_parse(
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pluggy\_hooks.py", line 265, in __call__
        return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pluggy\_manager.py", line 80, in _hookexec
        return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pluggy\_callers.py", line 55, in _multicall
        gen.send(outcome)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\_pytest\helpconfig.py", line 102, in pytest_cmdline_parse
        config: Config = outcome.get_result()
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pluggy\_result.py", line 60, in get_result
        raise ex[1].with_traceback(ex[2])
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pluggy\_callers.py", line 39, in _multicall
        res = hook_impl.function(*args)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\_pytest\config\__init__.py", line 1017, in pytest_cmdline_parse
        self.parse(args)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\_pytest\config\__init__.py", line 1305, in parse
        self._preparse(args, addopts=addopts)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\_pytest\config\__init__.py", line 1207, in _preparse
        self.hook.pytest_load_initial_conftests(
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pluggy\_hooks.py", line 265, in __call__
        return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pluggy\_manager.py", line 80, in _hookexec
        return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pluggy\_callers.py", line 60, in _multicall
        return outcome.get_result()
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pluggy\_result.py", line 60, in get_result
        raise ex[1].with_traceback(ex[2])
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pluggy\_callers.py", line 39, in _multicall
        res = hook_impl.function(*args)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pytest_django\plugin.py", line 350, in pytest_load_initial_conftests
        with _handle_import_error(_django_project_scan_outcome):
      File "C:\Users\Machina\AppData\Local\Programs\Python\Python310\lib\contextlib.py", line 153, in __exit__
        self.gen.throw(typ, value, traceback)
      File "E:\MachinaData\Escritorio\ToxTest\django-afip\.tox\py310-django40-sqlite\lib\site-packages\pytest_django\plugin.py", line 183, in _handle_import_error
        raise ImportError(msg)
    ImportError: No module named 'testapp'
    

    The tox.ini is:

    [tox]
    envlist =
      py{37,38,39,310}-django{32,40}-{sqlite,postgres,mysql},
      live
    
    [testenv]
    deps =
      dj-database-url
      coverage
      factory-boy
      freezegun
      pytest-django
      pytest-cov
      postgres: -e .[postgres]
      mysql: -e .[mysql]
      django32: Django>=3.2,<3.3
      django40: Django>=4.0,<4.1
    commands = pytest -vv -m "not live" {posargs}
    setenv =
      PYTHONPATH={toxinidir}/testapp:{toxinidir}
      sqlite: DATABASE_URL=sqlite:///:memory:
      mysql: DATABASE_URL={env:DATABASE_URL:mysql://root:[email protected]:3306/mysql}
      postgres: DATABASE_URL=postgres://postgres:[email protected]:5432/postgres
    passenv =
      CODECOV_TOKEN
      GENTESTCSR
    
    [testenv:live]
    deps =
      {[testenv]deps}
      -e .[postgres]
    commands = pytest -vv -m "live" {posargs}
    setenv =
      PYTHONPATH={toxinidir}/testapp:{toxinidir}
      DATABASE_URL=postgres://postgres:[email protected]:5432/postgres
    
    [testenv:makemigrations]
    deps = {[testenv]deps}
    commands = django-admin makemigrations
    setenv =
      PYTHONPATH={toxinidir}/testapp:{toxinidir}
      DATABASE_URL=sqlite:///:memory:
      DJANGO_SETTINGS_MODULE=testapp.settings
    
    [testenv:fixtures]
    commands = python scripts/dump_metadata.py
    setenv =
      PYTHONPATH={toxinidir}/testapp:{toxinidir}
      DJANGO_SETTINGS_MODULE=testapp.settings
    
    [testenv:mypy]
    deps =
      django-stubs
      dj_database_url
    commands = mypy --show-traceback --pdb django_afip
    
    [testenv:docs]
    extras=docs
    commands =
      sphinx-autobuild docs/ docs/_build/html --port 9009
    whitelist_externals =
      make
    

    I supposed that the problem is in the tox.ini but I'm really lost here.

    bug:normal 
    opened by erebodino 0
  • Expand installation instruction for common linux distros, macos

    Expand installation instruction for common linux distros, macos

    The instructions for installing tox through linux/macos package managers mention potential name conflicts with other projects but lacks in examples. I also could not find info anywhere else in the docs that expanded upon this.

    I looked through the repositories for the most popular linux distro's package managers and homebrew for macos and added a section with the installation commands. Given there's some variation in project's name between tox, python-tox, and python3-tox, I think this section helps to add some clarity to these specific installation instructions.

    Contribution checklist:

    (also see CONTRIBUTING.rst for details)

    • [X] wrote descriptive pull request text
    • [ ] added/updated test(s)
    • [X] updated/extended the documentation
    • [ ] added relevant issue keyword in message body
    • [X] added news fragment in changelog folder
      • fragment name: <issue number>.<type>.rst for example (588.bugfix.rst)
      • <type> is must be one of bugfix, feature, deprecation, breaking, doc, misc
      • if PR has no issue: consider creating one first or change it to the PR number after creating the PR
      • "sign" fragment with -- by :user:`<your username>`.
      • please, use full sentences with correct case and punctuation, for example:
        Fixed an issue with non-ascii contents in doctest text files -- by :user:`superuser`.
        
      • also see examples
    • [ ] added yourself to CONTRIBUTORS (preserving alphabetical order)
    bot:chronographer:provided 
    opened by alago1 2
Releases(3.26.0)
  • 3.26.0(Sep 8, 2022)

    What's Changed

    • release 3.25.1 by @gaborbernat in https://github.com/tox-dev/tox/pull/2451
    • [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in https://github.com/tox-dev/tox/pull/2454
    • [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in https://github.com/tox-dev/tox/pull/2465
    • Check 3.11 support v3 by @gaborbernat in https://github.com/tox-dev/tox/pull/2468
    • [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in https://github.com/tox-dev/tox/pull/2471
    • Update CODEOWNERS by @jugmac00 in https://github.com/tox-dev/tox/pull/2472
    • Fix fallback to "python" environment when "isolated_build = true" is set by @Unrud in https://github.com/tox-dev/tox/pull/2475
    • [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in https://github.com/tox-dev/tox/pull/2477
    • Use tomllib from the standard library on Python 3.11+ by @hroncok in https://github.com/tox-dev/tox/pull/2463
    • [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in https://github.com/tox-dev/tox/pull/2485
    • Fix SetuptoolsDeprecationWarning about using --global-option by @adamchainz in https://github.com/tox-dev/tox/pull/2487

    New Contributors

    • @Unrud made their first contribution in https://github.com/tox-dev/tox/pull/2475

    Full Changelog: https://github.com/tox-dev/tox/compare/3.25.1...3.26.0

    Source code(tar.gz)
    Source code(zip)
  • 3.25.1(Jun 29, 2022)

    What's Changed

    • release 3.25.0 by @gaborbernat in https://github.com/tox-dev/tox/pull/2398
    • [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in https://github.com/tox-dev/tox/pull/2399
    • Adding APPDATA as default passenv on Windows by @niander in https://github.com/tox-dev/tox/pull/2404
    • [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in https://github.com/tox-dev/tox/pull/2415
    • Avoid importing pipes on Python 3.3+ by @adamchainz in https://github.com/tox-dev/tox/pull/2418
    • Fix link to download stats by @jugmac00 in https://github.com/tox-dev/tox/pull/2424
    • [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in https://github.com/tox-dev/tox/pull/2441
    • Bump actions/setup-python from 2 to 4 by @dependabot in https://github.com/tox-dev/tox/pull/2446
    • Bump actions/download-artifact from 2 to 3 by @dependabot in https://github.com/tox-dev/tox/pull/2444
    • Bump actions/upload-artifact from 2 to 3 by @dependabot in https://github.com/tox-dev/tox/pull/2443
    • Bump actions/checkout from 2 to 3 by @dependabot in https://github.com/tox-dev/tox/pull/2445
    • Improve advice on constraints files by @apljungquist in https://github.com/tox-dev/tox/pull/2423
    • fix isolated builds when stderr is buffered and appears after print() by @asottile in https://github.com/tox-dev/tox/pull/2449
    • Unify badges style by @DeadNews in https://github.com/tox-dev/tox/pull/2448

    New Contributors

    • @niander made their first contribution in https://github.com/tox-dev/tox/pull/2404
    • @dependabot made their first contribution in https://github.com/tox-dev/tox/pull/2446
    • @apljungquist made their first contribution in https://github.com/tox-dev/tox/pull/2423
    • @DeadNews made their first contribution in https://github.com/tox-dev/tox/pull/2448

    Full Changelog: https://github.com/tox-dev/tox/compare/3.25.0...3.25.1

    Source code(tar.gz)
    Source code(zip)
  • 4.0.0a10(Jan 10, 2022)

Owner
tox development team
testing out of the box
tox development team
Simple frontend TypeScript testing utility

TSFTest Simple frontend TypeScript testing utility. Installation Install webpack in your project directory: npm install --save-dev webpack webpack-cli

null 2 Nov 9, 2021
A command-line tool and Python library and Pytest plugin for automated testing of RESTful APIs, with a simple, concise and flexible YAML-based syntax

1.0 Release See here for details about breaking changes with the upcoming 1.0 release: https://github.com/taverntesting/tavern/issues/495 Easier API t

null 892 Sep 25, 2022
A complete test automation tool

Golem - Test Automation Golem is a test framework and a complete tool for browser automation. Tests can be written with code in Python, codeless using

null 486 Sep 9, 2022
PyAutoEasy is a extension / wrapper around the famous PyAutoGUI, a cross-platform GUI automation tool to replace your boooring repetitive tasks.

PyAutoEasy PyAutoEasy is a extension / wrapper around the famous PyAutoGUI, a cross-platform GUI automation tool to replace your boooring repetitive t

Dingu Sagar 6 Dec 7, 2021
Obsei is a low code AI powered automation tool.

Obsei is a low code AI powered automation tool. It can be used in various business flows like social listening, AI based alerting, brand image analysis, comparative study and more .

Obsei 727 Sep 30, 2022
Fi - A simple Python 3.9+ command-line application for managing Fidelity portfolios

fi fi is a simple Python 3.9+ command-line application for managing Fidelity por

Darik Harter 2 Feb 26, 2022
Data-Driven Tests for Python Unittest

DDT (Data-Driven Tests) allows you to multiply one test case by running it with different test data, and make it appear as multiple test cases. Instal

null 420 Sep 8, 2022
Generic automation framework for acceptance testing and RPA

Robot Framework Introduction Installation Example Usage Documentation Support and contact Contributing License Introduction Robot Framework is a gener

Robot Framework 7.3k Sep 27, 2022
A folder automation made using Watch-dog, it only works in linux for now but I assume, it will be adaptable to mac and PC as well

folder-automation A folder automation made using Watch-dog, it only works in linux for now but I assume, it will be adaptable to mac and PC as well Th

Parag Jyoti Paul 31 May 28, 2021
A browser automation framework and ecosystem.

Selenium Selenium is an umbrella project encapsulating a variety of tools and libraries enabling web browser automation. Selenium specifically provide

Selenium 24.7k Sep 28, 2022
✅ Python web automation and testing. 🚀 Fast, easy, reliable. 💠

Build fast, reliable, end-to-end tests. SeleniumBase is a Python framework for web automation, end-to-end testing, and more. Tests are run with "pytes

SeleniumBase 2.9k Sep 26, 2022
Integration layer between Requests and Selenium for automation of web actions.

Requestium is a Python library that merges the power of Requests, Selenium, and Parsel into a single integrated tool for automatizing web actions. The

Tryolabs 1.7k Sep 25, 2022
Python version of the Playwright testing and automation library.

?? Playwright for Python Docs | API Playwright is a Python library to automate Chromium, Firefox and WebKit browsers with a single API. Playwright del

Microsoft 6.9k Oct 1, 2022
Network automation lab using nornir, scrapli, and containerlab with Arista EOS

nornir-scrapli-eos-lab Network automation lab using nornir, scrapli, and containerlab with Arista EOS. Objectives Deploy base configs to 4xArista devi

Vireak Ouk 13 Jul 7, 2022
API Test Automation with Requests and Pytest

api-testing-requests-pytest Install Make sure you have Python 3 installed on your machine. Then: 1.Install pipenv sudo apt-get install pipenv 2.Go to

Sulaiman Haque 2 Nov 21, 2021
A cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard.

PyAutoGUI PyAutoGUI is a cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard. pip inst

Al Sweigart 7.2k Sep 24, 2022
Headless chrome/chromium automation library (unofficial port of puppeteer)

Pyppeteer Pyppeteer has moved to pyppeteer/pyppeteer Unofficial Python port of puppeteer JavaScript (headless) chrome/chromium browser automation libr

miyakogi 3.5k Sep 21, 2022
Selenium-python but lighter: Helium is the best Python library for web automation.

Selenium-python but lighter: Helium Selenium-python is great for web automation. Helium makes it easier to use. For example: Under the hood, Helium fo

Michael Herrmann 3.1k Sep 27, 2022
Flexible test automation for Python

Nox - Flexible test automation for Python nox is a command-line tool that automates testing in multiple Python environments, similar to tox. Unlike to

Stargirl Flowers 888 Sep 22, 2022