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

Use rich traceback #996

Open
timofurrer opened this issue Feb 3, 2022 · 3 comments
Open

Use rich traceback #996

timofurrer opened this issue Feb 3, 2022 · 3 comments

Comments

@timofurrer
Copy link

At the moment behave handles all assertion exceptions, therefore preventing someone to use rich tracebacks.

It would be awesome if rich tracebacks and behave would work together somehow.

In the meantime, is it possible to overwrite how exceptions are rendered in behave?

@jenisys
Copy link
Member

jenisys commented Feb 4, 2022

Mmh, after a short look at „rich / rich trackbacks“:

  • Installation is probably no problem: Probably best in „features/environment.py“
  • BUT: You basically need to do different things where exceptions are caught and normally print-ed.
    Rich requires to replace this print() calls w/ console.print_exception() calls
  • Therefore, this probably needs a new extension-point / variation-point (or level of indirection)
  • QUICK IDEA (to be elaborated): The best way is probably to add a runner.console attribute that hides if normal print is used or rich traceback print mechanism is used.

POTENTIALlY AFFECTED:

  • behave.main() — Outer-most exception handling
  • behave.runner
  • behave.model classes (Step, …) used during the test run
  • MAYBE: Behave formatters that print/show theses exception tracebacks (normally the just print the captured output)

EXPERIMENT (for you):

  • Inject rich.traceback in „features/environment.py“ (should be easy)
  • CLEAN WAY: Add a new formatter (based on the plain formatter) that uses rich tracebacks
  • DIRTY WAY: Patch the plain formatter to use rich tracebacks

HINTS:

  • The trackback is stored in the Step and other model entity classes (as far as I recall)
  • Therefore, you may need to replace the trackback of the captured output with the rich traceback output
  • Hooks are normally not captured (but you can use a decorator to do that)

QUESTIONS:

  • What happens when output-capture is disabled during the test run ?

Explore how far you get with that (and what other stumbling stones are that lay in the way).

@timofurrer
Copy link
Author

Thanks for the quick review and digging into it a little.

Inject rich.traceback in „features/environment.py“ (should be easy)

I've already tried that, but it doesn't have any effect. I could actually except my own assert and then just print it with rich. However, I'm more looking for the install() approach, which installs and exception handler for unhandled exceptions, which I understand doesn't work because behave handles that itself :)

I may do an experiment with a rich formatter ... I'll keep you posted.

@slafs
Copy link

slafs commented Feb 11, 2022

Inspired by "Debug-on-Error (in Case of Step Failures)",
I've tried using a step hook for this and it works kinda nice:

import behave
from behave.model import Step
from rich.console import Console
from rich.traceback import Traceback


def print_rich_traceback(step: Step):
    """
    Print an exception traceback from a failed step
    using https://pypi.org/project/rich/

    To be used in a step hook like::

        def after_step(context, step):
            if step.status == "failed":
                print_rich_traceback(step)
            ...
    """

    if not (getattr(step, "exception", False) and getattr(step, "exc_traceback", False)):
        return

    traceback = Traceback.from_exception(
        type(step.exception),
        step.exception,
        step.exc_traceback,
        show_locals=True,
        suppress=[behave],
    )

    # Forcing terminal on the console, because behave captures output.
    # TODO: auto-detect this (from context.config?)
    console = Console(force_terminal=True)
    console.print(traceback)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants