fixenv

package module
v0.6.1 Latest Latest
Warning

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

Go to latest
Published: Nov 26, 2023 License: MIT Imports: 8 Imported by: 0

README

Go Reference Coverage Status GoReportCard Mentioned in Awesome Go

Go Fixtures

Inspired by pytest fixtures.

Examples

The package provide engine for write and use own fixtures.

Fixture - function-helper for provide some object/service for test. Fixture calls with same parameters cached and many time calls of the fixture return same result and work did once only.

package example

// counter fixture - increment globalCounter every non cached call
// and return new globalCounter value
// cache shared one test 
func counter(e fixenv.Env) int {...}

func TestCounter(t *testing.T) {
	e := fixenv.NewEnv(t)

	r1 := counter(e)
	r2 := counter(e)
	if r1 != r2 {
		t.Error()
	}

	t.Run("subtest", func(t *testing.T) {
		e := fixenv.NewEnv(t)
		r3 := counter(e)
		if r3 == r1 {
			t.Error()
		}
	})
}

For example with default scope test - it work will done once per test. With scope TestAndSubtests - cache shared by test (TestFunction(t *testing.T)) and all of that subtest. With package scope - result cached for all test in package. Fixture can have cleanup function, that called while out of scope.

Fixture can call other fixtures, cache shared between them.

For example simple account test:

package example

// db create database abd db struct, cached per package - call
// once and same db shared with all tests
func db(e Env)*DB{...}

// DbCustomer - create customer with random personal data
// but fixed name. Fixture result shared by test and subtests, 
// then mean many calls Customer with same name will return same
// customer object.
// Call Customer with other name will create new customer
// and resurn other object.
func DbCustomer(e Env, name string) Customer {
	// ... create customer
	db(e).CustomerStore(cust)
	// ...
	return cust
}

// DbAccount create bank account for customer with given name.
func DbAccount(e Env, customerName, accountName string)Account{
	cust := DbCustomer(e, customerName)
	// ... create account
	db(e).AccountStore(acc)
	// ...
	return acc
}

func TestFirstOwnAccounts(t *testing.T){
	e := NewEnv(t)
	// background:
	// create database
	// create customer bob 
	// create account from
	accFrom := DbAccount(e, "bob", "from")
	
	// get existed db, get existed bob, create account to
	accTo := DbAccount(e, "bob", "to")
	
	PutMoney(accFrom, 100)
	SendMoney(accFrom, accTo, 20)
	if accFrom != 80 {
		t.Error()
	}
	if accTo != 20 {
		t.Error()   
	}
	
	// background:
	// delete account to
	// delete account from
	// delete customer bob
}

func TestSecondTransferBetweenCustomers(t *testing.T){
	e := NewEnv(t)
	
	// background:
	// get db, existed from prev test
	// create customer bob
	// create account main for bob
	accFrom := DbAccount(e, "bob", "main")
	
	// background:
	// get existed db
	// create customer alice
	// create account main for alice
	accTo := DbAccount(e, "alice", "main")
	PutMoney(accFrom, 100)
	SendMoney(accFrom, accTo, 20)
	if accFrom != 80 {
		t.Error()
	}
	if accTo != 20 {
		t.Error()
	}
	
	// background:
	// remove account of alice
	// remove customer alice
	// remove account of bob
	// remove customer bob
}

// background:
// after all test finished drop database

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrSkipTest - error for return from fixtures
	// return the error mean skip test and cache decision about skip test for feature fixtures call
	// as usual result/error cache.
	//
	// Use special error instead of detect of test.SkipNow() need for prevent run fixture in separate goroutine for
	// skip detecting
	ErrSkipTest = errors.New("skip test")
)

Functions

func Cache added in v0.2.3

func Cache[TRes any](env Env, cacheKey any, opt *FixtureOptions, f func() (TRes, error)) TRes

Cache is call f once per cache scope (default per test) and cache result (success or error). All other calls of the f will return same result Deprecated: Use CacheResult

func CacheResult added in v0.5.4

func CacheResult[TRes any](env Env, f GenericFixtureFunction[TRes], options ...CacheOptions) TRes

CacheResult is call f once per cache scope (default per test) and cache result (success or error). All other calls of the f will return same result.

func CacheWithCleanup added in v0.3.0

func CacheWithCleanup[TRes any](env Env, cacheKey any, opt *FixtureOptions, f func() (TRes, FixtureCleanupFunc, error)) TRes

