test

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2025 License: MIT Imports: 6 Imported by: 3

README

krostar/test

Go Reference Go Report Card Go Version

A lightweight, dependency-minimal testing library for Go that provides detailed assertion messages through source code analysis. Designed to make your tests as clear, readable, and maintainable as the code being tested.

Why

  • Simplicity: Write standard Go expressions in your tests without learning a complex API
  • Clarity: Get error messages that directly relate to your test code through source analysis
  • Minimalism: Enjoy a small, focused API instead of numerous specialized assertions
  • Readability: Keep your test code looking like regular Go code
  • Composability: Easily create custom test checks

Installation

go get github.com/krostar/test

Quick start

Assert and Require

The library exposes two main functions:

  • Assert(t, condition, [msg...]): Reports test failure if condition is false but continues execution
  • Require(t, condition, [msg...]): Reports test failure and stops execution immediately if condition is false
package foo

import (
    "context"
    "errors"
    "testing"

    "github.com/krostar/test"
)

func Test_Something(t *testing.T) {
    got := 42
    want := 24

    test.Assert(t, got == want)

    err := errors.New("test error")
    test.Assert(t, errors.Is(err, context.Canceled), "context should have canceled and produced an error")
}

Output:

go test -v ./...
=== RUN   Test_Something
    test_test.go:13: Error: got is not equal to want
    test_test.go:17: Error: context.Canceled is not in the error tree of err [context should have canceled and produced an error]
--- FAIL: Test_Something (0.36s)

FAIL
Automatic error messages

The library generates detailed error messages by analyzing your test expressions:

// With simple expressions
test.Assert(t, user.Name == "John")
// Error: user.Name is not equal to "John"

// With compound expressions
test.Assert(t, err == nil && user != nil)
// Error: err is not nil, or user is nil

// With function calls
test.Assert(t, strings.Contains(response, "success"))
// Error: response does not contain "success"
Built-in checks

The check package provides several built-in checks for common testing scenarios:

import (
    "testing"
    "time"
    "context"

    "github.com/krostar/test"
    "github.com/krostar/test/check"
)

func TestChecks(t *testing.T) {
    // Deep comparison
    got := map[string]int{"a": 1, "b": 2}
    want := map[string]int{"b": 2, "a": 1}
    test.Assert(check.Compare(t, got, want))

    // Wait for async condition
    test.Assert(check.Eventually(test.Context(t), t, func(ctx context.Context) error {
        // Check some condition that may take time to become true
        return nil
    }, time.Millisecond*100))

    // Verify a function panics
    test.Assert(check.Panics(t, func() { panic("boom") }, nil))

    // Invert a check
    test.Assert(check.Not(check.Panics(t, func() { panic("boom") }, nil)))

    // Verify zero values
    test.Assert(check.ZeroValue(t, 0))
}
Custom Checks

You can easily create custom checks to extend functionality:

func IsValidUser(t test.TestingT, user *User) (test.TestingT, bool, string) {
    if user == nil {
        return t, false, "user is nil"
    }

    if user.ID == 0 {
        return t, false, "user ID should not be zero"
    }

    if user.Name == "" {
        return t, false, "user name should not be empty"
    }

    return t, true, "user is valid"
}

// Usage
test.Assert(IsValidUser(t, user))

Test Doubles

The double package provides test doubles for testing code that uses a testing.T interface:

import (
    "testing"

    "github.com/krostar/test"
    "github.com/krostar/test/double"
)

func TestWithSpy(t *testing.T) {
    // Create a spy on a fake to record calls
    spyT := double.NewSpy(double.NewFake())

    // Use the spy in your test
    functionUnderTest(spyT)

    // Verify calls were made
    spyT.ExpectRecords(t, false,
        double.SpyTestingTRecord{Method: "Logf", Inputs: []any{"Success: %s", double.SpyTestingTRecordIgnoreParam}},
    )

    // Verify test passed/failed
    spyT.ExpectTestToPass(t)
}

Comparison with Other Testing Libraries

Library API Design Implementation Error Messages Maintenance
Go Standard Library ✅ Core functionality only ✅ Standard go, no external dependencies ❌ Basic messages requiring manual formatting ✅ Part of go core
stretchr/testify ⚠️ Very large API with many similar assertions ❌ Heavy use of reflection
⚠️ Encourages using non native (suite), or often misused (mock) packages
✅ Detailed error messages
✅ Good diffs for complex types
✅ Actively maintained
✅ Well-established in community
gotest.tools/v3 ✅ Minimalist and clear ✅ Thin layer over go testing lib ✅ Detailed error messages
✅ Good diffs for complex types
✅ Actively maintained
matryer/is ⚠️ Extremely minimalist API ✅ Thin layer over go testing lib ⚠️ Basic but clear error messages ❌ No longer actively maintained
krostar/test ✅ Minimalist and clear ✅ Thin layer over go testing lib ✅ Detailed error messages
⚠️ Diffs via go-cmp integration when using Compare check
✅ Actively maintained

Documentation

Overview

Package test provides a lightweight assertion library for Go tests.

It offers simple assertion functions like Assert and Require which provide detailed error messages by analyzing the expression being tested.

Index

Constants

This section is empty.

Variables

View Source
var (
	// SuccessMessageEnabled controls whether to enable success messages logging in assert functions.
	SuccessMessageEnabled = false
)

Functions

func Assert

func Assert(t TestingT, result bool, msgAndArgs ...any) bool

Assert checks the provided boolean `result`.

If `result` is false, it logs a detailed error message based on source code parsing and fails the test. The error message includes the expression that evaluated to false.

Optionally, `msgAndArgs` can be provided to add custom messages to the error output.

If check.SuccessMessageEnabled is true, it will log a success message even if `result` is true.

Assert returns the same value as `result`.

Example usage:

func Test_Something(t *testing.T) {
	user, err := GetUser(context.Background(), "[email protected]")
	test.Require(t, err == nil && user != nil)
	test.Assert(t, user.Name == "Bob" && user.Age == 42)
}

-> Error: user.Name is not equal to "Bob", or user.Age is not equal to 42.

func Context

func Context(t TestingT) context.Context

Context returns a context.Context derived from the test's context.

This function extracts the context from the TestingT and handles timeout management: - If the test has a deadline, it adjusts the deadline to allow for clean shutdown - It reserves a small portion of time before the test deadline to allow for proper cleanup - The returned context will be automatically canceled when the test completes

func Require

func Require(t TestingT, result bool, msgAndArgs ...any)

Require stops the test execution immediately if `result` is false. Otherwise, it behaves the same as Assert.

Types

type TestingT

type TestingT internal.TestingT

TestingT is an interface for testing types. It mimics the standard library's *testing.T.

Directories

Path Synopsis
code
Package code provides utilities for working with Go source code and ASTs.
Package code provides utilities for working with Go source code and ASTs.
message
Package message provides functions for generating formatted messages for assertions.
Package message provides functions for generating formatted messages for assertions.

Jump to

Keyboard shortcuts

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