1# Rapid [![GoDoc][godoc-img]][godoc] ![CI][ci-img] 2 3Rapid is a Go library for property-based testing. 4 5Rapid checks that properties you define hold for a large number 6of automatically generated test cases. If a failure is found, rapid 7automatically minimizes the failing test case before presenting it. 8 9Property-based testing emphasizes thinking about high level properties 10the program should satisfy rather than coming up with a list 11of individual examples of desired behavior (test cases). 12This results in concise and powerful tests that are a pleasure to write. 13 14Design and implementation of rapid are heavily inspired by 15[Hypothesis](https://github.com/HypothesisWorks/hypothesis), which is itself 16a descendant of [QuickCheck](https://hackage.haskell.org/package/QuickCheck). 17 18## Features 19 20- Idiomatic Go API 21 - Designed to be used together with `go test` and the `testing` package 22 - Works great with libraries like 23 [testify/require](https://godoc.org/github.com/stretchr/testify/require) and 24 [testify/assert](https://godoc.org/github.com/stretchr/testify/assert) 25- Automatic minimization of failing test cases 26- No dependencies outside of the Go standard library 27 28### Planned features 29 30- Automatic persistence of failing test cases 31 32## Examples 33 34Here is what a trivial test using rapid looks like: 35 36```go 37package rapid_test 38 39import ( 40 "net" 41 "testing" 42 43 "pgregory.net/rapid" 44) 45 46func TestParseValidIPv4(t *testing.T) { 47 const ipv4re = `(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])` + 48 `\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])` + 49 `\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])` + 50 `\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])` 51 52 rapid.Check(t, func(t *rapid.T) { 53 addr := rapid.StringMatching(ipv4re).Draw(t, "addr").(string) 54 ip := net.ParseIP(addr) 55 if ip == nil || ip.String() != addr { 56 t.Fatalf("parsed %q into %v", addr, ip) 57 } 58 }) 59} 60``` 61 62You can [play around](https://play.golang.org/p/Lp_C99wMBve) with the IPv4 63regexp to see what happens when it is generating invalid addresses 64(or try to pass the test with your own `ParseIP` implementation). More complete 65function ([source code](./example_function_test.go), 66[playground](https://play.golang.org/p/lJmJvKRE_7H)) and state machine 67([source code](./example_statemachine_test.go), 68[playground](https://play.golang.org/p/ywwugVkCm3m)) example tests are provided. 69They both fail. Making them pass is a good way to get first real experience 70of working with rapid. 71 72## Usage 73 74Just run `go test` as usual, it will pick up also all `rapid` tests. 75 76There are a number of optional flags to influence rapid behavior, run 77`go test -args -h` and look at the flags with the `-rapid.` prefix. You can 78then pass such flags as usual. For example: 79 80``` 81go test -rapid.checks=1000 82``` 83 84## Comparison 85 86Rapid aims to bring to Go the power and convenience Hypothesis brings to Python. 87 88Compared to [gopter](https://godoc.org/github.com/leanovate/gopter), rapid: 89 90- has a much simpler API (queue test in [rapid](./example_statemachine_test.go) vs 91 [gopter](https://github.com/leanovate/gopter/blob/master/commands/example_circularqueue_test.go)) 92- does not require any user code to minimize failing test cases 93- generates biased data to explore "small" values and edge cases more thoroughly (inspired by 94 [SmallCheck](https://hackage.haskell.org/package/smallcheck)) 95- enables interactive tests by allowing data generation and test code to arbitrarily intermix 96 97Compared to [testing/quick](https://golang.org/pkg/testing/quick/), rapid: 98 99- provides much more control over test case generation 100- supports state machine ("stateful" or "model-based") testing 101- automatically minimizes any failing test case 102- has to settle for `rapid.Check` being the main exported function 103 instead of much more stylish `quick.Check` 104 105## Status 106 107Rapid is alpha software. Important pieces of functionality are missing; 108API breakage and bugs should be expected. 109 110If rapid fails to find a bug you believe it should, or the failing test case 111that rapid reports does not look like a minimal one, 112please [open an issue](https://github.com/flyingmutant/rapid/issues). 113 114## License 115 116Rapid is licensed under the [Mozilla Public License version 2.0](./LICENSE). 117 118[godoc-img]: https://godoc.org/pgregory.net/rapid?status.svg 119[godoc]: https://godoc.org/pgregory.net/rapid 120[ci-img]: https://github.com/flyingmutant/rapid/workflows/CI/badge.svg 121