-
Notifications
You must be signed in to change notification settings - Fork 20
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
Add RichExceptionChainRepr
for richer exception highlighting
#8
Conversation
This looks amazing 😍 great work! About testing: not sure how we can approach testing in pytest-rich in general TBH. Any ideas? |
Thanks! 😊 As far as testing, I'm a bit stumped too. A quick glance through Rich's test suite, most of the traceback tests are testing the Might be worth pinging Will to see if he has any suggestions. |
For the time being, could we use a mark on failing tests so that you could manually test the terminal output for tracebacks without breaking CI? |
Running this PR on my main Django app, I get this error: ──────────────────────── forsythia/lease/clubs/tests/test_views.py::TestClubList::test_post ────────────────────────
Traceback (most recent call last):
File "/usr/local/bin/pytest", line 8, in <module>
sys.exit(console_main())
File "/usr/local/lib/python3.10/site-packages/_pytest/config/__init__.py", line 188, in console_main
code = main()
File "/usr/local/lib/python3.10/site-packages/_pytest/config/__init__.py", line 165, in main
ret: Union[ExitCode, int] = config.hook.pytest_cmdline_main(
File "/usr/local/lib/python3.10/site-packages/pluggy/_hooks.py", line 265, in __call__
return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
File "/usr/local/lib/python3.10/site-packages/pluggy/_manager.py", line 80, in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
File "/usr/local/lib/python3.10/site-packages/pluggy/_callers.py", line 60, in _multicall
return outcome.get_result()
File "/usr/local/lib/python3.10/site-packages/pluggy/_result.py", line 60, in get_result
raise ex[1].with_traceback(ex[2])
File "/usr/local/lib/python3.10/site-packages/pluggy/_callers.py", line 39, in _multicall
res = hook_impl.function(*args)
File "/usr/local/lib/python3.10/site-packages/_pytest/main.py", line 315, in pytest_cmdline_main
return wrap_session(config, _main)
File "/usr/local/lib/python3.10/site-packages/_pytest/main.py", line 303, in wrap_session
config.hook.pytest_sessionfinish(
File "/usr/local/lib/python3.10/site-packages/pluggy/_hooks.py", line 265, in __call__
return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
File "/usr/local/lib/python3.10/site-packages/pluggy/_manager.py", line 80, in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
File "/usr/local/lib/python3.10/site-packages/pluggy/_callers.py", line 60, in _multicall
return outcome.get_result()
File "/usr/local/lib/python3.10/site-packages/pluggy/_result.py", line 60, in get_result
raise ex[1].with_traceback(ex[2])
File "/usr/local/lib/python3.10/site-packages/pluggy/_callers.py", line 39, in _multicall
res = hook_impl.function(*args)
File "/usr/local/lib/python3.10/site-packages/pytest_rich.py", line 241, in pytest_sessionfinish
self.console.print(tb)
File "/usr/local/lib/python3.10/site-packages/rich/console.py", line 1616, in print
extend(render(renderable, render_options))
File "/usr/local/lib/python3.10/site-packages/rich/console.py", line 1254, in render
for render_output in iter_render:
File "/usr/local/lib/python3.10/site-packages/pytest_rich.py", line 315, in __rich_console__
repr_highlighter(
File "/usr/local/lib/python3.10/site-packages/rich/highlighter.py", line 36, in __call__
raise TypeError(f"str or Text instance required, not {text!r}")
TypeError: str or Text instance required, not None Running without ________________________________________ TestClubList.test_post[data0-201] _________________________________________
self = <forsythia.lease.clubs.tests.test_views.TestClubList object at 0x7f3ded0d7040>
api_client = <rest_framework.test.APIClient object at 0x7f3debb5dc30>
data = {'clubInfo': 'test club 1', 'description': 'test club 1', 'name': 'test club 1'}, expected_status_code = 201
@pytest.mark.parametrize(
"data,expected_status_code",
[
(
{
"name": "test club 1",
"description": "test club 1",
"clubInfo": "test club 1",
},
status.HTTP_201_CREATED,
),
(
{
"name": "test club 2",
},
status.HTTP_201_CREATED,
),
({}, status.HTTP_400_BAD_REQUEST),
],
)
def test_post(self, api_client, data, expected_status_code):
response = api_client.post(self.endpoint, data=data)
> assert response.status_code != expected_status_code
E assert 201 != 201
E + where 201 = <Response status_code=201, "application/json">.status_code
forsythia/lease/clubs/tests/test_views.py:57: AssertionError Guess my implementation of |
Yeah I guess somewhere there's a |
First pass at dealing with the error messages. The original Here are a few screenshots to show progress so far: |
This PR may be in a good spot to merge. There are still improvments to be done:
I think those all should go in as separate issues with their own PRs, in order to avoid this PR's scope from expanding beyond richer exception highlighting. |
Additional stray thoughts:
So maybe I was fibbing a bit and this PR isn't ready to merge just yet. |
Agreed, want to mark it as Ready for Review then? |
RichExceptionChainRepr
RichExceptionChainRepr
for richer exception highlighting in failed tests
My goal was this PR was to get a good starting point. Here are some areas for improvement:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks awesome!
I didn't review the code in detail, but the results do look great.
Could you please also update the screenshot in assets/
? Thanks!
Btw your detailed comments for follow ups should probably be moved to their own issues so we don't lose track of them. 👍 |
RichExceptionChainRepr
for richer exception highlighting in failed testsRichExceptionChainRepr
for richer exception highlighting
When I ever thought about pytest+rich, this is the feature I had in mind. |
Yanked most of
__rich_console__
from Rich'sTraceback
class and adapted for pytest'sExceptionChainRepr
.I ignored locals for the time being, which I assume I can grab from
reprlocals
on eachReprEntry
.There's no testing other than the eye test and the code could stand to be cleaned up a bit as well. But! It's working.