In pytest, how do I set an environment variable based on a bash shell expression?

Viewed 2759

I'm using Python 3.8 and pytest. I have this pytest.ini file ...

[pytest]
env_override_existing_values = 1
env_files =
    tests/.test_env

My tests/.test_env contains

TZ=`ls -la /etc/localtime | cut -d/ -f8-9`

However, this is getting literally evaluated in my pytest -- that is TZ is being equal to "ls -la /etc/localtime | cut -d/ -f8-9". Is there a way I can configure my env var for pytest to be the result of an expression when I run "pytest tests/my_test.py"? FYI, it is not an option to do something like "TZ=ls -la /etc/localtime | cut -d/ -f8-9; pytest tests/my_test.py"

3 Answers

So, if I understand this correctly, you want to set an envvar within the pytest process, without using any outside parameters. You could use a session scoped pytest fixture in conftest.py like this:

$ cat conftest.py
import os
import subprocess

import pytest


@pytest.fixture(scope="session", autouse=True)
def setenv():
    process = subprocess.run("ls -la /etc/localtime | cut -d/ -f8-9", shell=True, capture_output=True)
    os.environ["TZ"] = process.stdout.decode("utf8")

$ cat test_foo.py
import os


def test_my_test():
    print(os.environ["TZ"])
$ pytest -s
================================================================================= test session starts ==================================================================================
platform linux -- Python 3.8.2, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
rootdir: /tmp/testy
collected 1 item                                                                                                                                                                       

test_foo.py New York

.

================================================================================== 1 passed in 0.01s ===================================================================================
$ echo $TZ

$

The (pytest documentation)[https://pypi.org/project/pytest-envfiles/] suggests the files used by the pytest "env_files" directive need to contain literal key=val lines. Yes, the documentation is not clear regarding the format for pytest env files. So your, incorrect, expectation those files are "evaluated" using your $SHELL program, let alone in any other fashion, is not surprising.

I don't understand why you can't do something like "TZ=ls -la /etc/localtime | cut -d/ -f8-9; pytest tests/my_test.py". Also, you are apparently trying to explicitly set $TZ to the default timezone for the platform. Why? That should be the default. Which suggests there is a deeper problem. That is, you are asking a xyproblem.info question.

So basically pytest.ini may contain:

[pytest]
TZ=

Then, you can pass it at cmd line as:

$ TZ=`ls -la /etc/localtime | cut -d/ -f8-9` pytest -c pytest.ini -s tests/**
Related