diff --git a/changelog/5914.bugfix.rst b/changelog/5914.bugfix.rst new file mode 100644 index 000000000..b62b0b3c0 --- /dev/null +++ b/changelog/5914.bugfix.rst @@ -0,0 +1 @@ +pytester: fix ``no_fnmatch_line`` when used after positive matching. diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 02414a299..bacb1c23d 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -1438,8 +1438,10 @@ class LineMatcher: self._log("{:>{width}}".format("and:", width=wnick), repr(nextline)) extralines.append(nextline) else: - self._log("remains unmatched: {!r}".format(line)) - pytest.fail(self._log_text.lstrip()) + msg = "remains unmatched: {!r}".format(line) + self._log(msg) + self._fail(msg) + self._log_output = [] def no_fnmatch_line(self, pat): """Ensure captured lines do not match the given pattern, using ``fnmatch.fnmatch``. @@ -1465,18 +1467,20 @@ class LineMatcher: __tracebackhide__ = True nomatch_printed = False wnick = len(match_nickname) + 1 - try: - for line in self.lines: - if match_func(line, pat): - self._log("%s:" % match_nickname, repr(pat)) - self._log("{:>{width}}".format("with:", width=wnick), repr(line)) - pytest.fail(self._log_text.lstrip()) - else: - if not nomatch_printed: - self._log( - "{:>{width}}".format("nomatch:", width=wnick), repr(pat) - ) - nomatch_printed = True - self._log("{:>{width}}".format("and:", width=wnick), repr(line)) - finally: - self._log_output = [] + for line in self.lines: + if match_func(line, pat): + msg = "{}: {!r}".format(match_nickname, pat) + self._log(msg) + self._log("{:>{width}}".format("with:", width=wnick), repr(line)) + self._fail(msg) + else: + if not nomatch_printed: + self._log("{:>{width}}".format("nomatch:", width=wnick), repr(pat)) + nomatch_printed = True + self._log("{:>{width}}".format("and:", width=wnick), repr(line)) + self._log_output = [] + + def _fail(self, msg): + log_text = self._log_text + self._log_output = [] + pytest.fail(log_text) diff --git a/testing/test_pytester.py b/testing/test_pytester.py index 758e999dc..5bdbacdd0 100644 --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -530,7 +530,7 @@ def test_no_matching(function): ] else: assert obtained == [ - "nomatch: '{}'".format(good_pattern), + " nomatch: '{}'".format(good_pattern), " and: 'cachedir: .pytest_cache'", " and: 'collecting ... collected 1 item'", " and: ''", @@ -542,6 +542,14 @@ def test_no_matching(function): func(bad_pattern) # bad pattern does not match any line: passes +def test_no_matching_after_match(): + lm = LineMatcher(["1", "2", "3"]) + lm.fnmatch_lines(["1", "3"]) + with pytest.raises(pytest.fail.Exception) as e: + lm.no_fnmatch_line("*") + assert str(e.value).splitlines() == ["fnmatch: '*'", " with: '1'"] + + def test_pytester_addopts(request, monkeypatch): monkeypatch.setenv("PYTEST_ADDOPTS", "--orig-unused")