Skip to content

Fix ipytest error-display mislabeling#372

Open
edoardob90 wants to merge 3 commits intomainfrom
fix/345-ipytest-error-display
Open

Fix ipytest error-display mislabeling#372
edoardob90 wants to merge 3 commits intomainfrom
fix/345-ipytest-error-display

Conversation

@edoardob90
Copy link
Copy Markdown
Member

@edoardob90 edoardob90 commented Apr 15, 2026

Summary

Partially addresses #345 – three small display-layer fixes in tutorial/tests/testsuite/ that stop students from seeing "🚨 Syntax Error" for problems that are not syntax errors.

#345 requires another refactor: the traceback-walk TODO at helpers.py:764 remains open and is better addressed in the standalone-testsuite rewrite. Full reasoning in this comment on #345.

Three changes were made

  1. Route _pytest.outcomes.Failed to TestOutcome.FAIL, so failing pytest.raises(X) renders as ❌ Failed: DID NOT RAISE X (the original ResultCollector exception handling: improvement for pytest.raises() failures #345 proposal).
  2. Branch the TEST_ERROR banner on the actual exception class: real SyntaxError/IndentationError stay 🚨 Syntax Error; everything else (AttributeError from None.shape, etc.) becomes ⚠️ Runtime Error (<ExcName>).
  3. Stop downgrading TESTS_FAILED runs to PYTEST_ERROR when any test errors, so mixed runs render per-row instead of as a single catch-all panel. PYTEST_ERROR stays live for the INTERNAL_ERROR and compile-error paths.

Each change is an independent commit, reviewable and revertible.

Test plan

Manual smoke tests in live notebooks (no unit-test exists for the display layer):

  • Commit 1 – in 02_control_flow.ipynb, set solution_base_converter body to return 42; run; expect ❌ Failed: DID NOT RAISE ValueError, not 🚨 Syntax Error.
  • Commit 2 – in magic_example.ipynb, set the student solution body to bare return; run; expect ⚠️ Runtime Error (<ExcName>). Then break the cell with def f(: pass; expect 🚨 Syntax Error still fires (regression guard for the COMPILE_ERROR path).
  • Commit 3 – a parametrized cell where the solution passes most cases but raises on one; expect per-row mix of and ⚠️, not a single catch-all panel.

Pre-flight (ruff check, ruff format --check, pre-commit run) clean on the modified files.

When a test uses pytest.raises(SomeException) and the student's
solution fails to raise that exception, pytest raises
_pytest.outcomes.Failed. The ResultCollector hook only recognized
AssertionError and pytest.fail.Exception, so the failure was routed
to TestOutcome.TEST_ERROR and rendered as a misleading Syntax Error
banner instead of a clean Failed row with the 'DID NOT RAISE …'
message.

Add _pytest.outcomes.Failed to the isinstance check so pytest.raises
failures consistently surface as TestOutcome.FAIL across pytest
versions. Import Failed explicitly to make the routing
self-documenting.
TestCaseResult.to_html() unconditionally rendered every TEST_ERROR
outcome as '🚨 Syntax Error', even when the underlying exception was
a plain AttributeError or TypeError raised from the student's
solution code (e.g. 'NoneType' object has no attribute 'shape' when
a stub is left as 'return'). The banner contradicted the actual
exception type shown in the error block below.

Branch the label on the exception class: real SyntaxError
(including its IndentationError subclass) still renders as
'🚨 Syntax Error' on the COMPILE_ERROR path; everything else
renders as '⚠️ Runtime Error (ExcName)', reflecting what the
student actually hit.
run_pytest_for_function downgraded the entire result to
IPytestOutcome.PYTEST_ERROR whenever any individual test had a
TEST_ERROR outcome, discarding every TestCaseResult including
parametrizations that had actually passed. The student saw a single
generic error panel instead of per-case feedback.

The IPytestOutcome.FINISHED display path already iterates test
results and renders a mix of PASS/FAIL/TEST_ERROR correctly
per-row, so the downgrade is redundant. Drop it. PYTEST_ERROR
remains in use for pytest.ExitCode.INTERNAL_ERROR and for cell
compilation failures wrapped by run_cell().

Drop the now-unused TestOutcome import from testsuite.py.
@edoardob90 edoardob90 changed the title Fix %%ipytest error-display mislabeling (partial fix for #345) Fix %%ipytest error-display mislabeling Apr 15, 2026
@edoardob90 edoardob90 changed the title Fix %%ipytest error-display mislabeling Fix ipytest error-display mislabeling Apr 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant