Coverage for /usr/local/lib/python3.7/site-packages/_pytest/stepwise.py : 21%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import pytest
4def pytest_addoption(parser):
5 group = parser.getgroup("general")
6 group.addoption(
7 "--sw",
8 "--stepwise",
9 action="store_true",
10 dest="stepwise",
11 help="exit on test failure and continue from last failing test next time",
12 )
13 group.addoption(
14 "--stepwise-skip",
15 action="store_true",
16 dest="stepwise_skip",
17 help="ignore the first failing test but stop on the next failing test",
18 )
21@pytest.hookimpl
22def pytest_configure(config):
23 config.pluginmanager.register(StepwisePlugin(config), "stepwiseplugin")
26class StepwisePlugin:
27 def __init__(self, config):
28 self.config = config
29 self.active = config.getvalue("stepwise")
30 self.session = None
31 self.report_status = ""
33 if self.active:
34 self.lastfailed = config.cache.get("cache/stepwise", None)
35 self.skip = config.getvalue("stepwise_skip")
37 def pytest_sessionstart(self, session):
38 self.session = session
40 def pytest_collection_modifyitems(self, session, config, items):
41 if not self.active:
42 return
43 if not self.lastfailed:
44 self.report_status = "no previously failed tests, not skipping."
45 return
47 already_passed = []
48 found = False
50 # Make a list of all tests that have been run before the last failing one.
51 for item in items:
52 if item.nodeid == self.lastfailed:
53 found = True
54 break
55 else:
56 already_passed.append(item)
58 # If the previously failed test was not found among the test items,
59 # do not skip any tests.
60 if not found:
61 self.report_status = "previously failed test not found, not skipping."
62 already_passed = []
63 else:
64 self.report_status = "skipping {} already passed items.".format(
65 len(already_passed)
66 )
68 for item in already_passed:
69 items.remove(item)
71 config.hook.pytest_deselected(items=already_passed)
73 def pytest_runtest_logreport(self, report):
74 if not self.active:
75 return
77 if report.failed:
78 if self.skip:
79 # Remove test from the failed ones (if it exists) and unset the skip option
80 # to make sure the following tests will not be skipped.
81 if report.nodeid == self.lastfailed:
82 self.lastfailed = None
84 self.skip = False
85 else:
86 # Mark test as the last failing and interrupt the test session.
87 self.lastfailed = report.nodeid
88 self.session.shouldstop = (
89 "Test failed, continuing from this test next run."
90 )
92 else:
93 # If the test was actually run and did pass.
94 if report.when == "call":
95 # Remove test from the failed ones, if exists.
96 if report.nodeid == self.lastfailed:
97 self.lastfailed = None
99 def pytest_report_collectionfinish(self):
100 if self.active and self.config.getoption("verbose") >= 0 and self.report_status:
101 return "stepwise: %s" % self.report_status
103 def pytest_sessionfinish(self, session):
104 if self.active:
105 self.config.cache.set("cache/stepwise", self.lastfailed)
106 else:
107 # Clear the list of failing tests if the plugin is not active.
108 self.config.cache.set("cache/stepwise", [])