@@ -24,45 +24,24 @@ When ``xdist`` is disabled (running with ``-n0`` for example), then
24
24
Worker processes also have the following environment variables
25
25
defined:
26
26
27
- * ``PYTEST_XDIST_WORKER ``: the name of the worker, e.g., ``"gw2" ``.
28
- * ``PYTEST_XDIST_WORKER_COUNT ``: the total number of workers in this session,
29
- e.g., ``"4" `` when ``-n 4 `` is given in the command-line.
27
+ .. envvar :: PYTEST_XDIST_WORKER
30
28
31
- The information about the worker_id in a test is stored in the ``TestReport `` as
32
- well, under the ``worker_id `` attribute.
33
-
34
- Since version 2.0, the following functions are also available in the ``xdist `` module:
35
-
36
- .. code-block :: python
37
-
38
- def is_xdist_worker (request_or_session ) -> bool :
39
- """ Return `True` if this is an xdist worker, `False` otherwise
40
-
41
- :param request_or_session: the `pytest` `request` or `session` object
42
- """
29
+ The name of the worker, e.g., ``"gw2" ``.
43
30
44
- def is_xdist_controller (request_or_session ) -> bool :
45
- """ Return `True` if this is the xdist controller, `False` otherwise
31
+ .. envvar :: PYTEST_XDIST_WORKER_COUNT
46
32
47
- Note: this method also returns `False` when distribution has not been
48
- activated at all.
33
+ The total number of workers in this session, e.g., ``"4" `` when ``-n 4 `` is given in the command-line.
49
34
50
- :param request_or_session: the `pytest` `request` or `session` object
51
- """
52
-
53
- def is_xdist_master (request_or_session ) -> bool :
54
- """ Deprecated alias for is_xdist_controller."""
55
-
56
- def get_xdist_worker_id (request_or_session ) -> str :
57
- """ Return the id of the current worker ('gw0', 'gw1', etc) or 'master'
58
- if running on the controller node.
35
+ The information about the worker_id in a test is stored in the ``TestReport `` as
36
+ well, under the ``worker_id `` attribute.
59
37
60
- If not distributing tests (for example passing `-n0` or not passing `-n` at all)
61
- also return 'master'.
38
+ Since version 2.0, the following functions are also available in the ``xdist `` module:
62
39
63
- :param request_or_session: the `pytest` `request` or `session` object
64
- """
65
40
41
+ .. autofunction :: xdist.is_xdist_worker
42
+ .. autofunction :: xdist.is_xdist_controller
43
+ .. autofunction :: xdist.is_xdist_master
44
+ .. autofunction :: xdist.get_xdist_worker_id
66
45
67
46
Identifying workers from the system environment
68
47
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -98,6 +77,7 @@ wanted to create a separate database for each test run:
98
77
import pytest
99
78
from posix_ipc import Semaphore, O_CREAT
100
79
80
+
101
81
@pytest.fixture (scope = " session" , autouse = True )
102
82
def create_unique_database (testrun_uid ):
103
83
""" create a unique database for this particular test run """
@@ -107,6 +87,7 @@ wanted to create a separate database for each test run:
107
87
if not database_exists(database_url):
108
88
create_database(database_url)
109
89
90
+
110
91
@pytest.fixture ()
111
92
def db (testrun_uid ):
112
93
""" retrieve unique database """
@@ -116,7 +97,9 @@ wanted to create a separate database for each test run:
116
97
117
98
Additionally, during a test run, the following environment variable is defined:
118
99
119
- * ``PYTEST_XDIST_TESTRUNUID ``: the unique id of the test run.
100
+ .. envvar :: PYTEST_XDIST_TESTRUNUID
101
+
102
+ The unique id of the test run.
120
103
121
104
Accessing ``sys.argv `` from the controller node in workers
122
105
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -222,3 +205,46 @@ initializing a database service and populating initial tables.
222
205
223
206
This technique might not work for every case, but should be a starting point for many situations
224
207
where executing a high-scope fixture exactly once is important.
208
+
209
+
210
+ Creating one log file for each worker
211
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
212
+
213
+ To create one log file for each worker with ``pytest-xdist ``, you can leverage :envvar: `PYTEST_XDIST_WORKER `
214
+ an option to ``pytest.ini `` for the file base name. Then, in ``conftest.py ``,
215
+ register it with ``pytest_addoption(parser) `` and use ``pytest_configure(config) ``
216
+ to rename it with the worker id.
217
+
218
+ Example:
219
+
220
+ .. code-block :: ini
221
+
222
+ [pytest]
223
+ log_file_format = %(asctime)s %(name)s %(levelname)s %(message)s
224
+ log_file_level = INFO
225
+ worker_log_file = tests_{worker_id}.log
226
+
227
+
228
+ .. code-block :: python
229
+
230
+ # content of conftest.py
231
+ def pytest_addoption (parser ):
232
+ parser.addini(
233
+ " worker_log_file" ,
234
+ help = " Similar to log_file, but %w will be replaced with a worker identifier." ,
235
+ )
236
+
237
+
238
+ def pytest_configure (config ):
239
+ worker_id = os.environ.get(" PYTEST_XDIST_WORKER" )
240
+ if worker_id is not None :
241
+ log_file = config.getini(" worker_log_file" )
242
+ logging.basicConfig(
243
+ format = config.getini(" log_file_format" ),
244
+ filename = log_file.format(worker_id = worker_id),
245
+ level = config.getini(" log_file_level" ),
246
+ )
247
+
248
+
249
+ When running the tests with ``-n3 ``, for example, three files will be created in the current directory:
250
+ ``tests_gw0.log ``, ``tests_gw1.log `` and ``tests_gw2.log ``.
0 commit comments