Documentation ¶
Overview ¶
Package testy is an extensible facade around Go's core testing library.
Go's core testing package doesn't let you refactor repetitive tests without reporting errors from the wrong place in the code. Testy implements a facade around the testing package and hijacks its logging features. This means:
* You can report test errors at any level up the call stack.
* You can label all errors in a scope to disambiguate repetitive tests.
The downside is an extra level of log message nesting (which your editor's quickfix window should ignore, anyway).
It gives a few convenient helper functions for common cases and makes it easy to implement your own.
The following example shows how to set up testy and use test helpers. In particular, note the use of 'defer' and a closure to schedule testy to output the log at the end of the function's execution.
package example import ( "github.com/xdg/testy" "testing" ) func TestExample(t *testing.T) { is := testy.New(t) defer func() { t.Logf(is.Done()) }() is.True(1+1 == 3) is.False(2 == 2) is.Equal(1, 2) is.Equal(1.0, 1) is.Equal("foo\tbar", "foo\tbaz") is.Equal(true, false) is.Unequal(42, 42) is.NotNil(is) }
Each error will be reported at the calling line. Calls to 'Equal' and 'Unequal' will return diagnostic details. Here is how some of the output would look in Vim's quickfix window:
... _examples/example_test.go|15| Values were not equal: || Got: 1 (int) || Wanted: 2 (int) _examples/example_test.go|16| Values were not equal: || Got: 1 (float64) || Wanted: 1 (int) _examples/example_test.go|17| Values were not equal: || Got: "foo\tbar" || Wanted: "foo\tbaz" ...
You can use the 'Uplevel' and 'Label' methods to return new facades, which you can use to implement custom helpers in various ways:
func TestExample(t *testing.T) { is := testy.New(t) defer func() { t.Logf(is.Done()) }() // Check for numbers equal to 3 for i := 1; i <= 5; i++ { is.Label("Checking", i).True(i == 3) // Line 13 } // Check for positive, even numbers for i := -1; i <= 2; i++ { checkEvenPositive(is, i) // Line 18 } } func checkEvenPositive(is *testy.T, n int) { // Report one level up with a custom label is = is.Uplevel(1).Label("Testing", n) if n < 1 { is.Error("Value was not positive") } if n%2 != 0 { is.Error("Value was not even") } }
The example above would return errors to a quickfix window like this:
... _examples/example_test.go|13| Checking 1: Expression was not true _examples/example_test.go|13| Checking 2: Expression was not true _examples/example_test.go|13| Checking 4: Expression was not true _examples/example_test.go|13| Checking 5: Expression was not true _examples/example_test.go|18| Testing -1: Value was not positive _examples/example_test.go|18| Testing -1: Value was not even _examples/example_test.go|18| Testing 0: Value was not positive _examples/example_test.go|18| Testing 1: Value was not even ...
Index ¶
- type T
- func (t *T) Done() string
- func (t *T) Equal(got, want interface{})
- func (t *T) Error(args ...interface{})
- func (t *T) Errorf(format string, args ...interface{})
- func (t *T) Fail()
- func (t T) FailCount() int
- func (t *T) FailNow()
- func (t *T) Failed() bool
- func (t *T) False(cond bool)
- func (t *T) Fatal(args ...interface{})
- func (t *T) Fatalf(format string, args ...interface{})
- func (t T) Label(s ...interface{}) *T
- func (t *T) Log(args ...interface{})
- func (t *T) Logf(format string, args ...interface{})
- func (t *T) Nil(got interface{})
- func (t *T) NotNil(got interface{})
- func (t T) Output() []string
- func (t *T) Skip(args ...interface{})
- func (t *T) SkipNow()
- func (t *T) Skipf(format string, args ...interface{})
- func (t *T) Skipped() bool
- func (t *T) True(cond bool)
- func (t *T) Unequal(got, want interface{})
- func (t T) Uplevel(depth int) *T
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type T ¶
type T struct {
// contains filtered or unexported fields
}
T is a facade around the testing.T type passed to Test functions. It intercepts log messages to attribute them to the correct level of the call stack.
func New ¶
New wraps a testy.T struct around a testing.T struct. The resulting struct can be used in the same way the testing.T struct would be, plus has additional methods specific to Testy. It calls NewCase with the calling function's name as the test case name.
func NewCase ¶
NewCase wraps a testy.T struct around a testing.T struct. The resulting struct can be used in the same way the testing.T struct would be, plus has additional methods specific to Testy. It takes a name argument that is used in the summary line during log output.
func (*T) Done ¶
Done returns any test log output formatted suitably for passing to a testing.T struct Logf method.
func (*T) Equal ¶
func (t *T) Equal(got, want interface{})
Equal checks if its arguments are equal using reflect.DeepEqual. It is subject to all the usual limitations of that function. If the values are not equal, an error is logged and the 'got' and 'want' values are logged on subsequent lines for comparison.
func (*T) Error ¶
func (t *T) Error(args ...interface{})
Error is equivalent to Log followed by Fail
func (T) FailCount ¶
FailCount returns the number of Fail, Error, Fatal or test helper failures recorded by the testy.T struct.
func (*T) FailNow ¶
func (t *T) FailNow()
FailNow marks the test as having failed and stops execution. It is subject to the same restrictions as FailNow from the testing package.
func (*T) Fatal ¶
func (t *T) Fatal(args ...interface{})
Fatal is equivalent to Log followed by FailNow
func (T) Label ¶
Label returns a testy.T struct that will prefix a label to all log messages. The label is constructed by concatenating arguments separated by a space (like fmt.Sprintln without the trailing space). A colon character and space will be added automatically
func (*T) Log ¶
func (t *T) Log(args ...interface{})
Log joins its arguments by spaces like fmt.Sprintln and records the result for later delivery by the Done method.
func (*T) Logf ¶
Logf joins its arguments like fmt.Sprintf and records the result for later delivery by the Done method.
func (*T) Nil ¶
func (t *T) Nil(got interface{})
Nil checks if its argument is nil (literal or nil slice, map, etc.); if non-nil, it logs an error.
func (*T) NotNil ¶
func (t *T) NotNil(got interface{})
Nil checks if its argument is nil (literal or nil slice, map, etc.); if non-nil, it logs an error.
func (T) Output ¶
Output returns a copy of the slice of log messages recorded by the testy.T struct.
func (*T) Skip ¶
func (t *T) Skip(args ...interface{})
Skip is equivalent to Log followed by SkipNow
func (*T) SkipNow ¶
func (t *T) SkipNow()
SkipNow marks the test as skipped and halts execution. It is subject to the same restrictions as SkipNow from the testing package.