55[ ![ check] ( https://github.com/pytest-dev/pytest-env/actions/workflows/check.yaml/badge.svg )] ( https://github.com/pytest-dev/pytest-env/actions/workflows/check.yaml )
66[ ![ Downloads] ( https://static.pepy.tech/badge/pytest-env/month )] ( https://pepy.tech/project/pytest-env )
77
8- This is a ` pytest ` plugin that enables you to set environment variables in ` pytest.ini ` , ` pyproject .toml` , ` pytest.toml `
9- or ` .pytest.toml ` files.
8+ A ` pytest ` plugin that sets environment variables from ` pyproject.toml ` , ` pytest .toml` , ` . pytest.toml` , or ` pytest.ini `
9+ configuration files.
1010
1111## Installation
1212
13- Install with pip:
14-
1513``` shell
1614pip install pytest-env
1715```
1816
1917## Usage
2018
21- ### Native form in ` pyproject.toml ` , ` pytest.toml ` and ` .pytest.toml `
22-
23- Native form takes precedence over the ` pytest.ini ` form. ` pytest.toml ` takes precedence over ` .pytest.toml ` , and that
24- takes precedence over ` pyproject.toml ` .
19+ ### TOML configuration (native form)
2520
26- In ` pyproject.toml ` :
21+ Define environment variables under ` [tool.pytest_env] ` in ` pyproject.toml ` , or ` [pytest_env] ` in ` pytest.toml ` /
22+ ` .pytest.toml ` :
2723
2824``` toml
25+ # pyproject.toml
2926[tool .pytest_env ]
3027HOME = " ~/tmp"
3128RUN_ENV = 1
@@ -34,9 +31,8 @@ SKIP_IF_SET = { value = "on", skip_if_set = true }
3431DATABASE_URL = { unset = true }
3532```
3633
37- In ` pytest.toml ` (or ` .pytest.toml ` ):
38-
3934``` toml
35+ # pytest.toml or .pytest.toml
4036[pytest_env ]
4137HOME = " ~/tmp"
4238RUN_ENV = 1
@@ -45,93 +41,129 @@ SKIP_IF_SET = { value = "on", skip_if_set = true }
4541DATABASE_URL = { unset = true }
4642```
4743
48- The ` tool.pytest_env ` ( ` pytest_env ` in ` pytest.toml ` and ` .pytest.toml ` ) tables keys are the environment variables keys
49- to set. The right hand side of the assignment :
44+ Each key is the environment variable name. The value is either a plain value (cast to string) or an inline table with
45+ the following keys :
5046
51- - if an inline table you can set options via the ` transform ` , ` skip_if_set ` or ` unset ` keys, while the ` value ` key holds
52- the value to set (or transform before setting). For transformation the variables you can use is other environment
53- variable,
54- - otherwise the value to set for the environment variable to set (casted to a string).
47+ | Key | Type | Description |
48+ | ------------- | ------ | --------------------------------------------------------------------------- |
49+ | ` value ` | string | The value to set |
50+ | ` transform ` | bool | Expand ` {VAR} ` references in the value using existing environment variables |
51+ | ` skip_if_set ` | bool | Only set the variable if it is not already defined |
52+ | ` unset ` | bool | Remove the variable from the environment (ignores ` value ` ) |
5553
56- ### Via pytest configurations
54+ ### INI configuration
5755
58- In your pytest.ini file add a key value pair with ` env ` as the key and the environment variables as a line separated
59- list of ` KEY=VALUE ` entries. The defined variables will be added to the environment before any tests are run:
56+ Define environment variables as a line-separated list of ` KEY=VALUE ` entries under the ` env ` key:
6057
6158``` ini
59+ # pytest.ini
6260[pytest]
6361env =
6462 HOME =~/tmp
6563 RUN_ENV =test
6664```
6765
68- Or with ` pyproject.toml ` :
69-
7066``` toml
67+ # pyproject.toml
7168[tool .pytest ]
7269env = [
7370 " HOME=~/tmp" ,
7471 " RUN_ENV=test" ,
7572]
7673```
7774
78- ### Only set if not already set
75+ Prefix flags modify behavior. Flags are case-insensitive and can be combined in any order (e.g., ` R:D:KEY=VALUE ` ):
76+
77+ | Flag | Description |
78+ | ---- | ------------------------------------------------------------------ |
79+ | ` D: ` | Default — only set if the variable is not already defined |
80+ | ` R: ` | Raw — skip ` {VAR} ` expansion (INI expands by default, unlike TOML) |
81+ | ` U: ` | Unset — remove the variable from the environment entirely |
7982
80- Use ` skip_if_set = true ` in the native TOML form, or the ` D: ` (default) prefix in INI form, to only set the variable
81- when it is not already defined in the environment:
83+ ### Precedence
84+
85+ When multiple configuration sources are present, the native TOML form takes precedence over the INI form. Within the
86+ TOML form, files are checked in this order: ` pytest.toml ` , ` .pytest.toml ` , ` pyproject.toml ` . The first file containing a
87+ ` pytest_env ` section wins.
88+
89+ ### Configuration file discovery
90+
91+ The plugin walks the directory tree starting from the directory containing the configuration file pytest resolved
92+ (` inipath ` ). For each directory it checks ` pytest.toml ` , ` .pytest.toml ` , and ` pyproject.toml ` in order, stopping at the
93+ first file with a ` pytest_env ` section. This means a subdirectory config takes precedence over a parent config:
94+
95+ ```
96+ project/
97+ ├── pyproject.toml # [tool.pytest_env] DB_HOST = "prod-db"
98+ └── tests_integration/
99+ ├── pytest.toml # [pytest_env] DB_HOST = "test-db"
100+ └── test_api.py
101+ ```
102+
103+ Running ` pytest tests_integration/ ` uses ` DB_HOST = "test-db" ` from the subdirectory.
104+
105+ If no TOML file with a ` pytest_env ` section is found, the plugin falls back to the INI-style ` env ` key.
106+
107+ ### Examples
108+
109+ ** Expanding environment variables** — reference existing variables using ` {VAR} ` syntax:
82110
83111``` toml
84112[pytest_env ]
85- HOME = { value = " ~/tmp" , skip_if_set = true }
86- RUN_ENV = { value = " test" , skip_if_set = true }
113+ RUN_PATH = { value = " /run/path/{USER}" , transform = true }
87114```
88115
89116``` ini
90117[pytest]
91118env =
92- D:HOME =~/tmp
93- D:RUN_ENV =test
119+ RUN_PATH =/run/path/{USER}
94120```
95121
96- ### Transformation
122+ In TOML, expansion requires ` transform = true ` . In INI, expansion is the default; use the ` R: ` flag to disable it.
97123
98- You can reference existing environment variables using a python-like format. Use ` transform = true ` in the native TOML
99- form, or omit the ` R: ` prefix in INI form (transformation is the default in INI):
124+ ** Keeping raw values** — prevent ` {VAR} ` expansion:
100125
101126``` toml
102127[pytest_env ]
103- RUN_PATH = { value = " /run/path/{USER}" , transform = true }
128+ PATTERN = { value = " /run/path/{USER}" }
104129```
105130
106131``` ini
107132[pytest]
108133env =
109- RUN_PATH =/run/path/{USER}
134+ R: PATTERN =/run/path/{USER}
110135```
111136
112- To keep the raw value and skip transformation, omit ` transform ` (or set it to ` false ` ) in TOML, or apply the ` R: ` prefix
113- in INI (can combine with ` D: ` /` skip_if_set ` , order is not important):
137+ ** Conditional defaults** — only set when not already defined:
114138
115139``` toml
116140[pytest_env ]
117- RUN_PATH = { value = " /run/path/{USER}" }
118- RUN_PATH_IF_NOT_SET = { value = " /run/path/{USER}" , skip_if_set = true }
141+ HOME = { value = " ~/tmp" , skip_if_set = true }
119142```
120143
121144``` ini
122145[pytest]
123146env =
124- R:RUN_PATH =/run/path/{USER}
125- R:D:RUN_PATH_IF_NOT_SET =/run/path/{USER}
147+ D:HOME =~/tmp
126148```
127149
128- ### Unsetting variables
150+ ** Unsetting variables** — completely remove a variable from ` os.environ ` (not the same as setting to empty string):
129151
130- You can use ` U: ` (unset) as prefix to remove an environment variable. This differs from setting a variable to an empty
131- string — the variable will be completely removed from ` os.environ ` :
152+ ``` toml
153+ [pytest_env ]
154+ DATABASE_URL = { unset = true }
155+ ```
132156
133157``` ini
134158[pytest]
135159env =
136160 U:DATABASE_URL
137161```
162+
163+ ** Combining flags** — flags can be combined in any order:
164+
165+ ``` ini
166+ [pytest]
167+ env =
168+ R:D:TEMPLATE =/path/{placeholder}
169+ ```
0 commit comments