pytestgitlab-citox

In tox What is the difference between setenv, and passenv


I setting up tox to be used in my .gitlab-ci.yml in combination with pytest. I want pytest to run with specific environment that are set in the .gitlab-ci.yml file

In the documentation I found the tox.ini configurations setenv and passenv but I couldn't understand what is the use case for each configuration.

What is the difference? What are the use cases? i.e. when would I want to use setenv over passenv or vice versa?


Solution

  • setenv expects you to set a value explicitly:

    setenv =
      foo=bar
    

    passenv does not require a value to be set -- it should be passed from the context in which tox is invoked. As relevant background... without passenv, any environment variables you may have set before invoking tox won't be present in the testing environment created by tox!


    For example, I might have some tests that I know can run locally, but will not work when run in a CI environment. So, in pytest, I might have something like this:

    @pytest.mark.skipif(os.environ.get('CI', False), reason="this test won't work in CI")
    def test_function():
        ...
    

    In this case I don't want to use setenv because I still want these tests to run when I invoke tox locally, but not in CI. So, I configure passenv for this variable to ensure the variable CI (which is always present in the CI system) is accessible in the tox environment:

    passenv =
        CI
    

    In other cases, I may want a variable to always be set to a specific value whenever tox is invoked, for example, the PYTHONUNBUFFERED variable to ensure output from my tests is not buffered:

    setenv =
      PYTHONUNBUFFERED=1
    

    Another unique usecase for passenv is that it supports using * and ? for glob-like matching of multiple environment variables. For example, perhaps your tests make use of many GitHub Actions environment variables (which are namespaced with with the prefix GITHUB_), you might do something like this:

    passenv = 
      GITHUB_*
      CI
    

    Or for GitLab CI's environment variables which are prefixed with CI_ and GITLAB_:

    passenv = 
      GITLAB_*
      CI_*
      CI
    

    Lastly, setenv values take precedence over passenv values. So, even if a wildcard in passenv matches a present environment variable, using setenv will take precedence over passenv, ensuring the variable/value you specify takes effect over any value that may have been specified or matched with passenv.