darrenburns / ward

Ward is a modern test framework for Python with a focus on productivity and readability.
https://ward.readthedocs.io
MIT License
1.21k stars 54 forks source link

Option to simplify stack trace logs #338

Open RamonGiovane opened 2 years ago

RamonGiovane commented 2 years ago

Hi. Fantastic framework.

But have you guys thought in an option to shorten the output log, especially the stacktrace? Sometimes I'm only interested on the exception message but Ward formats the entire stack trace, and prints it out infinitely.

For instance, SQLAlchemy errors stack trace are so large that it blocks the scrolling of the VS Code console keeping me from reading what I really need to.

image and this is a short one, sometimes, these red and yellow borded boxes take the entire screen

It's nice and pretty, but most of the time this pretty printed stuff is useless to me. It's some external module stuff, that doesn't help. An option that only shows the file and the line number would be very nice. Like this: image Like Python's regular stacktrace

Thanks for all.

backwardspy commented 2 years ago

i'd also like to register my interest in this. testing fastapi and piccolo tends to produce some pretty hefty stack traces too, to the point where my terminal's scrollback gets filled up and i can't actually see what went wrong.

RamonGiovane commented 1 year ago

I created a codespace and did some experimentation.

First, I messed up with an existing test on purpose, adding some chained function calls, just to create some stacktrace.

def my_func1(*params):
    1/0

def my_func2(fruit):
    number = 3
    letter = 'p'
    my_func1(fruit, letter, number)

def my_func3():
    fruit = 'apple'
    my_func2(fruit)

@test("Diff renders a simple string diff correctly (no symbols, no intraline diff)")
def _():
    # In this case, difflib returns a diff without the intraline differences
    lhs = "hello"
    rhs = "halo"
    diff = Diff(lhs, rhs, 80)

    render_iter = diff.__rich_console__(None, None)

    actual_lhs: Text = next(render_iter)
    actual_rhs: Text = next(render_iter)

    assert actual_lhs == Text(lhs)
    assert actual_lhs.style == "green"

    assert actual_rhs == Text(rhs)
    assert actual_rhs.style == "red"
    my_func3()

Then I tried to disable some printing to see how it would look. The most interesting was this print_traceback function. Setting show_locals to False may solve the extensive printing on SQLAlchemy and FastAPI tests. It would be awesome if we could toggle this by an input parameter.

   def print_traceback(self, err):
        trace = getattr(err, "__traceback__", "")
        if trace:
            # The first frame contains library internal code which is not
            # relevant to end users, so skip over it.
            trace = trace.tb_next
            tb = Traceback.from_exception(err.__class__, err, trace, show_locals=False)  # here
            self.console.print(Padding(tb, pad=(0, 2, 1, 2)))
        else:
            self.console.print(str(err))

Output comparison

Before hiding locals

It doesn't even fit entirely on the screen :sweat_smile: image

Afer hiding locals

image

RamonGiovane commented 6 months ago

A created a fork with this option I made. Solves the problem for now: https://github.com/RamonGiovane/sward