diff --git a/assert/assert.go b/assert/assert.go index 1ec1d2d..5ba6465 100644 --- a/assert/assert.go +++ b/assert/assert.go @@ -59,10 +59,15 @@ messages it produces. Assert and Check -Assert() and Check() both accept a Comparison, and fail the test when the -comparison fails. The one difference is that Assert() will end the test execution -immediately (using t.FailNow()) whereas Check() will fail the test (using t.Fail()), -return the value of the comparison, then proceed with the rest of the test case. +Assert and Check are very similar, they both accept a Comparison, and fail +the test when the comparison fails. The one difference is that Assert uses +testing.T.FailNow to fail the test, which will end the test execution immediately. +Check uses testing.T.Fail to fail the test, which allows it to return the +result of the comparison, then proceed with the rest of the test case. + +Like testing.T.FailNow, Assert must be called from the goroutine running the test, +not from other goroutines created during the test. Check is safe to use from any +goroutine. Comparisons @@ -105,16 +110,23 @@ type helperT interface { // failed, a failure message is logged, and execution is stopped immediately. // // The comparison argument may be one of three types: +// // bool -// True is success. False is a failure. -// The failure message will contain the literal source code of the expression. +// True is success. False is a failure, and the failure message will contain +// the literal source code of the expression. +// // cmp.Comparison -// Uses cmp.Result.Success() to check for success of failure. -// The comparison is responsible for producing a helpful failure message. -// http://pkg.go.dev/gotest.tools/v3/assert/cmp provides many common comparisons. +// Uses cmp.Result.Success() to check for success of failure. +// The comparison is responsible for producing a helpful failure message. +// http://pkg.go.dev/gotest.tools/v3/assert/cmp provides many common comparisons. +// // error -// A nil value is considered success. -// A non-nil error is a failure, err.Error() is used as the failure message. +// A nil value is considered success, and a non-nil error is a failure. +// err.Error is used as the failure message. +// +// Assert uses t.FailNow to fail the test. Like t.FailNow, Assert must be called +// from the goroutine running the test function, not from other +// goroutines created during the test. Use Check from other goroutines. func Assert(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) { if ht, ok := t.(helperT); ok { ht.Helper() @@ -125,8 +137,8 @@ func Assert(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) } // Check performs a comparison. If the comparison fails the test is marked as -// failed, a failure message is logged, and Check returns false. Otherwise returns -// true. +// failed, a failure message is printed, and Check returns false. If the comparison +// is successful Check returns true. Check may be called from any goroutine. // // See Assert for details about the comparison arg and failure messages. func Check(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) bool { @@ -140,8 +152,12 @@ func Check(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) b return true } -// NilError fails the test immediately if err is not nil. -// This is equivalent to Assert(t, err) +// NilError fails the test immediately if err is not nil, and includes err.Error +// in the failure message. +// +// NilError uses t.FailNow to fail the test. Like t.FailNow, NilError must be +// called from the goroutine running the test function, not from other +// goroutines created during the test. Use Check from other goroutines. func NilError(t TestingT, err error, msgAndArgs ...interface{}) { if ht, ok := t.(helperT); ok { ht.Helper() @@ -154,15 +170,22 @@ func NilError(t TestingT, err error, msgAndArgs ...interface{}) { // Equal uses the == operator to assert two values are equal and fails the test // if they are not equal. // -// If the comparison fails Equal will use the variable names for x and y as part -// of the failure message to identify the actual and expected values. +// If the comparison fails Equal will use the variable names and types of +// x and y as part of the failure message to identify the actual and expected +// values. +// +// assert.Equal(t, actual, expected) +// // assertion failed: 1 (actual int) != 21 (expected int32) // // If either x or y are a multi-line string the failure message will include a // unified diff of the two values. If the values only differ by whitespace // the unified diff will be augmented by replacing whitespace characters with // visible characters to identify the whitespace difference. // -// This is equivalent to Assert(t, cmp.Equal(x, y)). +// Equal uses t.FailNow to fail the test. Like t.FailNow, Equal must be +// called from the goroutine running the test function, not from other +// goroutines created during the test. Use Check with cmp.Equal from other +// goroutines. func Equal(t TestingT, x, y interface{}, msgAndArgs ...interface{}) { if ht, ok := t.(helperT); ok { ht.Helper() @@ -178,7 +201,10 @@ func Equal(t TestingT, x, y interface{}, msgAndArgs ...interface{}) { // Package http://pkg.go.dev/gotest.tools/v3/assert/opt provides some additional // commonly used Options. // -// This is equivalent to Assert(t, cmp.DeepEqual(x, y)). +// DeepEqual uses t.FailNow to fail the test. Like t.FailNow, DeepEqual must be +// called from the goroutine running the test function, not from other +// goroutines created during the test. Use Check with cmp.DeepEqual from other +// goroutines. func DeepEqual(t TestingT, x, y interface{}, opts ...gocmp.Option) { if ht, ok := t.(helperT); ok { ht.Helper() @@ -188,21 +214,33 @@ func DeepEqual(t TestingT, x, y interface{}, opts ...gocmp.Option) { } } -// Error fails the test if err is nil, or the error message is not the expected -// message. -// Equivalent to Assert(t, cmp.Error(err, message)). -func Error(t TestingT, err error, message string, msgAndArgs ...interface{}) { +// Error fails the test if err is nil, or if err.Error is not equal to expected. +// Both err.Error and expected will be included in the failure message. +// Error performs an exact match of the error text. Use ErrorContains if only +// part of the error message is relevant. Use ErrorType or ErrorIs to compare +// errors by type. +// +// Error uses t.FailNow to fail the test. Like t.FailNow, Error must be +// called from the goroutine running the test function, not from other +// goroutines created during the test. Use Check with cmp.Error from other +// goroutines. +func Error(t TestingT, err error, expected string, msgAndArgs ...interface{}) { if ht, ok := t.(helperT); ok { ht.Helper() } - if !assert.Eval(t, assert.ArgsAfterT, cmp.Error(err, message), msgAndArgs...) { + if !assert.Eval(t, assert.ArgsAfterT, cmp.Error(err, expected), msgAndArgs...) { t.FailNow() } } -// ErrorContains fails the test if err is nil, or the error message does not -// contain the expected substring. -// Equivalent to Assert(t, cmp.ErrorContains(err, substring)). +// ErrorContains fails the test if err is nil, or if err.Error does not +// contain the expected substring. Both err.Error and the expected substring +// will be included in the failure message. +// +// ErrorContains uses t.FailNow to fail the test. Like t.FailNow, ErrorContains +// must be called from the goroutine running the test function, not from other +// goroutines created during the test. Use Check with cmp.ErrorContains from other +// goroutines. func ErrorContains(t TestingT, err error, substring string, msgAndArgs ...interface{}) { if ht, ok := t.(helperT); ok { ht.Helper() @@ -213,19 +251,29 @@ func ErrorContains(t TestingT, err error, substring string, msgAndArgs ...interf } // ErrorType fails the test if err is nil, or err is not the expected type. -// Equivalent to Assert(t, cmp.ErrorType(err, expected)). +// Most new code should use ErrorIs instead. ErrorType may be deprecated in the +// future. // // Expected can be one of: +// // func(error) bool -// Function should return true if the error is the expected type. -// type struct{}, type &struct{} -// A struct or a pointer to a struct. -// Fails if the error is not of the same type as expected. +// The function should return true if the error is the expected type. +// +// type struct{} or type &struct{} +// A struct or a pointer to a struct. The assertion fails if the error is +// not of the same type. +// // type &interface{} -// A pointer to an interface type. -// Fails if err does not implement the interface. +// A pointer to an interface type. The assertion fails if err does not +// implement the interface. +// // reflect.Type -// Fails if err does not implement the reflect.Type +// The assertion fails if err does not implement the reflect.Type +// +// ErrorType uses t.FailNow to fail the test. Like t.FailNow, ErrorType +// must be called from the goroutine running the test function, not from other +// goroutines created during the test. Use Check with cmp.ErrorType from other +// goroutines. func ErrorType(t TestingT, err error, expected interface{}, msgAndArgs ...interface{}) { if ht, ok := t.(helperT); ok { ht.Helper() @@ -237,7 +285,12 @@ func ErrorType(t TestingT, err error, expected interface{}, msgAndArgs ...interf // ErrorIs fails the test if err is nil, or the error does not match expected // when compared using errors.Is. See https://golang.org/pkg/errors/#Is for -// accepted argument values. +// accepted arguments. +// +// ErrorIs uses t.FailNow to fail the test. Like t.FailNow, ErrorIs +// must be called from the goroutine running the test function, not from other +// goroutines created during the test. Use Check with cmp.ErrorIs from other +// goroutines. func ErrorIs(t TestingT, err error, expected error, msgAndArgs ...interface{}) { if ht, ok := t.(helperT); ok { ht.Helper()