Testo – testing framework for Go with plugins, parametrization, parallel tests and more

Testo is a modular, zero-dependency testing framework for Go. It has a unique plugin system which was inspired by Pytest. Plugins can generate reports, add new functionality, plan test execution and much more.

Testo started as an internal project at a large big-tech company and was recently open-sourced. It powers thousands of end-to-end tests daily at enterprise scale.

GitHub: github.com/ozontech/testo

Feedback and contributions are greatly appreciated!

go get github.com/ozontech/testo

It comes with its own VS Code extension for running tests in suites.

Features

  • Plugins - adapt your tests to any scenario with features you need.
  • Parametrized tests - define a test once, repeat it with different parameters.
  • Parallel tests - t.Parallel() just works.
  • Lifecycle hooks - before and after any suite, test & sub-test.
  • Test annotations - attach static options to any test.
  • Informative errors and traces.
  • Suites, sub-tests & sub-suites - organize your tests the way you need.
  • Test reflection - deeply inspect test’s meta-information.
  • Caching - key-value storage persistent between test runs.
  • Zero dependencies.

Example

package main

import (
	"testing"

	"github.com/ozontech/testo"
	allure "github.com/ozontech/testo-allure"
	"github.com/ozontech/testo-toppings/parallel"
)

type T struct {
	*testo.T

	// plugins:

	*allure.PluginAllure     // generate allure reports
	*parallel.PluginParallel // make all tests parallel by default
}

func TestSingle(t *testing.T) {
	testo.RunTest(t, func(t T) {
		t.Log("hello")
	})
}

func TestNamed(t *testing.T) {
	t.Run("First test", testo.Test(func(t T) {
		t.Log("greetings")
	}))

	t.Run("Second test", testo.Test(func(t T) {
		t.Log("hola")
	}))
}

func TestSuite(t *testing.T) {
	testo.RunSuite(t, new(Functional))
}

type Functional struct {
	testo.Suite[T]
}

func (Functional) TestSimple(t T) {
	t.Log("hello")
}

// Parameterized test which will be executed for all combinations of A & B.
func (Functional) TestAdd(t T, p struct{ A, B int }) {
	t.Log(p.A, p.B)
}

// Special CasesXxx methods
func (Functional) CasesA() []int {
	return []int{1, 2, 3}
}

func (Functional) CasesB() []int {
	return []int{100, 200}
}