1// Copyright 2017 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package testing 6 7import ( 8 "bytes" 9 "regexp" 10 "strings" 11) 12 13func TestTBHelper(t *T) { 14 var buf bytes.Buffer 15 ctx := newTestContext(1, newMatcher(regexp.MatchString, "", "")) 16 t1 := &T{ 17 common: common{ 18 signal: make(chan bool), 19 w: &buf, 20 }, 21 context: ctx, 22 } 23 t1.Run("Test", testHelper) 24 25 want := `--- FAIL: Test (?s) 26helperfuncs_test.go:12: 0 27helperfuncs_test.go:33: 1 28helperfuncs_test.go:21: 2 29helperfuncs_test.go:35: 3 30helperfuncs_test.go:42: 4 31--- FAIL: Test/sub (?s) 32helperfuncs_test.go:45: 5 33helperfuncs_test.go:21: 6 34helperfuncs_test.go:44: 7 35helperfuncs_test.go:56: 8 36helperfuncs_test.go:64: 9 37helperfuncs_test.go:60: 10 38` 39 lines := strings.Split(buf.String(), "\n") 40 durationRE := regexp.MustCompile(`\(.*\)$`) 41 for i, line := range lines { 42 line = strings.TrimSpace(line) 43 line = durationRE.ReplaceAllString(line, "(?s)") 44 lines[i] = line 45 } 46 got := strings.Join(lines, "\n") 47 if got != want { 48 t.Errorf("got output:\n\n%s\nwant:\n\n%s", got, want) 49 } 50} 51 52func TestTBHelperParallel(t *T) { 53 var buf bytes.Buffer 54 ctx := newTestContext(1, newMatcher(regexp.MatchString, "", "")) 55 t1 := &T{ 56 common: common{ 57 signal: make(chan bool), 58 w: &buf, 59 }, 60 context: ctx, 61 } 62 t1.Run("Test", parallelTestHelper) 63 64 lines := strings.Split(strings.TrimSpace(buf.String()), "\n") 65 if len(lines) != 6 { 66 t.Fatalf("parallelTestHelper gave %d lines of output; want 6", len(lines)) 67 } 68 want := "helperfuncs_test.go:21: parallel" 69 if got := strings.TrimSpace(lines[1]); got != want { 70 t.Errorf("got output line %q; want %q", got, want) 71 } 72} 73 74func TestTBHelperLineNumer(t *T) { 75 var buf bytes.Buffer 76 ctx := newTestContext(1, newMatcher(regexp.MatchString, "", "")) 77 t1 := &T{ 78 common: common{ 79 signal: make(chan bool), 80 w: &buf, 81 }, 82 context: ctx, 83 } 84 t1.Run("Test", func(t *T) { 85 helperA := func(t *T) { 86 t.Helper() 87 t.Run("subtest", func(t *T) { 88 t.Helper() 89 t.Fatal("fatal error message") 90 }) 91 } 92 helperA(t) 93 }) 94 95 want := "helper_test.go:92: fatal error message" 96 got := "" 97 lines := strings.Split(strings.TrimSpace(buf.String()), "\n") 98 if len(lines) > 0 { 99 got = strings.TrimSpace(lines[len(lines)-1]) 100 } 101 if got != want { 102 t.Errorf("got output:\n\n%v\nwant:\n\n%v", got, want) 103 } 104} 105 106type noopWriter int 107 108func (nw *noopWriter) Write(b []byte) (int, error) { return len(b), nil } 109 110func BenchmarkTBHelper(b *B) { 111 w := noopWriter(0) 112 ctx := newTestContext(1, newMatcher(regexp.MatchString, "", "")) 113 t1 := &T{ 114 common: common{ 115 signal: make(chan bool), 116 w: &w, 117 }, 118 context: ctx, 119 } 120 f1 := func() { 121 t1.Helper() 122 } 123 f2 := func() { 124 t1.Helper() 125 } 126 b.ResetTimer() 127 b.ReportAllocs() 128 for i := 0; i < b.N; i++ { 129 if i&1 == 0 { 130 f1() 131 } else { 132 f2() 133 } 134 } 135} 136