stretchr / testify

A toolkit with common assertions and mocks that plays nicely with the standard library
MIT License
23.15k stars 1.59k forks source link

Allow user to skip (ignore) specific caller frames in assert.CallerInfo() #1527

Open xuxife opened 8 months ago

xuxife commented 8 months ago

Hi, I notice my assertion failure message sometimes has loooong stack traces, where most of them are from sdk or framework. I hope there could be a feature that I can customize assert.CallerInfo(), such that I can focus the stacks in my codebase.

for instance, allow a package-level callback like SkipCallerFrame(pc uintptr, file, line string) bool to skip the frame if the callback returns true.

    callers := []string{}
    for i := 0; ; i++ {
        pc, file, line, ok = runtime.Caller(i)
        if !ok {
            // The breaks below failed to terminate the loop, and we ran off the
            // end of the call stack.
            break
        }

             +  if SkipCallerFrame(pc, file, line) {
             +          break
             +  }
        // This is a huge edge case, but it will panic if this is the case, see #180
        if file == "<autogenerated>" {
            break
        }

        f := runtime.FuncForPC(pc)
        if f == nil {
            break
        }
        name = f.Name()

        // testing.tRunner is the standard library function that calls
        // tests. Subtests are called directly by tRunner, without going through
        // the Test/Benchmark/Example function that contains the t.Run calls, so
        // with subtests we should break when we hit tRunner, without adding it
        // to the list of callers.
        if name == "testing.tRunner" {
            break
        }
brackendawson commented 7 months ago

An aside: I'm pretty sure CallerInfo isn't supposed to be exported. I've noted this in #1431.

How long is too long? Can you show us an example? In go 1.21 the Go runtime chose to only print the first and last 50 frames: https://tip.golang.org/doc/go1.21#runtime-changes We could emulate that.

dolmen commented 4 months ago

An aside: I'm pretty sure CallerInfo isn't supposed to be exported. I've noted this in #1431.

I agree, but CallerInfo appears to be heavily used in the wild: https://github.com/search?q=assert.CallerInfo%28%29+lang%3AGo+&type=code