I'd like to wrap standard golang test functions, such as t.Errorf
from the testing package.
I tried this:
// AssertEqual tests that the expected and actual values match
func AssertEqual(t *testing.T, expected interface{}, actual interface{}) {
switch expected.(type) {
case string:
if expected != actual {
t.Errorf("Error:
expected: %s
actual: %s", expected, actual)
}
default:
t.Errorf("Unsupported type")
}
}
However, when a test fails, I get the function and line number of my helper function:
test_asserts.go:12: Error:
expected:
actual: TestValue
Is there a way to error at the line number of the caller?
This is how the testing library does it: https://golang.org/src/testing/testing.go?h=Errorf#L285
By using runtime.Caller
.
You can borrow this code for your own error function that would look one deeper into the stack. You can replace the entirety of Errorf
(which is log
+ fail
) or a bit less pretty but less code would be to just print the entire stack using something like debug.PrintStack()
before calling Errorf
.
You can see Fail
function in assert
package: https://github.com/stretchr/testify/blob/master/assert/assertions.go#L207
Example:
package main_test
import (
"fmt"
"github.com/stretchr/testify/assert"
"strings"
"testing"
)
// AssertEqual tests that the expected and actual values match
func AssertEqual(t *testing.T, expected interface{}, actual interface{}) {
switch expected.(type) {
case string:
if expected != actual {
callInfo := assert.CallerInfo()
errorTrace := strings.Join(callInfo, "
\t\t\t")
t.Errorf("%s\tError Trace:\t%s
"+
"\tError:%s
",
"",
errorTrace,
fmt.Sprintf("Error:
expected: %s
actual: %s", expected, actual),
)
}
default:
t.Errorf("Unsupported type")
}
}
func TestFoo(t *testing.T) {
AssertEqual(t, "hello", 21)
}
Result:
$ go test main_test.go
--- FAIL: TestFoo (0.00s)
Error Trace::22:main_test.go:15
main_test.go:30
Error:Error:
expected: hello
actual: %!s(int=21)
FAIL
FAIL command-line-arguments 0.002s
With the recent Go 1.9 (August 2017), all you need to do is adding one line to your function:
t.Helper()
That will silence this function in error report, and your actual error line will be the one you expect (ie the one calling this function)
See pkg/testing/#T.Helper
(also available for Benchmark test, but... not for the TB
interface, where it was forgotten!)
// AssertEqual tests that the expected and actual values match
func AssertEqual(t *testing.T, expected interface{}, actual interface{}) {
t.Helper()
switch expected.(type) {
case string:
if expected != actual {
t.Errorf("Error:
expected: %s
actual: %s", expected, actual)
}
default:
t.Errorf("Unsupported type")
}
}