Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flag -testify.shuffle for suites #1413

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions suite/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package suite
import (
"flag"
"fmt"
"math/rand"
"os"
"reflect"
"regexp"
"runtime/debug"
"strconv"
"sync"
"testing"
"time"
Expand All @@ -17,6 +19,7 @@ import (

var allTestsFilter = func(_, _ string) (bool, error) { return true, nil }
var matchMethod = flag.String("testify.m", "", "regular expression to select tests of the testify suite to run")
var shuffle = flag.String("testify.shuffle", "off", "randomize the execution order of tests in testify suites, like -test.shuffle")

// Suite is a basic testing suite with methods for storing and
// retrieving the current *testing.T context.
Expand Down Expand Up @@ -199,6 +202,26 @@ func Run(t *testing.T, suite TestingSuite) {
}
tests = append(tests, test)
}

// implementation is similar to the implementation of -test.shuffle in package testing
// https://cs.opensource.google/go/go/+/refs/tags/go1.20.5:src/testing/testing.go;l=1876-1893
if *shuffle != "off" {
dolmen marked this conversation as resolved.
Show resolved Hide resolved
var n int64
var err error
if *shuffle == "on" {
n = time.Now().UnixNano()
} else {
n, err = strconv.ParseInt(*shuffle, 10, 64)
if err != nil {
t.Fatal(`testing: -testify.shuffle should be "off", "on", or a valid integer:`, err)
return
}
}
t.Log("-testify.shuffle", n)
rng := rand.New(rand.NewSource(n))
rng.Shuffle(len(tests), func(i, j int) { tests[i], tests[j] = tests[j], tests[i] })
}
dolmen marked this conversation as resolved.
Show resolved Hide resolved

if suiteSetupDone {
defer func() {
if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
Expand Down
46 changes: 46 additions & 0 deletions suite/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -617,3 +617,49 @@ func (s *FailfastSuite) Test_B_Passes() {
s.call("Test B Passes")
s.Require().True(true)
}

type ShuffleOrderSuite struct {
Suite
callOrder []string
}

func (s *ShuffleOrderSuite) call(method string) {
s.callOrder = append(s.callOrder, method)
}

func TestSuiteShuffleOrder(t *testing.T) {
Run(t, new(ShuffleOrderSuite))
}

// TestShuffleOrderSuiteShuffleOn relies on the algorithm used by package math/rand.
// If that algorithm changes the seed value may have to be adapted.
func TestShuffleOrderSuiteShuffleOn(t *testing.T) {
// To test this with testify.shuffle on we launch it in its own process
cmd := exec.Command("go", "test", "-v", "-run", "TestSuiteShuffleOrder", "-testify.shuffle", "2")
var out bytes.Buffer
cmd.Stdout = &out
t.Logf("Running %s", strings.Join(cmd.Args, " "))
err := cmd.Run()
t.Log(out.String())
if err != nil {
t.Log(err)
t.Fail()
}
}

func (s *ShuffleOrderSuite) TearDownSuite() {
shuffle := flag.Lookup("testify.shuffle").Value.(flag.Getter).Get().(string)
if shuffle == "off" {
assert.Equal(s.T(), "Test A;Test B", strings.Join(s.callOrder, ";"))
} else {
assert.Equal(s.T(), "Test B;Test A", strings.Join(s.callOrder, ";"))
}
}

func (s *ShuffleOrderSuite) Test_A() {
s.call("Test A")
}

func (s *ShuffleOrderSuite) Test_B() {
s.call("Test B")
}