A small matrix test generator implementation for go.
The general approach to writing parametric tests in go is often a table-driven test, that spells out all variations (the cartesian product) of the table and looks somewhat like this:
func TestExample(t *testing.T) {
type tcase struct {
X, Y bool
}
for _, tcase := range []tcase{
{false, false},
{false, true},
{true, false},
{true, true},
} {
t.Run(fmt.Sprintf("%t_%t", tcase.X, tcase.Y), func(t *testing.T) {
// Imaginary test code.
})
}
}
This can become very tedious, especially when more dimensions get added to the test matrix.
In this package I propose a solution that works like this:
- Define a struct with one field per test dimension. (Just like the example above).
- Call
matrix.Generate
passing your struct type and slices of values per dimension. matrix.Generate
returns an iterator that you canrange
over.
It's easier to explain through code, so here we go:
package example
import (
"fmt"
"testing"
"github.com/erdii/matrix"
)
func TestExample(t *testing.T) {
t.Parallel()
// Imagine that you want to test all possible combinations
// of Priyanka, Pedro and Paul
// eating Pizza, Spaghetti, Bananas and Sushi:
type tcase struct {
Who string
Food string
}
for tcase := range matrix.Generate(t, tcase{},
[]string{"Priyanka", "Pedro", "Paul"},
[]string{"Pizza", "Spaghetti", "Bananas", "Sushi"}) {
t.Run(fmt.Sprintf("%s_%s", tcase.Who, tcase.Food), func(t *testing.T) {
// Imaginary test code.
})
}
}
Running the example test with go test -v ./example
will print:
=== RUN TestExample
=== PAUSE TestExample
=== CONT TestExample
=== RUN TestExample/Priyanka_Pizza
=== RUN TestExample/Pedro_Pizza
=== RUN TestExample/Paul_Pizza
=== RUN TestExample/Priyanka_Spaghetti
=== RUN TestExample/Pedro_Spaghetti
=== RUN TestExample/Paul_Spaghetti
=== RUN TestExample/Priyanka_Bananas
=== RUN TestExample/Pedro_Bananas
=== RUN TestExample/Paul_Bananas
=== RUN TestExample/Priyanka_Sushi
=== RUN TestExample/Pedro_Sushi
=== RUN TestExample/Paul_Sushi
--- PASS: TestExample (0.00s)
--- PASS: TestExample/Priyanka_Pizza (0.00s)
--- PASS: TestExample/Pedro_Pizza (0.00s)
--- PASS: TestExample/Paul_Pizza (0.00s)
--- PASS: TestExample/Priyanka_Spaghetti (0.00s)
--- PASS: TestExample/Pedro_Spaghetti (0.00s)
--- PASS: TestExample/Paul_Spaghetti (0.00s)
--- PASS: TestExample/Priyanka_Bananas (0.00s)
--- PASS: TestExample/Pedro_Bananas (0.00s)
--- PASS: TestExample/Paul_Bananas (0.00s)
--- PASS: TestExample/Priyanka_Sushi (0.00s)
--- PASS: TestExample/Pedro_Sushi (0.00s)
--- PASS: TestExample/Paul_Sushi (0.00s)
PASS
ok github.com/erdii/matrix/example 0.001s
Coincidentally this package is designed in a similar way to rust's test_matrix.