assert

package
v0.0.0-...-6b51fb8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 7, 2019 License: BSD-3-Clause Imports: 12 Imported by: 0

Documentation

Overview

Package assert provides a more readable way to assert in test cases; for example:

assert.For(t).ThatCalling(fn).PanicsReporting("expected error")

This way, the assert statement reads well; it flows like a proper sentence.

Also, one can easily tell which value is the test case got (actual) and which it wanted (expected); this is key to printing the values correctly to make debugging a bit easier. In Go, the actual value is usually printed first; for example:

assert.For(t).ThatActual(foo).Equals(expected)

The above enforces said order in both reading the code and the assertion failure message (if any).

For convenience (that also improves readability), there are methods for special cases like:

assert.For(t).ThatActual(foo).IsTrue()
assert.For(t).ThatActualString(bar).IsEmpty()

Which are equivalent to:

assert.For(t).ThatActual(foo).Equals(true)
assert.For(t).ThatActual(len(bar)).Equals(0)

To identify a test case in a table-driven test, optional ID parameters can be specified and will be included in failure messages:

cases := []struct {
    id       string
    actual   interface{}
    expected interface{}
}{
    {"different values", 42, 13},
    {"different types", 42.0, 42},
    {"different containers", [...]int{42}, []int{42}},
}

for _, c := range cases {
    assert.For(t, c.id).ThatActual(c.actual).Equals(c.expected)
}

After an assertion is performed, a ValueAssertionResult is returned to allow for post-assert actions to be performed; for example:

assert.For(t).ThatActual(value).Equals(expected).ThenDiffOnFail()

Which will pretty-print a detailed diff of both objects recursively on failure.

It also can be used as a condition to perform extra test steps:

value := GetValue()
if assert.For(t).ThatActual(value).IsNotNil().Passed() {
    assert.For(t).ThatActual(value.GetFoo()).Equals(expected)
}

Or to perform a deeper analysis of the test values:

if !assert.For(t).ThatActual(value).Equals(expected).Passed() {
    analyze(value, expected) // e.g., analyze may look at common bugs
}

Conveniently, the last example above can be rewritten as:

assert.For(t).ThatActual(value).Equals(expected).ThenRunOnFail(analyze)

Another use is to print a custom failure message:

assert.For(t).ThatActual(foo).Equals(bar).ThenRunOnFail(func(actual, expected interface{}) {
    fmt.Printf("JSON: %q != %q", actual.ToJSON(), expected.ToJSON())
})

The above pattern allows for reuse of post-failure analysis and cleanup.

The interfaces in this package are still a work-in-progress, and are subject to change.

Index

Constants

View Source
const (
	// TestHookTagKey denotes the tag key to use to tag a field as a test hook.
	TestHookTagKey = "test-hook"
)

Variables

This section is empty.

Functions

func PrettyPrint

func PrettyPrint(actual interface{}, expected interface{})

PrettyPrint pretty-prints the specified actual and expected values, in that order.

func PrintDiff

func PrintDiff(actual interface{}, expected interface{})

PrintDiff prints a pretty diff of the specified actual and expected values, in that order.

Types

type AssertableCall

type AssertableCall interface {
	// PanicsReporting asserts that calling the specified callable causes
	// a panic with the specified expected error.
	PanicsReporting(interface{})
}

AssertableCall represents an under-test function call that's expected to meet certain criteria.

type AssertableError

type AssertableError interface {
	// Equals asserts that the specified actual error equals the expected one.
	// Returns a ValueAssertionResult that provides post-assert actions.
	Equals(expected error) ValueAssertionResult

	// FormatsAs asserts that the specified actual error formats as expected.
	// The specified text is wrapped in an ErrorString object for comparison.
	// Returns a ValueAssertionResult that provides post-assert actions.
	FormatsAs(text string) ValueAssertionResult

	// IsNil asserts that the specified actual error is nil.
	// Returns a ValueAssertionResult that provides post-assert actions.
	IsNil() ValueAssertionResult

	// IsNotNil asserts that the specified actual error is not nil.
	// Returns a ValueAssertionResult that provides post-assert actions.
	IsNotNil() ValueAssertionResult
}

AssertableError represents an under-test error that's expected to meet certain criteria.

type AssertableString

type AssertableString interface {
	// Equals asserts that the specified actual string equals the expected one.
	// String values are compared byte-wise (implies case-sensetivity).
	// Returns a ValueAssertionResult that provides post-assert actions.
	Equals(expected string) ValueAssertionResult

	// IsEmpty asserts that the specified actual string is empty.
	// Returns a ValueAssertionResult that provides post-assert actions.
	IsEmpty() ValueAssertionResult

	// IsNotEmpty asserts that the specified actual string is not empty.
	// Returns a ValueAssertionResult that provides post-assert actions.
	IsNotEmpty() ValueAssertionResult
}

AssertableString represents an under-test string that's expected to meet certain criteria.

type AssertableTime

type AssertableTime interface {
	// Equals asserts that the specified actual time equals the expected one.
	// Returns a ValueAssertionResult that provides post-assert actions.
	Equals(expected *time.Time) ValueAssertionResult

	// IsNil asserts that the specified actual time is nil.
	// Returns a ValueAssertionResult that provides post-assert actions.
	IsNil() ValueAssertionResult

	// IsNotNil asserts that the specified actual time is not nil.
	// Returns a ValueAssertionResult that provides post-assert actions.
	IsNotNil() ValueAssertionResult
}

AssertableTime represents an under-test time that's expected to meet certain criteria.

type AssertableType

