如何包装golang测试功能

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")
    }
}