From 72961116a105ebd7782bc0cf207cb6c35857852f Mon Sep 17 00:00:00 2001 From: Adam Wolfe Gordon Date: Tue, 6 Sep 2016 16:06:25 -0600 Subject: [PATCH] Fix #341 Go 1.7 subtests are called directly from testing.tRunner, not from the test that contains the t.Run call. Because of this, the call stack doesn't contain a function starting with Test, Benchmark, or Example, causing assert.CallerInfo() to run off the end of the call stack and return nil. Look for testing.tRunner explicitly to solve this problem, and return the list of callers if we do run off the call stack so that if there's a similar problem in the future we still get an inflated stack trace rather than no trace at all. --- assert/assertions.go | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 348d5f1..1320317 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -82,7 +82,9 @@ func CallerInfo() []string { for i := 0; ; i++ { pc, file, line, ok = runtime.Caller(i) if !ok { - return nil + // The breaks below failed to terminate the loop, and we ran off the + // end of the call stack. + break } // This is a huge edge case, but it will panic if this is the case, see #180 @@ -90,6 +92,21 @@ func CallerInfo() []string { 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 + } + parts := strings.Split(file, "/") dir := parts[len(parts)-2] file = parts[len(parts)-1] @@ -97,11 +114,6 @@ func CallerInfo() []string { callers = append(callers, fmt.Sprintf("%s:%d", file, line)) } - f := runtime.FuncForPC(pc) - if f == nil { - break - } - name = f.Name() // Drop the package segments := strings.Split(name, ".") name = segments[len(segments)-1]