Skip to content

refactor: enhance error reporting in pytest output for better debugging #3943

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

Merged
merged 7 commits into from
May 22, 2025
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
1 change: 1 addition & 0 deletions doc/changelog.d/3943.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
refactor: enhance error reporting in pytest output for better debugging
94 changes: 88 additions & 6 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,24 +315,106 @@ class MyReporter(TerminalReporter):
def short_test_summary(self):
# your own impl goes here, for example:
self.write_sep("=", "PyMAPDL Pytest short summary")
markup = self._tw.markup

if self.hasmarkup:
color = True
else:
color = False

ERROR_COLOR = {"Red": color, "bold": True}
FAILED_COLOR = {"red": color, "bold": True}
PASSED_COLOR = {"green": color}
SKIPPED_COLOR = {"green": color, "bold": True}
XPASSED_COLOR = {"Yellow": color, "bold": True}
XFAILED_COLOR = {"yellow": color}

# self._tw.markup("asdf", Red=True)

def get_normal_message(rep, header, message):
location = rep.location
if message:
message = f" - {message}"

if location[0] == location[2]:
return f"{header} {rep.head_line}{message}"
else:
path = f"{location[0]}:{location[1]}"
return f"{header} {rep.head_line} - {path}{message}"

def get_failure_message(rep, header, message):
location = rep.location
path = f"{location[0]}:{location[1]}"
cause = message.splitlines()
cause = " ".join(
[
each[2:].strip() if each.startswith("E ") else each.strip()
for each in cause
]
)

return f"{header} {rep.head_line} - {path}: {cause}"

def get_skip_message(rep):
message = rep.longrepr[2]
header = markup("[SKIPPED]", **SKIPPED_COLOR)
return get_normal_message(rep, header, message)

def get_passed_message(rep):
message = rep.longreprtext
header = markup("[PASSED]", **PASSED_COLOR)
return get_normal_message(rep, header, message)

def get_xfailed_message(rep):
message = " ".join(rep.longrepr.reprcrash.message.split(":")[1:]).strip()
header = markup("[XFAILED]", **XFAILED_COLOR)
return get_normal_message(rep, header, message)

def get_xpassed_message(rep):
message = rep.longreprtext
header = markup("[XPASSED]", **XPASSED_COLOR)
return get_normal_message(rep, header, message)

def get_error_message(rep):
message = rep.longrepr.reprcrash.message
header = markup("[ERROR]", **ERROR_COLOR)
return get_failure_message(rep, header, message)

def get_failed_message(rep):
message = rep.longrepr.reprcrash.message
header = markup("[FAILED]", **FAILED_COLOR)
return get_failure_message(rep, header, message)

failed = self.stats.get("failed", [])
for rep in failed:
self.write_line(
f"[FAILED] {rep.head_line} - {rep.longreprtext.splitlines()[-3]}"
)
self.write_line(get_failed_message(rep))

skipped = self.stats.get("skipped", [])
for rep in skipped:
self.write_line(get_skip_message(rep))

errored = self.stats.get("error", [])
for rep in errored:
self.write_line(
f"[ERROR] {rep.head_line} - {rep.longreprtext.splitlines()[-3]}"
)
self.write_line(get_error_message(rep))

passed = self.stats.get("passed", [])
for rep in passed:
self.write_line(get_passed_message(rep))

xpassed = self.stats.get("xpassed", [])
for rep in xpassed:
self.write_line(get_xpassed_message(rep))

xfailed = self.stats.get("xfailed", [])
for rep in xfailed:
self.write_line(get_xfailed_message(rep))


@pytest.hookimpl(trylast=True)
def pytest_configure(config):
vanilla_reporter = config.pluginmanager.getplugin("terminalreporter")
my_reporter = MyReporter(config)
my_reporter._tw.fullwidth = 160
config.pluginmanager.unregister(vanilla_reporter)
config.pluginmanager.register(my_reporter, "terminalreporter")

Expand Down
5 changes: 4 additions & 1 deletion tests/test_krylov.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@

if not has_dependency("ansys-math-core"):
# Needs ansys-math-core
pytest.skip(allow_module_level=True)
pytest.skip(
allow_module_level=True,
reason="Skipping because 'ansys-math-core' is not installed",
)

PATH = os.path.dirname(os.path.abspath(__file__))

Expand Down
5 changes: 4 additions & 1 deletion tests/test_launcher_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
from conftest import has_dependency

if not has_dependency("ansys-platform-instancemanagement"):
pytest.skip(allow_module_level=True)
pytest.skip(
allow_module_level=True,
reason="Skipping because 'ansys-platform-instancemanagement' is not installed",
)

from unittest.mock import create_autospec

Expand Down
4 changes: 3 additions & 1 deletion tests/test_plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
from conftest import has_dependency, requires

if not has_dependency("pyvista"):
pytest.skip(allow_module_level=True)
pytest.skip(
allow_module_level=True, reason="Skipping because 'pyvista' is not installed"
)

from ansys.mapdl.core.errors import ComponentDoesNotExits, MapdlRuntimeError
from ansys.mapdl.core.plotting import GraphicsBackend
Expand Down
4 changes: 3 additions & 1 deletion tests/test_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@

# skipping if ON_STUDENT and ON_LOCAL because we cannot spawn that many instances.
if ON_STUDENT:
pytest.skip(allow_module_level=True)
pytest.skip(
allow_module_level=True, reason="Skipping Pool tests on student version."
)


skip_if_ignore_pool = pytest.mark.skipif(
Expand Down
4 changes: 3 additions & 1 deletion tests/test_theme.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
from conftest import has_dependency

if not has_dependency("pyvista"):
pytest.skip(allow_module_level=True)
pytest.skip(
allow_module_level=True, reason="Skipping because 'pyvista' is not installed"
)

import matplotlib
import numpy as np
Expand Down