tester: github.com/workfit/tester/assert Index | Files

package assert

import "github.com/workfit/tester/assert"

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

Package Files

assert.go call.go doc.go error.go result.go string.go time.go type.go value.go

Constants

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

func PrettyPrint Uses

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

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

func PrintDiff Uses

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

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

type AssertableCall Uses

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 Uses

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 Uses

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 Uses

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 Uses

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 Uses

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 Uses

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 Uses

func (err ErrorString) Error() string

type TestContext Uses

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 Uses

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 Uses

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.

Package assert imports 12 packages (graph) and is imported by 1 packages. Updated 2019-07-01. Refresh now. Tools for package owners.