GeezerVison is showing github.com — Use pytest data to extract the parametrised decoration (#17881) · haedeu/vscode-python@251cb30
File treeExpand file treeCollapse file tree Open diff view settings testing_tools/adapter/pytest tests/testing_tools/adapter/pytest
Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboard +2Lines changed: 2 additions & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +When parsing pytest node ids with parameters, use native pytest information to separate out the parameter decoration rather than try and parse the nodeid as text. | | 2 | +(thanks [Martijn Pieters](https://github.com/mjpieters)) |
Collapse file Copy file name to clipboardExpand all lines: pythonFiles/testing_tools/adapter/pytest/_pytest_item.py +15-39Lines changed: 15 additions & 39 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -158,9 +158,21 @@ def parse_item( | 158 | 158 | # Skip plugin generated tests | 159 | 159 | if kind is None: | 160 | 160 | return None, None | 161 | | - (nodeid, parents, fileid, testfunc, parameterized) = _parse_node_id( | 162 | | - item.nodeid, kind | 163 | | - ) | | 161 | + | | 162 | + if kind == "function" and item.originalname and item.originalname != item.name: | | 163 | + # split out parametrized decorations `node[params]`) before parsing | | 164 | + # and manually attach parametrized portion back in when done. | | 165 | + parameterized = item.name[len(item.originalname) :] | | 166 | + (parentid, parents, fileid, testfunc, _) = _parse_node_id( | | 167 | + item.nodeid[: -len(parameterized)], kind | | 168 | + ) | | 169 | + nodeid = "{}{}".format(parentid, parameterized) | | 170 | + parents = [(parentid, item.originalname, kind)] + parents | | 171 | + else: | | 172 | + (nodeid, parents, fileid, testfunc, parameterized) = _parse_node_id( | | 173 | + item.nodeid, kind | | 174 | + ) | | 175 | + | 164 | 176 | # Note: testfunc does not necessarily match item.function.__name__. | 165 | 177 | # This can result from importing a test function from another module. | 166 | 178 |
| @@ -434,32 +446,6 @@ def _parse_node_id( | 434 | 446 | ) | 435 | 447 |
| 436 | 448 |
| 437 | | -def _find_left_bracket(nodeid): | 438 | | - """Return tuple of part before final bracket open, separator [, and the remainder. | 439 | | - Notes: | 440 | | - Testcase names in case of parametrized tests are wrapped in [<test-case-name>]. | 441 | | - Examples: | 442 | | - dirname[sometext]/dirname/testfile.py::testset::testname[testcase] | 443 | | - => ('dirname[sometext]/dirname/testfile.py::testset::testname', '[', 'testcase]') | 444 | | - dirname/dirname/testfile.py::testset::testname[testcase] | 445 | | - => ('dirname/dirname/testfile.py::testset::testname', '[', 'testcase]') | 446 | | - dirname/dirname/testfile.py::testset::testname[testcase[x]] | 447 | | - => ('dirname/dirname/testfile.py::testset::testname', '[', 'testcase[x]]') | 448 | | - """ | 449 | | - if not nodeid.endswith("]"): | 450 | | - return nodeid, "", "" | 451 | | - bracketcount = 0 | 452 | | - for index, char in enumerate(nodeid[::-1]): | 453 | | - if char == "]": | 454 | | - bracketcount += 1 | 455 | | - elif char == "[": | 456 | | - bracketcount -= 1 | 457 | | - if bracketcount == 0: | 458 | | - n = len(nodeid) - 1 - index | 459 | | - return nodeid[:n], nodeid[n], nodeid[n + 1 :] | 460 | | - return nodeid, "", "" | 461 | | - | 462 | | - | 463 | 449 | def _iter_nodes( | 464 | 450 | testid, | 465 | 451 | kind, | @@ -473,16 +459,6 @@ def _iter_nodes( | 473 | 459 | if len(nodeid) > len(testid): | 474 | 460 | testid = "." + _pathsep + testid | 475 | 461 |
| 476 | | - if kind == "function" and nodeid.endswith("]"): | 477 | | - funcid, sep, parameterized = _find_left_bracket(nodeid) | 478 | | - if not sep: | 479 | | - raise should_never_reach_here( | 480 | | - nodeid, | 481 | | - # ... | 482 | | - ) | 483 | | - yield (nodeid, sep + parameterized, "subtest") | 484 | | - nodeid = funcid | 485 | | - | 486 | 462 | parentid, _, name = nodeid.rpartition("::") | 487 | 463 | if not parentid: | 488 | 464 | if kind is None: | |
Collapse file Copy file name to clipboardExpand all lines: pythonFiles/tests/testing_tools/adapter/pytest/test_discovery.py +14Lines changed: 14 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -530,6 +530,7 @@ def test_modifyitems(self): | 530 | 530 | stub, | 531 | 531 | nodeid="test_spam.py::SpamTests::test_one", | 532 | 532 | name="test_one", | | 533 | + originalname=None, | 533 | 534 | location=("test_spam.py", 12, "SpamTests.test_one"), | 534 | 535 | fspath=adapter_util.PATH_JOIN(testroot, "test_spam.py"), | 535 | 536 | function=FakeFunc("test_one"), | @@ -538,6 +539,7 @@ def test_modifyitems(self): | 538 | 539 | stub, | 539 | 540 | nodeid="test_spam.py::SpamTests::test_other", | 540 | 541 | name="test_other", | | 542 | + originalname=None, | 541 | 543 | location=("test_spam.py", 19, "SpamTests.test_other"), | 542 | 544 | fspath=adapter_util.PATH_JOIN(testroot, "test_spam.py"), | 543 | 545 | function=FakeFunc("test_other"), | @@ -546,6 +548,7 @@ def test_modifyitems(self): | 546 | 548 | stub, | 547 | 549 | nodeid="test_spam.py::test_all", | 548 | 550 | name="test_all", | | 551 | + originalname=None, | 549 | 552 | location=("test_spam.py", 144, "test_all"), | 550 | 553 | fspath=adapter_util.PATH_JOIN(testroot, "test_spam.py"), | 551 | 554 | function=FakeFunc("test_all"), | @@ -554,6 +557,7 @@ def test_modifyitems(self): | 554 | 557 | stub, | 555 | 558 | nodeid="test_spam.py::test_each[10-10]", | 556 | 559 | name="test_each[10-10]", | | 560 | + originalname="test_each", | 557 | 561 | location=("test_spam.py", 273, "test_each[10-10]"), | 558 | 562 | fspath=adapter_util.PATH_JOIN(testroot, "test_spam.py"), | 559 | 563 | function=FakeFunc("test_each"), | @@ -562,6 +566,7 @@ def test_modifyitems(self): | 562 | 566 | stub, | 563 | 567 | nodeid=relfile2 + "::All::BasicTests::test_first", | 564 | 568 | name="test_first", | | 569 | + originalname=None, | 565 | 570 | location=(relfile2, 31, "All.BasicTests.test_first"), | 566 | 571 | fspath=adapter_util.PATH_JOIN(testroot, relfile2), | 567 | 572 | function=FakeFunc("test_first"), | @@ -570,6 +575,7 @@ def test_modifyitems(self): | 570 | 575 | stub, | 571 | 576 | nodeid=relfile2 + "::All::BasicTests::test_each[1+2-3]", | 572 | 577 | name="test_each[1+2-3]", | | 578 | + originalname="test_each", | 573 | 579 | location=(relfile2, 62, "All.BasicTests.test_each[1+2-3]"), | 574 | 580 | fspath=adapter_util.PATH_JOIN(testroot, relfile2), | 575 | 581 | function=FakeFunc("test_each"), | @@ -781,6 +787,7 @@ def test_finish(self): | 781 | 787 | stub, | 782 | 788 | nodeid=relfile + "::SpamTests::test_spam", | 783 | 789 | name="test_spam", | | 790 | + originalname=None, | 784 | 791 | location=(relfile, 12, "SpamTests.test_spam"), | 785 | 792 | fspath=adapter_util.PATH_JOIN(testroot, relfile), | 786 | 793 | function=FakeFunc("test_spam"), | @@ -992,6 +999,7 @@ def test_nested_brackets(self): | 992 | 999 | stub, | 993 | 1000 | nodeid=relfile + "::SpamTests::test_spam[a-[b]-c]", | 994 | 1001 | name="test_spam[a-[b]-c]", | | 1002 | + originalname="test_spam", | 995 | 1003 | location=(relfile, 12, "SpamTests.test_spam[a-[b]-c]"), | 996 | 1004 | fspath=adapter_util.PATH_JOIN(testroot, relfile), | 997 | 1005 | function=FakeFunc("test_spam"), | @@ -1054,6 +1062,7 @@ def test_nested_suite(self): | 1054 | 1062 | stub, | 1055 | 1063 | nodeid=relfile + "::SpamTests::Ham::Eggs::test_spam", | 1056 | 1064 | name="test_spam", | | 1065 | + originalname=None, | 1057 | 1066 | location=(relfile, 12, "SpamTests.Ham.Eggs.test_spam"), | 1058 | 1067 | fspath=adapter_util.PATH_JOIN(testroot, relfile), | 1059 | 1068 | function=FakeFunc("test_spam"), | @@ -1120,6 +1129,7 @@ def test_windows(self): | 1120 | 1129 | # pytest always uses "/" as the path separator in node IDs: | 1121 | 1130 | nodeid="X/Y/Z/test_Eggs.py::SpamTests::test_spam", | 1122 | 1131 | name="test_spam", | | 1132 | + originalname=None, | 1123 | 1133 | # normal path separator (contrast with nodeid): | 1124 | 1134 | location=(relfile, 12, "SpamTests.test_spam"), | 1125 | 1135 | # path separator matches location: | @@ -1152,6 +1162,7 @@ def test_windows(self): | 1152 | 1162 | stub, | 1153 | 1163 | nodeid=fileid + "::test_spam", | 1154 | 1164 | name="test_spam", | | 1165 | + originalname=None, | 1155 | 1166 | location=(locfile, 12, "test_spam"), | 1156 | 1167 | fspath=fspath, | 1157 | 1168 | function=FakeFunc("test_spam"), | @@ -1412,6 +1423,7 @@ def test_mysterious_parens(self): | 1412 | 1423 | stub, | 1413 | 1424 | nodeid=relfile + "::SpamTests::()::()::test_spam", | 1414 | 1425 | name="test_spam", | | 1426 | + originalname=None, | 1415 | 1427 | location=(relfile, 12, "SpamTests.test_spam"), | 1416 | 1428 | fspath=adapter_util.PATH_JOIN(testroot, relfile), | 1417 | 1429 | function=FakeFunc("test_spam"), | @@ -1472,6 +1484,7 @@ def test_imported_test(self): | 1472 | 1484 | stub, | 1473 | 1485 | nodeid=relfile + "::SpamTests::test_spam", | 1474 | 1486 | name="test_spam", | | 1487 | + originalname=None, | 1475 | 1488 | location=(srcfile, 12, "SpamTests.test_spam"), | 1476 | 1489 | fspath=adapter_util.PATH_JOIN(testroot, relfile), | 1477 | 1490 | function=FakeFunc("test_spam"), | @@ -1480,6 +1493,7 @@ def test_imported_test(self): | 1480 | 1493 | stub, | 1481 | 1494 | nodeid=relfile + "::test_ham", | 1482 | 1495 | name="test_ham", | | 1496 | + originalname=None, | 1483 | 1497 | location=(srcfile, 3, "test_ham"), | 1484 | 1498 | fspath=adapter_util.PATH_JOIN(testroot, relfile), | 1485 | 1499 | function=FakeFunc("test_spam"), | |
|