Releases: adamluzsi/testcase
Support for testing library creators
Support for testing library creators
The new StubTB allows testing test-helpers functions with a StubTB
that behaves like the testing.TB
.
Expose http.Request and ResponseRecorder in httpspec
This should allow reusing them as commonly used testcase.Var(s) in specs focusing on HTTP coverage.
SQL & NoSQL injection strings
*testcase.T.Random.String
from now on will return generic SQL and NoSQL injection strings as well.- signature change for fixtures.New to use Go's generics syntax.
Naughty Strings
The Big List of Naughty Strings is incorporated into the testcase's random generator.
Unit tests that use these randomly generated string values will double as an enhanced fuzzing test.
To run your unit tests with various naughty strings, use the -count
testing flag.
Each test execution by -count
will run with a different naughty string.
go test -count 1024 -run TestMyUnit
Benchmark improvements
Exclude the time it takes to construct a dependency from the benchmark time.
func Benchmark_myBench(b *testing.B) {
s := testcase.NewSpec(b)
v := testcase.Let(s, func(t *testcase.T) int {
// benchmark time is not tracked here
time.Sleep(time.Second / 2)
return t.Random.Int()
})
s.Test(``, func(t *testcase.T) {
// benchmark time is tracked here
time.Sleep(time.Second)
_ = v.Get(t)
})
}
unify the signature between Retry.Assert and T.Eventually
Both testcase#Retry.Assert and testcase#T.Eventually use the same signature for convenience.
waiter := testcase.Waiter{
WaitDuration: time.Millisecond,
WaitTimeout: time.Second,
}
r := testcase.Retry{Strategy: waiter}
r.Assert(t, func(it assert.It) { // <- assert.It is passed here instead of testing.TB
if rand.Intn(1) == 0 {
it.Fatal(`boom`)
}
})
add support for asserting Error values
Assertions now support ErrorIs
assertion where you can check both if the error is equal to an expected one, or part of the actual error's error chain.
This leaves room for later refactoring like wrapping the error value to give better context to the returned error, without breaking a test.
actualErr := errors.New("boom")
assert.Must(tb).ErrorIs(errors.New("boom"), actualErr) // passes for equality
assert.Must(tb).ErrorIs(errors.New("boom"), fmt.Errorf("wrapped error: %w", actualErr)) // passes for wrapped errors
testing framework generics release
testcase's API is updated to remove the need for boilerplate when working with test bounded variables.
previous version had to rely on empty interface casting:
s := testcase.NewSpec(t)
input := testcase.Var{ID: "input"}
subject := func(t *testcase.T) string {
return MyFunc(input.Get(t).(string))
}
The latest release uses type safety through generics:
s := testcase.NewSpec(t)
input := testcase.Var[string]{ID: "input"}
subject := func(t *testcase.T) string {
return MyFunc(input.Get(t))
}
Happy Coding/Specifying! :)
v0.42.0
testcase.Race
Race is a test helper that allows you to create a race situation easily.
This is useful when you work on a component that requires thread-safety.
By using the Race helper, you can write an example use of your component,
and run the testing suite with go test -race
.
The race detector then should be able to notice issues with your implementation.
testcase.T.Random
T.Random is a random generator that uses the Spec seed.
When a test fails with random input from Random generator,
the failed test scenario can be recreated simply by providing the same TESTCASE_SEED
as you can read from the console output of the failed test.
testcase.Var Thread Safety
testcase.Var.Get
and testcase.Var.Set
now thread-safe.
v0.34.0
testcase.Contract & testcase.RunContract
Contract meant to represent a Role Interface Contract.
A role interface is a static code contract that expresses behavioral expectations as a set of method signatures.
A role interface used by one or many consumers.
These consumers often use implicit assumptions about how methods of the role interface behave.
Using these assumptions makes it possible to simplify the consumer code.
In testcase convention, instead of relying on implicit assumptions, the developer should create an explicit interface testing suite, in other words, a Contract.
The code that supplies a role interface then able to import a role interface Contract,
and confirm if the expected behavior is fulfilled by the implementation.
further references: