pytest-isolated 0.3.0__py3-none-any.whl → 0.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pytest_isolated/__init__.py +1 -1
- pytest_isolated/config.py +81 -0
- pytest_isolated/execution.py +504 -0
- pytest_isolated/grouping.py +87 -0
- pytest_isolated/plugin.py +15 -410
- pytest_isolated/reporting.py +173 -0
- {pytest_isolated-0.3.0.dist-info → pytest_isolated-0.4.1.dist-info}/METADATA +72 -10
- pytest_isolated-0.4.1.dist-info/RECORD +13 -0
- pytest_isolated-0.3.0.dist-info/RECORD +0 -9
- {pytest_isolated-0.3.0.dist-info → pytest_isolated-0.4.1.dist-info}/WHEEL +0 -0
- {pytest_isolated-0.3.0.dist-info → pytest_isolated-0.4.1.dist-info}/entry_points.txt +0 -0
- {pytest_isolated-0.3.0.dist-info → pytest_isolated-0.4.1.dist-info}/licenses/LICENSE +0 -0
- {pytest_isolated-0.3.0.dist-info → pytest_isolated-0.4.1.dist-info}/top_level.txt +0 -0
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pytest-isolated
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Run marked pytest tests in grouped subprocesses (cross-platform).
|
|
5
5
|
Author: pytest-isolated contributors
|
|
6
6
|
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/dyollb/pytest-isolated
|
|
8
|
+
Project-URL: Repository, https://github.com/dyollb/pytest-isolated
|
|
9
|
+
Project-URL: Issues, https://github.com/dyollb/pytest-isolated/issues
|
|
7
10
|
Classifier: Development Status :: 4 - Beta
|
|
8
11
|
Classifier: Framework :: Pytest
|
|
9
12
|
Classifier: Intended Audience :: Developers
|
|
@@ -17,11 +20,11 @@ Description-Content-Type: text/markdown
|
|
|
17
20
|
License-File: LICENSE
|
|
18
21
|
Requires-Dist: pytest>=7.0
|
|
19
22
|
Provides-Extra: dev
|
|
20
|
-
Requires-Dist: pre-commit; extra == "dev"
|
|
21
23
|
Requires-Dist: build; extra == "dev"
|
|
24
|
+
Requires-Dist: mypy; extra == "dev"
|
|
25
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest-timeout; extra == "dev"
|
|
22
27
|
Requires-Dist: ruff; extra == "dev"
|
|
23
|
-
Provides-Extra: test
|
|
24
|
-
Requires-Dist: pytest-timeout; extra == "test"
|
|
25
28
|
Dynamic: license-file
|
|
26
29
|
|
|
27
30
|
# pytest-isolated
|
|
@@ -29,18 +32,22 @@ Dynamic: license-file
|
|
|
29
32
|
[](https://github.com/dyollb/pytest-isolated/actions/workflows/test.yml)
|
|
30
33
|
[](https://pypi.org/project/pytest-isolated/)
|
|
31
34
|
|
|
32
|
-
A pytest plugin that runs marked tests in isolated subprocesses with intelligent grouping.
|
|
35
|
+
A cross-platform pytest plugin that runs marked tests in isolated subprocesses with intelligent grouping.
|
|
33
36
|
|
|
34
37
|
## Features
|
|
35
38
|
|
|
36
39
|
- Run tests in fresh Python subprocesses to prevent state pollution
|
|
37
40
|
- Group related tests to run together in the same subprocess
|
|
38
41
|
- Handles crashes, timeouts, and setup/teardown failures
|
|
39
|
-
-
|
|
42
|
+
- Respects pytest's standard output capture settings (`-s`, `--capture`)
|
|
40
43
|
- Works with pytest reporters (JUnit XML, etc.)
|
|
41
44
|
- Configurable timeouts to prevent hanging subprocesses
|
|
42
45
|
- Cross-platform: Linux, macOS, Windows
|
|
43
46
|
|
|
47
|
+
## Cheatsheet for pytest-forked users
|
|
48
|
+
|
|
49
|
+
This plugin is inspired by [pytest-forked](https://github.com/pytest-dev/pytest-forked). See [pytest-forked migration guide](docs/pytest-forked-migration.md) for a quick reference comparing features.
|
|
50
|
+
|
|
44
51
|
## Installation
|
|
45
52
|
|
|
46
53
|
```bash
|
|
@@ -63,6 +70,7 @@ def test_isolated():
|
|
|
63
70
|
Tests with the same group run together in one subprocess:
|
|
64
71
|
|
|
65
72
|
```python
|
|
73
|
+
# Using keyword argument
|
|
66
74
|
@pytest.mark.isolated(group="mygroup")
|
|
67
75
|
def test_one():
|
|
68
76
|
shared_state.append(1)
|
|
@@ -71,6 +79,11 @@ def test_one():
|
|
|
71
79
|
def test_two():
|
|
72
80
|
# Sees state from test_one
|
|
73
81
|
assert len(shared_state) == 2
|
|
82
|
+
|
|
83
|
+
# Or using positional argument
|
|
84
|
+
@pytest.mark.isolated("mygroup")
|
|
85
|
+
def test_three():
|
|
86
|
+
shared_state.append(3)
|
|
74
87
|
```
|
|
75
88
|
|
|
76
89
|
Set timeout per test group:
|
|
@@ -82,19 +95,58 @@ def test_with_timeout():
|
|
|
82
95
|
expensive_operation()
|
|
83
96
|
```
|
|
84
97
|
|
|
85
|
-
Tests without an explicit group
|
|
98
|
+
**Note:** Tests without an explicit `group` parameter each run in their own unique subprocess for maximum isolation.
|
|
99
|
+
|
|
100
|
+
### Class and Module Markers
|
|
101
|
+
|
|
102
|
+
Apply to entire classes to share state between methods:
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
@pytest.mark.isolated
|
|
106
|
+
class TestDatabase:
|
|
107
|
+
def test_setup(self):
|
|
108
|
+
self.db = create_database()
|
|
109
|
+
|
|
110
|
+
def test_query(self):
|
|
111
|
+
# Shares state with test_setup
|
|
112
|
+
result = self.db.query("SELECT 1")
|
|
113
|
+
assert result
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Apply to entire modules using `pytestmark`:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
import pytest
|
|
120
|
+
|
|
121
|
+
pytestmark = pytest.mark.isolated
|
|
122
|
+
|
|
123
|
+
def test_one():
|
|
124
|
+
# Runs in isolated subprocess
|
|
125
|
+
pass
|
|
126
|
+
|
|
127
|
+
def test_two():
|
|
128
|
+
# Shares subprocess with test_one
|
|
129
|
+
pass
|
|
130
|
+
```
|
|
86
131
|
|
|
87
132
|
## Configuration
|
|
88
133
|
|
|
89
134
|
### Command Line
|
|
90
135
|
|
|
91
136
|
```bash
|
|
137
|
+
# Run all tests in isolation (even without @pytest.mark.isolated)
|
|
138
|
+
pytest --isolated
|
|
139
|
+
|
|
92
140
|
# Set isolated test timeout (seconds)
|
|
93
141
|
pytest --isolated-timeout=60
|
|
94
142
|
|
|
95
143
|
# Disable subprocess isolation for debugging
|
|
96
144
|
pytest --no-isolation
|
|
97
145
|
|
|
146
|
+
# Control output capture (standard pytest flags work with isolated tests)
|
|
147
|
+
pytest -s # Disable capture, show all output
|
|
148
|
+
pytest --capture=sys # Capture at sys.stdout/stderr level
|
|
149
|
+
|
|
98
150
|
# Combine with pytest debugger
|
|
99
151
|
pytest --no-isolation --pdb
|
|
100
152
|
```
|
|
@@ -104,7 +156,6 @@ pytest --no-isolation --pdb
|
|
|
104
156
|
```ini
|
|
105
157
|
[pytest]
|
|
106
158
|
isolated_timeout = 300
|
|
107
|
-
isolated_capture_passed = false
|
|
108
159
|
```
|
|
109
160
|
|
|
110
161
|
Or in `pyproject.toml`:
|
|
@@ -112,7 +163,6 @@ Or in `pyproject.toml`:
|
|
|
112
163
|
```toml
|
|
113
164
|
[tool.pytest.ini_options]
|
|
114
165
|
isolated_timeout = "300"
|
|
115
|
-
isolated_capture_passed = false
|
|
116
166
|
```
|
|
117
167
|
|
|
118
168
|
## Use Cases
|
|
@@ -184,6 +234,18 @@ pytest --junitxml=report.xml --durations=10
|
|
|
184
234
|
|
|
185
235
|
## Advanced
|
|
186
236
|
|
|
237
|
+
### Coverage Integration
|
|
238
|
+
|
|
239
|
+
To collect coverage from isolated tests, enable subprocess tracking in `pyproject.toml`:
|
|
240
|
+
|
|
241
|
+
```toml
|
|
242
|
+
[tool.coverage.run]
|
|
243
|
+
parallel = true
|
|
244
|
+
concurrency = ["subprocess"]
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
See the [coverage.py subprocess documentation](https://coverage.readthedocs.io/en/latest/subprocess.html) for details.
|
|
248
|
+
|
|
187
249
|
### Timeout Handling
|
|
188
250
|
|
|
189
251
|
```bash
|
|
@@ -210,7 +272,7 @@ if os.environ.get("PYTEST_RUNNING_IN_SUBPROCESS") == "1":
|
|
|
210
272
|
|
|
211
273
|
**Tests timing out**: Increase timeout with `--isolated-timeout=600`
|
|
212
274
|
|
|
213
|
-
**Missing output**:
|
|
275
|
+
**Missing output**: Use `-s` or `--capture=no` to see output from passing tests, or `-v` for verbose output. pytest-isolated respects pytest's standard capture settings.
|
|
214
276
|
|
|
215
277
|
**Subprocess crashes**: Check for segfaults, OOM, or signal issues. Run with `-v` for details.
|
|
216
278
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
pytest_isolated/__init__.py,sha256=Rx5JwthqrahraDXAeDQkxTV9WXyw29nlQCrL-6RC72s,89
|
|
2
|
+
pytest_isolated/config.py,sha256=z8g5Pw5NUKuCuTosRtxR9IkzE6WaHhG2Zh8jJgBqwBU,2383
|
|
3
|
+
pytest_isolated/execution.py,sha256=tzYGwrbtfOAZHEX3mu52Du1iTm7T5fuiHNZRcIx6EWg,16644
|
|
4
|
+
pytest_isolated/grouping.py,sha256=jWYX8cdhqjIXVnq5DrSYImulPDsolPSb1DFGNUGBGvU,3248
|
|
5
|
+
pytest_isolated/plugin.py,sha256=Ieubhh2-CcmCS7IYf5HrGYFGstMyHzjNRpYTrWr-ghs,562
|
|
6
|
+
pytest_isolated/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
pytest_isolated/reporting.py,sha256=VXM8rc1o5-ug2aj02nkv87DtxDs43dejkN-udUPh59U,5869
|
|
8
|
+
pytest_isolated-0.4.1.dist-info/licenses/LICENSE,sha256=WECJyowi685PZSnKcA4Tqs7jukfzbnk7iMPLnm_q4JI,1067
|
|
9
|
+
pytest_isolated-0.4.1.dist-info/METADATA,sha256=S68b4OkZct1vVMJ3RAUml3us44kNox0ivnOILDSzr_k,7259
|
|
10
|
+
pytest_isolated-0.4.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
11
|
+
pytest_isolated-0.4.1.dist-info/entry_points.txt,sha256=HgRNPjIGoPBF1pkhma4UtaSwhpOVB8oZRZ0L1FcZXgk,45
|
|
12
|
+
pytest_isolated-0.4.1.dist-info/top_level.txt,sha256=FAtpozhvI-YaiFoZMepi9JAm6e87mW-TM1Ovu5xLOxg,16
|
|
13
|
+
pytest_isolated-0.4.1.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
pytest_isolated/__init__.py,sha256=b7RfFW9uJXumJ6DTDdg-VvSUEeh-Pc2srTjCKJRxB7k,89
|
|
2
|
-
pytest_isolated/plugin.py,sha256=ISfxTMyJVaddrqCFZOdBXFnC4E_Lh22gRUaNRb1Wo8I,15179
|
|
3
|
-
pytest_isolated/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
pytest_isolated-0.3.0.dist-info/licenses/LICENSE,sha256=WECJyowi685PZSnKcA4Tqs7jukfzbnk7iMPLnm_q4JI,1067
|
|
5
|
-
pytest_isolated-0.3.0.dist-info/METADATA,sha256=CDzpvrFqvUFguTk9_Yr32h88GatvKDHCO0d7CsVC5Ug,5384
|
|
6
|
-
pytest_isolated-0.3.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
7
|
-
pytest_isolated-0.3.0.dist-info/entry_points.txt,sha256=HgRNPjIGoPBF1pkhma4UtaSwhpOVB8oZRZ0L1FcZXgk,45
|
|
8
|
-
pytest_isolated-0.3.0.dist-info/top_level.txt,sha256=FAtpozhvI-YaiFoZMepi9JAm6e87mW-TM1Ovu5xLOxg,16
|
|
9
|
-
pytest_isolated-0.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|