testo

package module
v0.0.0-...-ab5b5df Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2025 License: Apache-2.0 Imports: 16 Imported by: 0

README

🧑‍🍳 Testo

testo mascot

Testo is a modular testing framework for Go built on top of testing.T. It is focused on suite based tests and has an extensive plugin system.

Get started

Your project must use go 1.22 or newer.

No stable version yet - the following command installs the version from the latest commit:

go get github.com/metafates/testo@main

Next steps

Plugins

Testo can be extended with hooks, built-in methods overrides, custom test planning and more! See Allure plugin an example.

To do

  • Mock generation (?).
  • Stabilize API.
  • Interface generator CLI. Similar to ifacemaker but simplified for project needs. The goal is to simplify plugin development.
  • Move Allure plugin into separate repository

Documentation

Overview

Package testo is a modular testing framework built on top of testing.T. It is focused on suite based tests and has an extensive plugin system.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddDefaultOptions

func AddDefaultOptions(options ...plugin.Option)

AddDefaultOptions appends given options to the global options.

Global options are prepended to each RunSuite call.

func init() {
    testo.AddDefaultOptions(myplugin.OutputDir("..."))
}

func Inspect

func Inspect[T CommonT](t T) plugin.TInfo

Inspect returns meta information about given t.

Note that all plugins and suite tests share the same underlying T value.

This exists to separate essential functionality of T from plugin focused information.

func Run

func Run[T CommonT](
	t T,
	name string,
	f func(t T),
	options ...plugin.Option,
) bool

Run a subtest. It has the same purpose as testing.T.Run but retains the passed T type for the subtest function.

func RunSuite

func RunSuite[Suite any, T CommonT](t *testing.T, options ...plugin.Option)

RunSuite will run the tests under the given suite.

Suite type must be a pointer in a form of *MySuite.

Test is defined as a suite method in the form of "TestXXX" or "Test" which accepts a single parameter of the same type as T passed to this function.

Suite may optionally provide hooks by implementing their methods:

  • BeforeAll(T) - is called before all suite tests once.
  • BeforeEach(T) - is called before each suite test. T is shared with an actual test.
  • AfterEach(T) - is called after each suite test. T is shared with an actual test.
  • AfterAll(T) - is called after all suite tests once.

It also accepts options for the plugins which can be used to configure those plugins. See plugin.Option.

Types

type CommonT

type CommonT interface {
	testing.TB

	Parallel()
	// contains filtered or unexported methods
}

CommonT is the interface common for all T derivatives.

type T

type T struct {
	*testing.T
	// contains filtered or unexported fields
}

T is a wrapper for testing.T. This is a core entity in testo and used as a testing.T replacement.

The common pattern is to embed it into new struct type:

type MyT struct {
	*T

	SomePlugin
}

Plugins can also optionally embed it - testo will automatically initialize it by sharing the same value as an actual currently running test's T.

type SomePlugin struct { *T }

Note: using raw testing.T embedded in this struct directly is highly discouraged, unless some method is not provided by T.

func (*T) Deadline

func (t *T) Deadline() (time.Time, bool)

Deadline reports the time at which the test binary will have exceeded the timeout specified by the -timeout flag.

The ok result is false if the -timeout flag indicates “no timeout” (0).

func (*T) Error

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

Error is equivalent to Log followed by Fail.

func (*T) Errorf

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

Errorf is equivalent to Logf followed by Fail.

func (*T) Fail

func (t *T) Fail()

Fail marks the function as having failed but continues execution.

func (*T) FailNow

func (t *T) FailNow()

FailNow marks the function as having failed and stops its execution by calling runtime.Goexit (which then runs all deferred calls in the current goroutine). Execution will continue at the next test or benchmark. FailNow must be called from the goroutine running the test or benchmark function, not from other goroutines created during the test. Calling FailNow does not stop those other goroutines.

func (*T) Failed

func (t *T) Failed() bool

Failed reports whether the function has failed.

func (*T) Fatal

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

Fatal is equivalent to Log followed by FailNow.

func (*T) Fatalf

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

Fatalf is equivalent to Logf followed by FailNow.

func (*T) Log

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

Log formats its arguments using default formatting, analogous to Println, and records the text in the error log. For tests, the text will be printed only if the test fails or the -test.v flag is set. For benchmarks, the text is always printed to avoid having performance depend on the value of the -test.v flag.

func (*T) Logf

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

Logf formats its arguments according to the format, analogous to Printf, and records the text in the error log. A final newline is added if not provided. For tests, the text will be printed only if the test fails or the -test.v flag is set. For benchmarks, the text is always printed to avoid having performance depend on the value of the -test.v flag.

func (*T) Name

func (t *T) Name() string

Name returns the name of the running (sub-) test or benchmark.

The name will include the name of the test along with the names of any nested sub-tests. If two sibling sub-tests have the same name, Name will append a suffix to guarantee the returned name is unique.

func (*T) Parallel

func (t *T) Parallel()

Parallel signals that this test is to be run in parallel with (and only with) other parallel tests. When a test is run multiple times due to use of -test.count or -test.cpu, multiple instances of a single test never run in parallel with each other.

Note that running this method in the second level is not supported and treated as no op.

func TestFoo(t *T) {
   t.Parallel() // level 1, this is ok

   t.Run("...", func(t *T) {
		// level 2, this is not supported
		t.Parallel()

  		t.Run("...", func(t *T) {
			// level 3, supported
			t.Parallel()
		})
	})
}

func (*T) Run

func (t *T) Run(name string, f func(t *T), options ...plugin.Option) bool

Run runs f as a subtest of t called name. It runs f in a separate goroutine and blocks until f returns or calls t.Parallel to become a parallel test. Run reports whether f succeeded (or at least did not fail before calling t.Parallel).

Run may be called simultaneously from multiple goroutines, but all such calls must return before the outer test function for t returns.

Note: use Run function instead if you need to preserve type of custom T.

func (*T) Setenv

func (t *T) Setenv(key, value string)

Setenv calls os.Setenv(key, value) and uses Cleanup to restore the environment variable to its original value after the test.

Because Setenv affects the whole process, it cannot be used in parallel tests or tests with parallel ancestors.

func (*T) Skip

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

Skip is equivalent to Log followed by SkipNow.

func (*T) SkipNow

func (t *T) SkipNow()

SkipNow marks the test as having been skipped and stops its execution by calling runtime.Goexit. If a test fails (see Error, Errorf, Fail) and is then skipped, it is still considered to have failed. Execution will continue at the next test or benchmark. See also FailNow. SkipNow must be called from the goroutine running the test, not from other goroutines created during the test. Calling SkipNow does not stop those other goroutines.

func (*T) Skipf

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

Skipf is equivalent to Logf followed by SkipNow.

func (*T) Skipped

func (t *T) Skipped() bool

Skipped reports whether the test was skipped.

func (*T) SuiteName

func (t *T) SuiteName() string

SuiteName returns current suite name.

func (*T) TempDir

func (t *T) TempDir() string

TempDir returns a temporary directory for the test to use. The directory is automatically removed when the test and all its subtests complete. Each subsequent call to t.TempDir returns a unique directory; if the directory creation fails, TempDir terminates the test by calling Fatal.

Directories

Path Synopsis
examples
04_plugins command
internal
pkg
plugins/allure
Package allure provides Allure provider as a plugin for testo.
Package allure provides Allure provider as a plugin for testo.
plugins/allure/internal/stacktrace
Package stacktrace provides support for gathering stack traces efficiently.
Package stacktrace provides support for gathering stack traces efficiently.
Package plugin provides plugin primitives for using plugins in testo.
Package plugin provides plugin primitives for using plugins in testo.

Jump to

Keyboard shortcuts

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