await

package
v1.32.1 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package await provides polling-based test assertions as a replacement for testify's Eventually, EventuallyWithT, and their formatted variants.

By default, it enforces a 10s timeout for each await attempt.

Improvements over testify's eventually functions:

  • Misuse detection: accidentally using the real *testing.T (e.g. s.T() or suite assertion methods) instead of the callback's collect T is a common mistake. This package detects it and fails with a clear message.

  • Safer bool predicates: unlike testify's Eventually, RequireTrue only accepts func() bool, so returning false is the sole retry signal. If the predicate accidentally marks the real test failed, it reports that immediately instead of polling until timeout.

  • Timeout-aware callbacks: callbacks receive a context derived from the parent context and canceled when the await timeout or test deadline is reached, so RPCs and blocking waits can exit instead of continuing after the retry window has expired.

  • Panic propagation: if the condition panics (e.g. nil dereference), the panic is propagated immediately rather than being silently swallowed or retried until timeout. See https://github.com/stretchr/testify/issues/1810

  • Bounded goroutine lifetime: each attempt completes before the next starts, avoiding the overlapping-attempt data races and "panic: Fail in goroutine after Test has completed" crashes seen with testify's Eventually. See https://github.com/stretchr/testify/issues/1611

  • Deadlock detection: a condition that ignores t.Context() is abandoned after a grace period, producing a clear "does it honor t.Context()?" failure instead of hanging until go test -timeout.

  • Condition always runs: testify's Eventually can fail without ever running the condition due to a timer/ticker race with short timeouts. This package runs the condition immediately on the first iteration. See https://github.com/stretchr/testify/issues/1652

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Require

func Require(ctx context.Context, tb testing.TB, condition func(*T), timeout, pollInterval time.Duration)

Require polls condition until it returns without assertion failures, or until ctx is canceled or timeout expires (whichever is earliest).

Pass the *await.T to require.*/assert.* — failures cause a retry, not a test failure. Use t.Context() inside the callback to honor the timeout.

func RequireTrue

func RequireTrue(tb testing.TB, condition func() bool, timeout, pollInterval time.Duration)

RequireTrue runs `condition` repeatedly until it returns true, or until the timeout expires. The timeout is capped at the test's deadline, if one is set.

Use RequireTrue for simple local predicates only. Do not use assertions or side effects in the predicate - use Require for these.

func RequireTruef

func RequireTruef(tb testing.TB, condition func() bool, timeout, pollInterval time.Duration, msg string, args ...any)

RequireTruef is like RequireTrue but accepts a format string that is included in the failure message when the condition is not satisfied before the timeout.

func Requiref

func Requiref(ctx context.Context, tb testing.TB, condition func(*T), timeout, pollInterval time.Duration, msg string, args ...any)

Requiref is like Require but adds a formatted message to the timeout failure.

Types

type T

type T struct {
	// contains filtered or unexported fields
}

T is passed to the condition callback. It intercepts assertion failures so the polling loop can retry.

Only use T for assertions (require.*, assert.*, t.Errorf, t.Fatal, t.FailNow).

func (*T) AssertionT

func (t *T) AssertionT() require.TestingT

AssertionT returns the current attempt as an assertion target.

func (*T) Context

func (t *T) Context() context.Context

Context returns the await-scoped context for the current attempt.

func (*T) Error

func (t *T) Error(args ...any)

Error records an error message for reporting on timeout.

func (*T) Errorf

func (t *T) Errorf(format string, args ...any)

Errorf records an error message for reporting on timeout.

func (*T) Fail

func (t *T) Fail()

Fail marks the current attempt as failed without stopping it.

func (*T) FailNow

func (t *T) FailNow()

FailNow is called by require.* on failure. It stops the current attempt. Unlike testing.TB.FailNow(), this does NOT mark the test as failed.

func (*T) Failed

func (t *T) Failed() bool

Failed reports whether this attempt has failed.

func (*T) Fatal

func (t *T) Fatal(args ...any)

Fatal records an error message and stops this attempt.

func (*T) Fatalf

func (t *T) Fatalf(format string, args ...any)

Fatalf records an error message and stops this attempt.

func (*T) Helper

func (t *T) Helper()

Helper marks the calling function as a test helper.

func (*T) Require

func (t *T) Require() *require.Assertions

Require returns assertions bound to the current attempt.

func (*T) TB

func (t *T) TB() testing.TB

TB returns the test handle running the await loop.

Jump to

Keyboard shortcuts

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