Skip to content

Commit

Permalink
Fix: Logging issues with teardown (pytest-dev#690)
Browse files Browse the repository at this point in the history
  • Loading branch information
BeyondEvil authored Jul 22, 2023
1 parent f6f623d commit 2ce0aa6
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 40 deletions.
18 changes: 10 additions & 8 deletions src/pytest_html/basereport.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,15 +248,17 @@ def _process_logs(report):
log = []
if report.longreprtext:
log.append(report.longreprtext.replace("<", "&lt;").replace(">", "&gt;") + "\n")
for section in report.sections:
header, content = section
log.append(f"{' ' + header + ' ':-^80}\n{content}")

# weird formatting related to logs
if "log" in header:
log.append("")
if "call" in header:
# Don't add captured output to reruns
if report.outcome != "rerun":
for section in report.sections:
header, content = section
log.append(f"{' ' + header + ' ':-^80}\n{content}")

# weird formatting related to logs
if "log" in header:
log.append("")
if "call" in header:
log.append("")
if not log:
log.append("No log output captured.")
return log
Expand Down
19 changes: 10 additions & 9 deletions src/pytest_html/report_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def set_data(self, key, value):
def add_test(self, test_data, report, logs):
# regardless of pass or fail we must add teardown logging to "call"
if report.when == "teardown":
self.update_test_log(report)
self.append_teardown_log(report)

# passed "setup" and "teardown" are not added to the html
if report.when == "call" or (
Expand All @@ -79,12 +79,13 @@ def add_test(self, test_data, report, logs):

return False

def update_test_log(self, report):
def append_teardown_log(self, report):
log = []
for test in self._data["tests"][report.nodeid]:
if test["testId"] == report.nodeid and "log" in test:
for section in report.sections:
header, content = section
if "teardown" in header:
log.append(f"{' ' + header + ' ':-^80}\n{content}")
test["log"] += _handle_ansi("\n".join(log))
if self._data["tests"][report.nodeid]:
# Last index is "call"
test = self._data["tests"][report.nodeid][-1]
for section in report.sections:
header, content = section
if "teardown" in header:
log.append(f"{' ' + header + ' ':-^80}\n{content}")
test["log"] += _handle_ansi("\n".join(log))
58 changes: 35 additions & 23 deletions testing/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -759,25 +759,29 @@ def log_cli(self, pytester):

@pytest.fixture
def test_file(self):
return """
import pytest
import logging
@pytest.fixture
def setup():
logging.info("this is setup")
{setup}
yield
logging.info("this is teardown")
{teardown}
def formatter(assertion, setup="", teardown="", flaky=""):
return f"""
import pytest
import logging
@pytest.fixture
def setup():
logging.info("this is setup")
{setup}
yield
logging.info("this is teardown")
{teardown}
{flaky}
def test_logging(setup):
logging.info("this is test")
assert {assertion}
"""

def test_logging(setup):
logging.info("this is test")
assert {assertion}
"""
return formatter

@pytest.mark.usefixtures("log_cli")
def test_all_pass(self, test_file, pytester):
pytester.makepyfile(test_file.format(setup="", teardown="", assertion=True))
pytester.makepyfile(test_file(assertion=True))
page = run(pytester)
assert_results(page, passed=1)

Expand All @@ -787,9 +791,7 @@ def test_all_pass(self, test_file, pytester):

@pytest.mark.usefixtures("log_cli")
def test_setup_error(self, test_file, pytester):
pytester.makepyfile(
test_file.format(setup="error", teardown="", assertion=True)
)
pytester.makepyfile(test_file(assertion=True, setup="error"))
page = run(pytester)
assert_results(page, error=1)

Expand All @@ -800,7 +802,7 @@ def test_setup_error(self, test_file, pytester):

@pytest.mark.usefixtures("log_cli")
def test_test_fails(self, test_file, pytester):
pytester.makepyfile(test_file.format(setup="", teardown="", assertion=False))
pytester.makepyfile(test_file(assertion=False))
page = run(pytester)
assert_results(page, failed=1)

Expand All @@ -813,9 +815,7 @@ def test_test_fails(self, test_file, pytester):
"assertion, result", [(True, {"passed": 1}), (False, {"failed": 1})]
)
def test_teardown_error(self, test_file, pytester, assertion, result):
pytester.makepyfile(
test_file.format(setup="", teardown="error", assertion=assertion)
)
pytester.makepyfile(test_file(assertion=assertion, teardown="error"))
page = run(pytester)
assert_results(page, error=1, **result)

Expand All @@ -825,7 +825,7 @@ def test_teardown_error(self, test_file, pytester, assertion, result):
assert_that(log).matches(self.LOG_LINE_REGEX.format(when))

def test_no_log(self, test_file, pytester):
pytester.makepyfile(test_file.format(setup="", teardown="", assertion=True))
pytester.makepyfile(test_file(assertion=True))
page = run(pytester)
assert_results(page, passed=1)

Expand All @@ -834,6 +834,18 @@ def test_no_log(self, test_file, pytester):
for when in ["setup", "test", "teardown"]:
assert_that(log).does_not_match(self.LOG_LINE_REGEX.format(when))

@pytest.mark.usefixtures("log_cli")
def test_rerun(self, test_file, pytester):
pytester.makepyfile(
test_file(assertion=False, flaky="@pytest.mark.flaky(reruns=2)")
)
page = run(pytester, query_params={"visible": "failed"})
assert_results(page, failed=1, rerun=2)

log = get_log(page)
assert_that(log.count("Captured log setup")).is_equal_to(3)
assert_that(log.count("Captured log teardown")).is_equal_to(5)


class TestCollapsedQueryParam:
@pytest.fixture
Expand Down

0 comments on commit 2ce0aa6

Please sign in to comment.