CacheWithCleanup is call f once per cache scope (default per test) and cache result (success or error). All other calls of the f will return same result. Used when fixture need own cleanup after exit from test scope Deprecated: Use CacheResult

func RunTests added in v0.6.0

func RunTests(m RunTestsI, opts ...CreateMainTestEnvOpts) int

RunTests runs the tests. It returns an exit code to pass to os.Exit.

Usage: declare in _test file TestMain function:

func TestMain(m *testing.M) {
	 os.Exit(fixenv.RunTests(m))
}

Types

type CacheOptions added in v0.5.4

type CacheOptions struct {
	// Scope for cache result
	Scope CacheScope

	// Key for cache results, must be json serializable value
	CacheKey interface{}
	// contains filtered or unexported fields
}

type CacheScope

type CacheScope int

CacheScope define life time of fixture value and allow use independent fixture values for different scopes, but share same value for one scope, which can be more then one test

const (
	// ScopeTest mean fixture function with same parameters called once per every test and subtests. Default value.
	// Second and more calls will use cached value.
	ScopeTest CacheScope = iota

	// ScopePackage mean fixture function with same parameters called once per package
	// for use the scope with TearDown function developer must initialize global handler and cleaner at TestMain.
	ScopePackage

	// ScopeTestAndSubtests mean fixture cached for top level test and subtests
	ScopeTestAndSubtests
)

type CreateMainTestEnvOpts

type CreateMainTestEnvOpts struct {
	// Fatalf equivalent of Fatalf in test.
	// Must write log, then exit from goroutine.
	// It may be panic.
	// Fatalf called if main envinment can't continue work
	Fatalf FatalfFunction

	// SkipNow is equivalent of SkipNow in test
	// default is panic
	//
	// 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.
	SkipNow SkipNowFunction
}

CreateMainTestEnvOpts is options for manage package env scope

type Env

type Env interface {
	// T - return t object of current test/benchmark.
	T() T

	// CacheResult add result of call f to cache and return same result for all
	// calls for the same function and cache options within cache scope
	CacheResult(f FixtureFunction, options ...CacheOptions) interface{}

	// Cache result of f calls
	// f call exactly once for every combination of scope and params
	// params must be json serializable (deserialize not need)
	// Deprecated: will be removed in next versions
	// Use Env.CacheResult instead.
	Cache(cacheKey interface{}, opt *FixtureOptions, f FixtureCallbackFunc) interface{}

	// CacheWithCleanup cache result of f calls
	// f call exactly once for every combination of scope and params
	// params must be json serializable (deserialize not need)
	// Deprecated: will be removed in next versions
	// Use Env.CacheResult instead.
	CacheWithCleanup(cacheKey interface{}, opt *FixtureOptions, f FixtureCallbackWithCleanupFunc) interface{}
}

Env - fixture cache engine. Env interface described TEnv method and need for easy reuse different Envs with same fixtures.

The interface can be extended. Create own Envs with embed TEnv or the interface for auto-implement all methods in the future.

type EnvT

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

EnvT - fixture cache and cleanup engine it created from test and pass to fixture function manage cache of fixtures, depends from fixture, param, test, scope. and call cleanup, when scope closed. It can be base to own, more powerful local environments.

func CreateMainTestEnv

func CreateMainTestEnv(opts *CreateMainTestEnvOpts) (env *EnvT, tearDown func())

CreateMainTestEnv called from TestMain for create global environment. It need only for use ScopePackage cache scope. If ScopePackage not used - no need to create main env.

func New added in v0.4.0

func New(t T) *EnvT

New create EnvT from test

func NewEnv

func NewEnv(t T) *EnvT

NewEnv create EnvT from test Deprecated: use New instead

func (*EnvT) Cache

func (e *EnvT) Cache(cacheKey interface{}, opt *FixtureOptions, f FixtureCallbackFunc) interface{}

Cache call from fixture and manage call f and cache it. Cache must be called direct from fixture - it use runtime stacktrace for detect called method - it is part of cache key. params - part of cache key. Usually - parameters, passed to fixture.

it allow use parametrized fixtures with different results.
params must be json serializable.

opt - fixture options, nil for default options. f - callback - fixture body. Cache guarantee for call f exactly once for same Cache called and params combination. Deprecated: will be removed in next versions. Use EnvT.CacheResult instead

func (*EnvT) CacheResult added in v0.5.4

func (e *EnvT) CacheResult(f FixtureFunction, options ...CacheOptions) interface{}

CacheResult call f callback once and cache result (ok and error), then return same result for all calls of the callback without additional calls f with same options calls max once per test (or defined test scope)

func (*EnvT) CacheWithCleanup added in v0.3.0

func (e *EnvT) CacheWithCleanup(cacheKey interface{}, opt *FixtureOptions, f FixtureCallbackWithCleanupFunc) interface{}

CacheWithCleanup call from fixture and manage call f and cache it. CacheWithCleanup must be called direct from fixture - it use runtime stacktrace for detect called method - it is part of cache key. params - part of cache key. Usually - parameters, passed to fixture.

it allow use parametrized fixtures with different results.
params must be json serializable.

opt - fixture options, nil for default options. f - callback - fixture body. cleanup, returned from f called while fixture cleanup Cache guarantee for call f exactly once for same Cache called and params combination. Deprecated: will be removed in next versions. Use EnvT.CacheResult instead

func (*EnvT) T

func (e *EnvT) T() T

T return test from EnvT created

type FatalfFunction

type FatalfFunction func(format string, args ...interface{})

FatalfFunction function signature of Fatalf

type FixtureCallbackFunc

type FixtureCallbackFunc func() (res interface{}, err error)

FixtureCallbackFunc - function, which result can cached res - result for cache. if err not nil - T().Fatalf() will called with error message if res exit without return (panic, GoExit, t.FailNow, ...) then cache error about unexpected exit

type FixtureCallbackWithCleanupFunc added in v0.3.0

type FixtureCallbackWithCleanupFunc func() (res interface{}, cleanup FixtureCleanupFunc, err error)

FixtureCallbackWithCleanupFunc - function, which result can cached res - result for cache. cleanup - if not nil - call on fixture cleanup. It called exactly once for every successfully call fixture if err not nil - T().Fatalf() will called with error message if res exit without return (panic, GoExit, t.FailNow, ...) then cache error about unexpected exit

type FixtureCleanupFunc

type FixtureCleanupFunc func()

FixtureCleanupFunc - callback function for cleanup after fixture value out from lifetime scope it called exactly once for every succesully call fixture

type FixtureFunction added in v0.5.4

type FixtureFunction func() (*Result, error)

FixtureFunction - callback function with structured result

type FixtureOptions

type FixtureOptions struct {
	// Scope for cache result
	Scope CacheScope
	// contains filtered or unexported fields
}

FixtureOptions options for fixenv engine for custom manage fixture

type GenericFixtureFunction added in v0.5.4

type GenericFixtureFunction[ResT any] func() (*GenericResult[ResT], error)

GenericFixtureFunction - callback function with structured result

type GenericResult added in v0.5.4

type GenericResult[ResT any] struct {
	Value ResT
	ResultAdditional
}

GenericResult of fixture callback

func NewGenericResult added in v0.5.4

func NewGenericResult[ResT any](res ResT) *GenericResult[ResT]

NewGenericResult return result struct and nil error. Use it for smaller boilerplate for define generic specifications

func NewGenericResultWithCleanup added in v0.5.4

func NewGenericResultWithCleanup[ResT any](res ResT, cleanup FixtureCleanupFunc) *GenericResult[ResT]

type Result added in v0.5.4

type Result struct {
	Value interface{}
	ResultAdditional
}

Result of fixture callback

func NewResult added in v0.5.4

func NewResult(res interface{}) *Result

func NewResultWithCleanup added in v0.5.4

func NewResultWithCleanup(res interface{}, cleanup FixtureCleanupFunc) *Result

type ResultAdditional added in v0.5.4

type ResultAdditional struct {
	Cleanup FixtureCleanupFunc
}

type RunTestsI added in v0.6.0

type RunTestsI interface {
	// Run runs the tests. It returns an exit code to pass to os.Exit.
	Run() (code int)
}

type SkipNowFunction added in v0.2.2

type SkipNowFunction func()

SkipNowFunction is function signature for SkipNow

type T

type T interface {
	// Cleanup registers a function to be called when the test (or subtest) and all its subtests complete.
	// Cleanup functions will be called in last added, first called order.
	Cleanup(func())

	// Fatalf is equivalent to Logf followed by FailNow.
	//
	// 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.
	//
	// 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.
	Fatalf(format string, args ...interface{})

	// 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.
	Logf(format string, args ...interface{})

	// 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.
	Name() string

	// SkipNow is followed by testing.T.SkipNow().
	// Don't use SkipNow() for skip test from fixture - use special error ErrSkipTest for it.
	//
	// 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.
	SkipNow()

	// Skipped reports whether the test was skipped.
	Skipped() bool
}

T is subtype of testing.TB

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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