|
1 | 1 | import sys
|
| 2 | +import textwrap |
2 | 3 |
|
3 | 4 | import pytest
|
4 | 5 | from _pytest.pytester import Pytester
|
@@ -155,6 +156,136 @@ def test_func(self):
|
155 | 156 | assert skipped
|
156 | 157 | assert skipped.reason == "condition: config._hackxyz"
|
157 | 158 |
|
| 159 | + def test_skipif_markeval_namespace(self, pytester: Pytester) -> None: |
| 160 | + pytester.makeconftest( |
| 161 | + """ |
| 162 | + import pytest |
| 163 | +
|
| 164 | + def pytest_markeval_namespace(): |
| 165 | + return {"color": "green"} |
| 166 | + """ |
| 167 | + ) |
| 168 | + p = pytester.makepyfile( |
| 169 | + """ |
| 170 | + import pytest |
| 171 | +
|
| 172 | + @pytest.mark.skipif("color == 'green'") |
| 173 | + def test_1(): |
| 174 | + assert True |
| 175 | +
|
| 176 | + @pytest.mark.skipif("color == 'red'") |
| 177 | + def test_2(): |
| 178 | + assert True |
| 179 | + """ |
| 180 | + ) |
| 181 | + res = pytester.runpytest(p) |
| 182 | + assert res.ret == 0 |
| 183 | + res.stdout.fnmatch_lines(["*1 skipped*"]) |
| 184 | + res.stdout.fnmatch_lines(["*1 passed*"]) |
| 185 | + |
| 186 | + def test_skipif_markeval_namespace_multiple(self, pytester: Pytester) -> None: |
| 187 | + """Keys defined by ``pytest_markeval_namespace()`` in nested plugins override top-level ones.""" |
| 188 | + root = pytester.mkdir("root") |
| 189 | + root.joinpath("__init__.py").touch() |
| 190 | + root.joinpath("conftest.py").write_text( |
| 191 | + textwrap.dedent( |
| 192 | + """\ |
| 193 | + import pytest |
| 194 | +
|
| 195 | + def pytest_markeval_namespace(): |
| 196 | + return {"arg": "root"} |
| 197 | + """ |
| 198 | + ) |
| 199 | + ) |
| 200 | + root.joinpath("test_root.py").write_text( |
| 201 | + textwrap.dedent( |
| 202 | + """\ |
| 203 | + import pytest |
| 204 | +
|
| 205 | + @pytest.mark.skipif("arg == 'root'") |
| 206 | + def test_root(): |
| 207 | + assert False |
| 208 | + """ |
| 209 | + ) |
| 210 | + ) |
| 211 | + foo = root.joinpath("foo") |
| 212 | + foo.mkdir() |
| 213 | + foo.joinpath("__init__.py").touch() |
| 214 | + foo.joinpath("conftest.py").write_text( |
| 215 | + textwrap.dedent( |
| 216 | + """\ |
| 217 | + import pytest |
| 218 | +
|
| 219 | + def pytest_markeval_namespace(): |
| 220 | + return {"arg": "foo"} |
| 221 | + """ |
| 222 | + ) |
| 223 | + ) |
| 224 | + foo.joinpath("test_foo.py").write_text( |
| 225 | + textwrap.dedent( |
| 226 | + """\ |
| 227 | + import pytest |
| 228 | +
|
| 229 | + @pytest.mark.skipif("arg == 'foo'") |
| 230 | + def test_foo(): |
| 231 | + assert False |
| 232 | + """ |
| 233 | + ) |
| 234 | + ) |
| 235 | + bar = root.joinpath("bar") |
| 236 | + bar.mkdir() |
| 237 | + bar.joinpath("__init__.py").touch() |
| 238 | + bar.joinpath("conftest.py").write_text( |
| 239 | + textwrap.dedent( |
| 240 | + """\ |
| 241 | + import pytest |
| 242 | +
|
| 243 | + def pytest_markeval_namespace(): |
| 244 | + return {"arg": "bar"} |
| 245 | + """ |
| 246 | + ) |
| 247 | + ) |
| 248 | + bar.joinpath("test_bar.py").write_text( |
| 249 | + textwrap.dedent( |
| 250 | + """\ |
| 251 | + import pytest |
| 252 | +
|
| 253 | + @pytest.mark.skipif("arg == 'bar'") |
| 254 | + def test_bar(): |
| 255 | + assert False |
| 256 | + """ |
| 257 | + ) |
| 258 | + ) |
| 259 | + |
| 260 | + reprec = pytester.inline_run("-vs", "--capture=no") |
| 261 | + reprec.assertoutcome(skipped=3) |
| 262 | + |
| 263 | + def test_skipif_markeval_namespace_ValueError(self, pytester: Pytester) -> None: |
| 264 | + pytester.makeconftest( |
| 265 | + """ |
| 266 | + import pytest |
| 267 | +
|
| 268 | + def pytest_markeval_namespace(): |
| 269 | + return True |
| 270 | + """ |
| 271 | + ) |
| 272 | + p = pytester.makepyfile( |
| 273 | + """ |
| 274 | + import pytest |
| 275 | +
|
| 276 | + @pytest.mark.skipif("color == 'green'") |
| 277 | + def test_1(): |
| 278 | + assert True |
| 279 | + """ |
| 280 | + ) |
| 281 | + res = pytester.runpytest(p) |
| 282 | + assert res.ret == 1 |
| 283 | + res.stdout.fnmatch_lines( |
| 284 | + [ |
| 285 | + "*ValueError: pytest_markeval_namespace() needs to return a dict, got True*" |
| 286 | + ] |
| 287 | + ) |
| 288 | + |
158 | 289 |
|
159 | 290 | class TestXFail:
|
160 | 291 | @pytest.mark.parametrize("strict", [True, False])
|
@@ -577,6 +708,33 @@ def test_foo():
|
577 | 708 | result.stdout.fnmatch_lines(["*1 failed*" if strict else "*1 xpassed*"])
|
578 | 709 | assert result.ret == (1 if strict else 0)
|
579 | 710 |
|
| 711 | + def test_xfail_markeval_namespace(self, pytester: Pytester) -> None: |
| 712 | + pytester.makeconftest( |
| 713 | + """ |
| 714 | + import pytest |
| 715 | +
|
| 716 | + def pytest_markeval_namespace(): |
| 717 | + return {"color": "green"} |
| 718 | + """ |
| 719 | + ) |
| 720 | + p = pytester.makepyfile( |
| 721 | + """ |
| 722 | + import pytest |
| 723 | +
|
| 724 | + @pytest.mark.xfail("color == 'green'") |
| 725 | + def test_1(): |
| 726 | + assert False |
| 727 | +
|
| 728 | + @pytest.mark.xfail("color == 'red'") |
| 729 | + def test_2(): |
| 730 | + assert False |
| 731 | + """ |
| 732 | + ) |
| 733 | + res = pytester.runpytest(p) |
| 734 | + assert res.ret == 1 |
| 735 | + res.stdout.fnmatch_lines(["*1 failed*"]) |
| 736 | + res.stdout.fnmatch_lines(["*1 xfailed*"]) |
| 737 | + |
580 | 738 |
|
581 | 739 | class TestXFailwithSetupTeardown:
|
582 | 740 | def test_failing_setup_issue9(self, pytester: Pytester) -> None:
|
|
0 commit comments