@@ -80,20 +80,133 @@ that worker and report the failure as usual. You can use the
80
80
``--max-worker-restart `` option to limit the number of workers that can
81
81
be restarted, or disable restarting altogether using ``--max-worker-restart=0 ``.
82
82
83
- By default, the ``-n `` option will send pending tests to any worker that is available, without
84
- any guaranteed order, but you can control this with these options:
83
+ Dividing tests up
84
+ ^^^^^^^^^^^^^^^^^
85
+
86
+ In order to divide the tests up amongst the workers, ``pytest-xdist `` first puts sets of
87
+ them into "test groups". The tests within a test group are all run together in one shot,
88
+ so fixtures of larger scopes won't be run once for every single test. Instead, they'll
89
+ be run as many times as they need to for the tests within that test group. But, once
90
+ that test group is finished, it should be assumed that all cached fixture values from
91
+ that test group's execution are destroyed.
92
+
93
+ By default, there is no grouping logic and every individual test is placed in its own
94
+ test group, so using the ``-n `` option will send pending tests to any worker that is
95
+ available, without any guaranteed order. It should be assumed that when using this
96
+ approach, every single test is run entirely in isolation from the others, meaning the
97
+ tests can't rely on cached fixture values from larger-scoped fixtures.
98
+
99
+ Provided test grouping options
100
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
101
+
102
+ By default, ``pytest-xdist `` doesn't group any tests together, but it provides some
103
+ grouping options, based on simple criteria about a test's nodeid. so you can gunarantee
104
+ that certain tests are run in the same process. When they're run in the same process,
105
+ you gunarantee that larger-scoped fixtures are only executed as many times as would
106
+ normally be expected for the tests in the test group. But, once that test group is
107
+ finished, it should be assumed that all cached fixture values from that test group's
108
+ execution are destroyed.
109
+
110
+ Here's the options that are built in:
111
+
112
+ * ``--dist=loadscope ``: tests will be grouped by **module ** shown in each test's node
113
+ for *test functions * and by the **class ** shown in each test's nodeid for *test
114
+ methods *. This feature was added in version ``1.19 ``.
115
+
116
+ * ``--dist=loadfile ``: tests will be grouped by the **module ** shown in each test's
117
+ nodeid. This feature was added in version ``1.21 ``.
118
+
119
+ Defining custom load distribution logic
120
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
121
+
122
+ ``pytest-xdist `` iterates over the entire list of collected tests and usually determines
123
+ what group to put them in based off of their nodeid. There is no set number of test
124
+ groups, as it creates a new groups as needed. You can tap into this system to define
125
+ your own grouping logic by using the ``pytest_xdist_set_test_group_from_nodeid ``.
126
+
127
+ If you define your own copy of that hook, it will be called once for every test, and the
128
+ nodeid for each test will be passed in. Whatever it returns is the test group for that
129
+ test. If a test group doesn't already exist with that name, then it will be created, so
130
+ anything can be used.
131
+
132
+ For example, let's say you have the following tests::
133
+
134
+ test/test_something.py::test_form_upload[image-chrome]
135
+ test/test_something.py::test_form_upload[image-firefox]
136
+ test/test_something.py::test_form_upload[video-chrome]
137
+ test/test_something.py::test_form_upload[video-firefox]
138
+ test/test_something_else.py::test_form_upload[image-chrome]
139
+ test/test_something_else.py::test_form_upload[image-firefox]
140
+ test/test_something_else.py::test_form_upload[video-chrome]
141
+ test/test_something_else.py::test_form_upload[video-firefox]
142
+
143
+ In order to have the ``chrome `` related tests run together and the ``firefox `` tests run
144
+ together, but allow them to be separated by file, this could be done:
85
145
86
- * ``--dist=loadscope ``: tests will be grouped by **module ** for *test functions * and
87
- by **class ** for *test methods *, then each group will be sent to an available worker,
88
- guaranteeing that all tests in a group run in the same process. This can be useful if you have
89
- expensive module-level or class-level fixtures. Currently the groupings can't be customized,
90
- with grouping by class takes priority over grouping by module.
91
- This feature was added in version ``1.19 ``.
146
+ .. code-block :: python
147
+
148
+ def pytest_xdist_set_test_group_from_nodeid (nodeid ):
149
+ browser_names = [' chrome' , ' firefox' ]
150
+ nodeid_params = nodeid.split(' [' , 1 )[- 1 ].rstrip(' ]' ).split(' -' )
151
+ for name in browser_names:
152
+ if name in nodeid_params:
153
+ return " {test_file} [{browser_name} ]" .format(
154
+ test_file = nodeid.split(" ::" , 1 )[0 ],
155
+ browser_name = name,
156
+ )
157
+
158
+ The tests would then be divided into these test groups:
159
+
160
+ .. code-block :: python
161
+
162
+ {
163
+ " test/test_something.py::test_form_upload[chrome]" : [
164
+ " test/test_something.py::test_form_upload[image-chrome]" ,
165
+ " test/test_something.py::test_form_upload[video-chrome]"
166
+ ],
167
+ " test/test_something.py::test_form_upload[firefox]" : [
168
+ " test/test_something.py::test_form_upload[image-firefox]" ,
169
+ " test/test_something.py::test_form_upload[video-firefox]"
170
+ ],
171
+ " test/test_something_else.py::test_form_upload[firefox]" : [
172
+ " test/test_something_else.py::test_form_upload[image-firefox]" ,
173
+ " test/test_something_else.py::test_form_upload[video-firefox]"
174
+ ],
175
+ " test/test_something_else.py::test_form_upload[chrome]" : [
176
+ " test/test_something_else.py::test_form_upload[image-chrome]" ,
177
+ " test/test_something_else.py::test_form_upload[video-chrome]"
178
+ ]
179
+ }
180
+
181
+ You can also fall back on one of the default load distribution mechanism by passing the
182
+ arguments for them listed above when you call pytest. Because this example returns
183
+ ``None `` if the nodeid doesn't meet any of the criteria, it will defer to whichever
184
+ mechanism you chose. So if you passed ``--dist=loadfile ``, tests would otherwise be
185
+ divided up by file name.
186
+
187
+ Keep in mind, this is a means of optimization, not a means for determinism.
188
+
189
+ Controlling test group execution order
190
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
191
+
192
+ Sometimes you may want to have certain test groups start before or after others. Once
193
+ the test groups have been determined, the ``OrderedDict `` they are stored in can have
194
+ its order modified through the ``pytest_xdist_order_test_groups `` hook. For example, in
195
+ order to move the test group named ``"groupA" `` to the end of the queue, this can be
196
+ done:
197
+
198
+ .. code-block :: python
199
+
200
+ def pytest_xdist_order_test_groups (workqueue ):
201
+ workqueue.move_to_end(" groupA" )
92
202
93
- * `` --dist=loadfile ``: tests will be grouped by file name, and then will be sent to an available
94
- worker, guaranteeing that all tests in a group run in the same worker. This feature was added
95
- in version `` 1.21 `` .
203
+ Keep in mind, this is a means of optimization, not a means for determinism or filtering.
204
+ Removing test groups from this `` OrderedDict ``, or adding new ones in after the fact can
205
+ have unforseen consequences .
96
206
207
+ If you want to filter out which tests get run, it is recommended to either rely on test
208
+ suite structure (so you can target the tests in specific locations), or by using marks
209
+ (so you can select or filter out based on specific marks with the ``-m `` flag).
97
210
98
211
Making session-scoped fixtures execute only once
99
212
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0 commit comments