type AssertableType interface {
	// HidesTestHooks asserts that the under-test type hides test hooks.
	// It asserts that fields tagged with TestHookTagKey; for example:
	//     type sleeper struct {
	//         sleep func(time.Duration) `test-hook:"verify-unexported"`
	//     }
	// are unexported. If the field is anonymous, it asserts that its type is
	// unexported. An empty test-hook tag value is equivalent to no test-hook
	// tag; in which case, HidesTestHooks does not check the field.
	HidesTestHooks()
}

AssertableType represents an under-test type that's expected to meet certain criteria.

type AssertableValue

type AssertableValue interface {
	// Equals asserts that the specified actual value equals the expected one.
	// See https://golang.org/pkg/reflect/#DeepEqual for equality rules.
	// Returns a ValueAssertionResult that provides post-assert actions.
	Equals(expected interface{}) ValueAssertionResult

	// DoesNotEqual asserts that the specified actual value does not equal
	// the unexpected one.
	// See https://golang.org/pkg/reflect/#DeepEqual for equality rules.
	// Returns a ValueAssertionResult that provides post-assert actions.
	DoesNotEqual(unexpected interface{}) ValueAssertionResult

	// IsNil asserts that the specified actual value is nil.
	// Returns a ValueAssertionResult that provides post-assert actions.
	IsNil() ValueAssertionResult

	// IsNotNil asserts that the specified actual value is not nil.
	// Returns a ValueAssertionResult that provides post-assert actions.
	IsNotNil() ValueAssertionResult

	// IsFalse asserts that the specified actual value is false.
	// Returns a ValueAssertionResult that provides post-assert actions.
	IsFalse() ValueAssertionResult

	// IsTrue asserts that the specified actual value is true.
	// Returns a ValueAssertionResult that provides post-assert actions.
	IsTrue() ValueAssertionResult

	// MarshalsEquivalentJSON asserts that the specified actual value yields
	// a JSON encoding equivalent to that of the specified expected value.
	// See https://golang.org/pkg/encoding/json/#Marshal for encoding details.
	// Returns a ValueAssertionResult that provides post-assert actions.
	MarshalsEquivalentJSON(expected interface{}) ValueAssertionResult
}

AssertableValue represents an under-test value that's expected to meet certain criteria.

type ErrorString

type ErrorString string

ErrorString is a trivial implementation of error. It's useful for asserting error messages. For example:

assert.For(t).ThatActualError(err).Equals(assert.ErrorString("foo"))

We compare errors by comapring the output of Error(), which is used to format the error when printed. Here's a convenient way to rewrite the above:

assert.For(t).ThatActualError(err).FormatsAs("foo")

The specified text is wrapped in an ErrorString object for comparison.

func (ErrorString) Error

func (err ErrorString) Error() string

type TestContext

type TestContext interface {
	// ThatCalling adapts the specified call to an assertable one that's
	// expected to meet certain criteria.
	ThatCalling(func()) AssertableCall

	// ThatActual adapts the specified value to an assertable one that's
	// expected to meet certain criteria.
	ThatActual(value interface{}) AssertableValue

	// ThatActualError adapts the specified error to an assertable one that's
	// expected to meet certain criteria.
	ThatActualError(value error) AssertableError

	// ThatActualString adapts the specified string to an assertable one that's
	// expected to meet certain criteria.
	ThatActualString(value string) AssertableString

	// ThatActualTime adapts the specified time to an assertable one that's
	// expected to meet certain criteria.
	ThatActualTime(value *time.Time) AssertableTime

	// ThatType adapts the specified type to an assertable one that's
	// expected to meet certain criteria.
	ThatType(t reflect.Type) AssertableType
}

TestContext provides methods to assert what the test actually got.

func For

func For(t testing.TB, parameters ...interface{}) TestContext

For adapts from testing.TB to TestContext in order to allow the latter to assert on behalf of the former. The optional parameter(s) can be used to identify a specific test case in a data-driven test.

type ValueAssertionResult

type ValueAssertionResult interface {
	// Passed returns true if the assertion passed.
	Passed() bool

	// ThenDiffOnFail performed a diff of asserted values on assertion failure;
	// it prints a pretty diff of the actual and expected values used in
	// the failed assertion, in that order.
	// Returns the current ValueAssertionResult to allow for call-chaining.
	ThenDiffOnFail() ValueAssertionResult

	// ThenPrettyPrintOnFail pretty-prints asserted values on assertion failure;
	// Returns the current ValueAssertionResult to allow for call-chaining.
	ThenPrettyPrintOnFail() ValueAssertionResult

	// ThenRunOnFail performed the specified action on assertion failure;
	// in which case, it passes the actual and expected values used in
	// the failed assertion as parameters to the specified function.
	// Returns the current ValueAssertionResult to allow for call-chaining.
	ThenRunOnFail(action func(actual, expected interface{})) ValueAssertionResult
}

ValueAssertionResult represents operations that may be performed on the result of value assertion. For example:

assert.For(t).ThatActual(value).Equals(expected).ThenDiffOnFail()

It also can be used as a condition to perform extra test steps:

value := GetValue()
if assert.For(t).ThatActual(value).IsNotNil().Passed() {
    assert.For(t).ThatActual(value.GetFoo()).Equals(expected)
}

Or to perform a deeper analysis of the test values:

if !assert.For(t).ThatActual(value).Equals(expected).Passed() {
    analyze(value, expected) // e.g., analyze may look at common bugs
}

Conveniently, the last example above can be rewritten as:

assert.For(t).ThatActual(value).Equals(expected).ThenRunOnFail(analyze)

The above pattern allows for reuse of post-failure analysis and cleanup.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL