pbt is a property-based testing library for Go that helps you verify program behavior against broad classes of generated inputs instead of a few hand-written test cases.
- Fast integration in existing
testingworkflows - Deterministic reproduction via explicit random seeds
- Configurable run count and generator size growth
- Counterexample shrinking for easier debugging
- Shrink traces, failure classifiers, labels, and coverage buckets
- Deterministic parallel execution with partitioned seeds
- Stateful/model-based testing with command sequences and invariants
- Small, modular package layout for maintainability
Add the module to your project:
import "github.com/Quad4-Software/pbt/pkg/pbt"package mypkg_test
import (
"testing"
"github.com/Quad4-Software/pbt/pkg/pbt"
)
func TestStringRoundTrip(t *testing.T) {
property := pbt.ForAll(
"double reverse preserves value",
pbt.StringASCII(0, 64),
func(in string) bool {
return reverse(reverse(in)) == in
},
pbt.WithShrinker[string](pbt.StringShrinker()),
)
pbt.Check(t, property, pbt.WithRuns(1000), pbt.WithSeed(42))
}For non-testing usage, call pbt.CheckResult and inspect the returned result.
pkg/pbt: public API for generators, properties, shrinking, and executioncmd/pbt-example: runnable example program
pbt.ForAll: defines a property from generator + predicatepbt.Check: executes a property and fails the test on first failurepbt.CheckResult: executes and returns a structured resultpbt.WithRuns,pbt.WithMaxSize,pbt.WithSeed,pbt.WithTimeout: execution configuration optionspbt.WithParallelism: deterministic partitioned parallel executionpbt.WithShrinkParallelism: shrink strategy worker tuning- Built-in generators:
Int,IntRange,Bool,Float64,StringASCII,SliceOf,Map - Conditional generation:
SuchThatandSuchThatFallbackfilter source values by predicate - Higher-order generator combinators:
Tuple2,Tuple3,Product2,OneOf,Frequency,Recursive - Built-in shrinkers:
IntShrinker,StringShrinker,SliceShrinker - Failure triage hooks:
WithClassifier,WithLabeler,WithBucketer - Coverage thresholds:
WithLabelCoverageRules,WithBucketCoverageRules - Distribution tooling:
AnalyzeDistribution,ValidateDistribution - Stateful testing:
CheckStateful,CheckStatefulResult,CommandSequence - Replay fixtures:
SerializeCounterexample,DeserializeCounterexample,Result.ToReplayFixture - Replay runners:
ReplayFixtureFile,ReplayStatefulFixtureFile - Hook/event bus:
Hook,HookFuncs,WithHook,WithHooks - Stateful hook/event bus:
StatefulHook,StatefulHookFuncs,CommandModel.Hooks
Use pbt.WithSeed to reproduce any failure exactly. The Result and failure message include the seed used for the run.
You can persist failing cases by converting a failing Result into a ReplayFixture and writing it to disk.
This repository includes a Taskfile.yml for common workflows:
task fmt: format codetask vet: static analysistask lint: run revive lintertask test: run unit teststask test:cov: run tests with coverage (fails if below 75%)task ci: run format, vet, lint, and tests
This library is structured for production use and intended to grow with additional generators, domain-specific shrinkers, and richer reporting over time.