go-testdeep
Extremely flexible golang deep comparison, extends the go testing package.
- Latest news
- Synopsis
- Description
- Installation
- Functions
- Available operators
- Helpers
- See also
- License
- FAQ
Latest news
- 2020/12/17: v1.8.0 release;
- 2020/07/19: v1.7.0 release;
- 2020/05/31: v1.6.0 release;
- 2020/05/17: v1.5.0 release;
- see commits history for other/older changes.
Synopsis
Make golang tests easy, from simplest usage:
import (
"testing"
"github.com/maxatome/go-testdeep/td"
)
func TestMyFunc(t *testing.T) {
td.Cmp(t, MyFunc(), &Info{Name: "Alice", Age: 42})
}
To a bit more complex one, allowing flexible comparisons using TestDeep operators:
import (
"testing"
"github.com/maxatome/go-testdeep/td"
)
func TestMyFunc(t *testing.T) {
td.Cmp(t, MyFunc(), td.Struct(
&Info{Name: "Alice"},
td.StructFields{
"Age": td.Between(40, 45),
},
))
}
Or anchoring operators directly in literals, as in:
import (
"testing"
"github.com/maxatome/go-testdeep/td"
)
func TestMyFunc(tt *testing.T) {
t := td.NewT(tt)
t.Cmp(MyFunc(), &Info{
Name: "Alice",
Age: t.Anchor(td.Between(40, 45)).(int),
})
}
To most complex one, allowing to easily test HTTP API routes, using flexible operators:
import (
"testing"
"time"
"github.com/maxatome/go-testdeep/helpers/tdhttp"
"github.com/maxatome/go-testdeep/td"
)
type Person struct {
ID uint64 `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
CreatedAt time.Time `json:"created_at"`
}
func TestMyApi(t *testing.T) {
var id uint64
var createdAt time.Time
testAPI := tdhttp.NewTestAPI(t, myAPI) // ← ①
testAPI.PostJSON("/person", Person{Name: "Bob", Age: 42}). // ← ②
Name("Create a new Person").
CmpStatus(http.StatusCreated). // ← ③
CmpJSONBody(td.JSON(`
// Note that comments are allowed
{
"id": $id, // set by the API/DB
"name": "Bob",
"age": 42,
"created_at": "$createdAt", // set by the API/DB
}`,
td.Tag("id", td.Catch(&id, td.NotZero())), // ← ④
td.Tag("created_at", td.All( // ← ⑤
td.HasSuffix("Z"), // ← ⑥
td.Smuggle(func(s string) (time.Time, error) { // ← ⑦
return time.Parse(time.RFC3339Nano, s)
}, td.Catch(&createdAt, td.Between(testAPI.SentAt(), time.Now()))), // ← ⑧
)),
))
if !testAPI.Failed() {
t.Logf("The new Person ID is %d and was created at %s", id, createdAt)
}
}
- the API handler ready to be tested;
- the POST request with automatic JSON marshalling;
- the expected response HTTP status should be
http.StatusCreated
and the line just below, the body should match theJSON
operator; - for the
$id
placeholder,Catch
its value: put it inid
variable and check it isNotZero
; - for the
$createdAt
placeholder, use theAll
operator. It combines several operators like a AND; - check that
$createdAt
date ends with "Z" usingHasSuffix
. As we expect a RFC3339 date, we require it in UTC time zone; - convert
$createdAt
date into atime.Time
using a custom function thanks to theSmuggle
operator; - then
Catch
the resulting value: put it increatedAt
variable and check it is greater or equal thantestAPI.SentAt()
(the time just before the request is handled) and lesser or equal thantime.Now()
.
See tdhttp
helper or the FAQ for details about HTTP API testing.
Example of produced error in case of mismatch:
Description
go-testdeep is a go rewrite and adaptation of wonderful Test::Deep perl.
In golang, comparing data structure is usually done using reflect.DeepEqual or using a package that uses this function behind the scene.
This function works very well, but it is not flexible. Both compared structures must match exactly and when a difference is returned, it is up to the caller to display it. Not easy when comparing big data structures.
The purpose of go-testdeep, via the td
package and its helpers, is to do its best to introduce this missing flexibility using "operators", when the expected value (or one of its component) cannot be matched exactly, mixed with some useful comparison functions.
See go-testdeep.zetta.rocks for details.
Installation
$ go get -u github.com/maxatome/go-testdeep
Helpers
The goal of helpers is to make use of go-testdeep
even more powerful by providing common features using TestDeep operators behind the scene.
tdhttp
or HTTP API testing helper
The package github.com/maxatome/go-testdeep/helpers/tdhttp
provides some functions to easily test HTTP handlers.
See tdhttp
documentation for details or FAQ for an example of use.
tdutil
aka the helper of helpers
The package github.com/maxatome/go-testdeep/helpers/tdutil
allows to write unit tests for go-testdeep helpers and so provides some helpful functions.
See tdutil
for details.
See also
- testify: a toolkit with common assertions and mocks that plays nicely with the standard library
- go-cmp: package for comparing Go values in tests
License
go-testdeep
is released under the BSD-style license found in the LICENSE
file in the root directory of this source tree.
Internal function deepValueEqual
is based on deepValueEqual
from reflect
golang package licensed under the BSD-style license found in the LICENSE
file in the golang repository.
Uses two files (bypass.go
& bypasssafe.go
) from Go-spew which is licensed under the copyfree ISC License.
Public Domain Gopher provided by Egon Elbre. The Go gopher was designed by Renee French.
FAQ
See FAQ.