some testing improvements

- show complete call stack of failures (this does include some of the
  testing machinery, but a) is simple, and b) is guaranteed to not
  miss important stack frames)
- add helper to run test with a timeout
- add AssertEqualuint64
This commit is contained in:
Matthias Radestock committed 2015-01-21 18:45:37 +00:00
1 parent b7b5fd3dd2
commit 6efa794ab4
1 file changed
+45 -25
+45 -25
View File
@@ -1,70 +1,90 @@
package testing
import (
"fmt"
"reflect"
"runtime"
"strings"
"testing"
"time"
)
func CallSite() string {
_, file, line, ok := runtime.Caller(2)
if ok {
// Truncate file name at last file name separator.
if index := strings.LastIndex(file, "/"); index >= 0 {
file = file[index+1:]
} else if index = strings.LastIndex(file, "\\"); index >= 0 {
file = file[index+1:]
}
} else {
file = "???"
line = 1
}
return fmt.Sprintf("%s:%d: ", file, line)
}
func AssertNoErr(t *testing.T, err error) {
if err != nil {
t.Fatal(CallSite(), err)
Fatalf(t, "Unexpected error: %s", err)
}
}
func AssertEqualuint64(t *testing.T, got, wanted uint64, desc string) {
if got != wanted {
Fatalf(t, "Expected %s %d but got %d", desc, wanted, got)
}
}
func AssertEqualInt(t *testing.T, got, wanted int, desc string) {
if got != wanted {
t.Fatalf("%s: Expected %s %d but got %d", CallSite(), desc, wanted, got)
Fatalf(t, "Expected %s %d but got %d", desc, wanted, got)
}
}
func AssertEqualString(t *testing.T, got, wanted string, desc string) {
if got != wanted {
t.Fatalf("%s: Expected %s '%s' but got '%s'", CallSite(), desc, wanted, got)
Fatalf(t, "Expected %s '%s' but got '%s'", desc, wanted, got)
}
}
func AssertStatus(t *testing.T, got int, wanted int, desc string) {
if got != wanted {
t.Fatalf("%s: Expected %s %d but got %d", CallSite(), desc, wanted, got)
Fatalf(t, "Expected %s %d but got %d", desc, wanted, got)
}
}
func AssertErrorInterface(t *testing.T, got interface{}, wanted interface{}, desc string) {
gotT, wantedT := reflect.TypeOf(got), reflect.TypeOf(wanted).Elem()
if !gotT.Implements(wantedT) {
t.Fatalf("%s: Expected %s but got %s (%s)", CallSite(), wantedT.String(), gotT.String(), desc)
Fatalf(t, "Expected %s but got %s (%s)", wantedT.String(), gotT.String(), desc)
}
}
func AssertErrorType(t *testing.T, got interface{}, wanted interface{}, desc string) {
gotT, wantedT := reflect.TypeOf(got), reflect.TypeOf(wanted).Elem()
if gotT != wantedT {
t.Fatalf("%s: Expected %s but got %s (%s)", CallSite(), wantedT.String(), gotT.String(), desc)
Fatalf(t, "Expected %s but got %s (%s)", wantedT.String(), gotT.String(), desc)
}
}
func AssertType(t *testing.T, got interface{}, wanted interface{}, desc string) {
gotT, wantedT := reflect.TypeOf(got), reflect.TypeOf(wanted)
if gotT != wantedT {
t.Fatalf("%s: Expected %s but got %s (%s)", CallSite(), wantedT.String(), gotT.String(), desc)
Fatalf(t, "Expected %s but got %s (%s)", wantedT.String(), gotT.String(), desc)
}
}
// Like testing.Fatalf, but adds the stack trace of the current call
func Fatalf(t *testing.T, format string, args ...interface{}) {
t.Fatalf(format+"\n%s", append(args, StackTrace())...)
}
func StackTrace() string {
return stackTrace(false)
}
func stackTrace(all bool) string {
buf := make([]byte, 1<<20)
stacklen := runtime.Stack(buf, all)
return string(buf[:stacklen])
}
// Borrowed from net/http tests:
// goTimeout runs f, failing t if f takes more than d to complete.
func RunWithTimeout(t *testing.T, d time.Duration, f func()) {
ch := make(chan bool, 2)
timer := time.AfterFunc(d, func() {
t.Errorf("Timeout expired after %v: stacks:\n%s", d, stackTrace(true))
ch <- true
})
defer timer.Stop()
go func() {
defer func() { ch <- true }()
f()
}()
<-ch
}