gotest.tools/gotestsum@v1.11.0/internal/aggregate/slowest_test.go (about)

     1  package aggregate
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/google/go-cmp/cmp"
    11  	"github.com/google/go-cmp/cmp/cmpopts"
    12  	"gotest.tools/gotestsum/testjson"
    13  	"gotest.tools/v3/assert"
    14  )
    15  
    16  func TestSlowest(t *testing.T) {
    17  	newEvent := func(pkg, test string, elapsed float64) testjson.TestEvent {
    18  		return testjson.TestEvent{
    19  			Package: pkg,
    20  			Test:    test,
    21  			Action:  testjson.ActionPass,
    22  			Elapsed: elapsed,
    23  		}
    24  	}
    25  
    26  	exec := newExecutionFromEvents(t,
    27  		newEvent("one", "TestOmega", 22.2),
    28  		newEvent("one", "TestOmega", 1.5),
    29  		newEvent("one", "TestOmega", 0.6),
    30  		newEvent("one", "TestOnion", 0.5),
    31  		newEvent("two", "TestTents", 2.5),
    32  		newEvent("two", "TestTin", 0.3),
    33  		newEvent("two", "TestTunnel", 1.1))
    34  
    35  	cmpCasesShallow := cmp.Comparer(func(x, y testjson.TestCase) bool {
    36  		return x.Package == y.Package && x.Test == y.Test
    37  	})
    38  
    39  	type testCase struct {
    40  		name      string
    41  		threshold time.Duration
    42  		num       int
    43  		expected  []testjson.TestCase
    44  	}
    45  
    46  	run := func(t *testing.T, tc testCase) {
    47  		actual := Slowest(exec, tc.threshold, tc.num)
    48  		assert.DeepEqual(t, actual, tc.expected, cmpCasesShallow)
    49  	}
    50  
    51  	testCases := []testCase{
    52  		{
    53  			name:      "threshold only",
    54  			threshold: time.Second,
    55  			expected: []testjson.TestCase{
    56  				{Package: "two", Test: "TestTents"},
    57  				{Package: "one", Test: "TestOmega"},
    58  				{Package: "two", Test: "TestTunnel"},
    59  			},
    60  		},
    61  		{
    62  			name:      "threshold only 2s",
    63  			threshold: 2 * time.Second,
    64  			expected: []testjson.TestCase{
    65  				{Package: "two", Test: "TestTents"},
    66  			},
    67  		},
    68  		{
    69  			name:      "threshold and num",
    70  			threshold: 400 * time.Millisecond,
    71  			num:       2,
    72  			expected: []testjson.TestCase{
    73  				{Package: "two", Test: "TestTents"},
    74  				{Package: "one", Test: "TestOmega"},
    75  			},
    76  		},
    77  		{
    78  			name: "num only",
    79  			num:  4,
    80  			expected: []testjson.TestCase{
    81  				{Package: "two", Test: "TestTents"},
    82  				{Package: "one", Test: "TestOmega"},
    83  				{Package: "two", Test: "TestTunnel"},
    84  				{Package: "one", Test: "TestOnion"},
    85  			},
    86  		},
    87  	}
    88  
    89  	for _, tc := range testCases {
    90  		t.Run(tc.name, func(t *testing.T) {
    91  			run(t, tc)
    92  		})
    93  	}
    94  }
    95  
    96  func newExecutionFromEvents(t *testing.T, events ...testjson.TestEvent) *testjson.Execution {
    97  	t.Helper()
    98  
    99  	buf := new(bytes.Buffer)
   100  	encoder := json.NewEncoder(buf)
   101  	for i, event := range events {
   102  		assert.NilError(t, encoder.Encode(event), "event %d", i)
   103  	}
   104  
   105  	exec, err := testjson.ScanTestOutput(testjson.ScanConfig{
   106  		Stdout: buf,
   107  		Stderr: strings.NewReader(""),
   108  	})
   109  	assert.NilError(t, err)
   110  	return exec
   111  }
   112  
   113  func TestByElapsed_WithMedian(t *testing.T) {
   114  	cases := []testjson.TestCase{
   115  		{Test: "TestOne", Package: "pkg", Elapsed: time.Second},
   116  		{Test: "TestTwo", Package: "pkg", Elapsed: 2 * time.Second},
   117  		{Test: "TestOne", Package: "pkg", Elapsed: 3 * time.Second},
   118  		{Test: "TestTwo", Package: "pkg", Elapsed: 4 * time.Second},
   119  		{Test: "TestOne", Package: "pkg", Elapsed: 5 * time.Second},
   120  		{Test: "TestTwo", Package: "pkg", Elapsed: 6 * time.Second},
   121  	}
   122  	actual := ByElapsed(cases, median)
   123  	expected := []testjson.TestCase{
   124  		{Test: "TestOne", Package: "pkg", Elapsed: 3 * time.Second},
   125  		{Test: "TestTwo", Package: "pkg", Elapsed: 4 * time.Second},
   126  	}
   127  	assert.DeepEqual(t, actual, expected,
   128  		cmpopts.SortSlices(func(x, y testjson.TestCase) bool {
   129  			return strings.Compare(x.Test.Name(), y.Test.Name()) == -1
   130  		}),
   131  		cmpopts.IgnoreUnexported(testjson.TestCase{}))
   132  }
   133  
   134  func TestMedian(t *testing.T) {
   135  	var testcases = []struct {
   136  		name     string
   137  		times    []time.Duration
   138  		expected time.Duration
   139  	}{
   140  		{
   141  			name:     "one item slice",
   142  			times:    []time.Duration{time.Minute},
   143  			expected: time.Minute,
   144  		},
   145  		{
   146  			name:     "odd number of items",
   147  			times:    []time.Duration{time.Millisecond, time.Hour, time.Second},
   148  			expected: time.Second,
   149  		},
   150  		{
   151  			name:     "even number of items",
   152  			times:    []time.Duration{time.Second, time.Millisecond, time.Microsecond, time.Hour},
   153  			expected: time.Second,
   154  		},
   155  	}
   156  
   157  	for _, tc := range testcases {
   158  		t.Run(tc.name, func(t *testing.T) {
   159  			actual := median(tc.times)
   160  			assert.Equal(t, actual, tc.expected)
   161  		})
   162  	}
   163  }