Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Logging issues with teardown #690

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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