matrix

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 29, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

README

Matrix

A small matrix test generator implementation for go.

Why

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.

What

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 can range over.

Example

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.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Generate

func Generate[T any](t testingT, tcase T, dimensions ...any) iter.Seq[T]

Generate generates all possible combinations of values for fields of the type T. It returns an iter.Seq[T] that can be for-ranged over. - len(dims) must equal len(fields(T)) - dimensions[i].(type) must equal [](fields(T)[i].(type)) - T must only have exported fields.

func GenerateAndCollect added in v0.1.0

func GenerateAndCollect[T any](t testingT, tcase T, dimensions ...any) []T

GenerateAndCollect generates all possible combinations of values for fields of the type T. It returns a collected slice of generated test cases. Use this function if you need all test cases at once, use a for-range loop on Generate otherwise. - len(dims) must equal len(fields(T)) - dimensions[i].(type) must equal [](fields(T)[i].(type)) - T must only have exported fields.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL