Source file src/testing/helperfuncs_test.go

     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  
     5  package testing_test
     6  
     7  import (
     8  	"sync"
     9  	"testing"
    10  )
    11  
    12  // The line numbering of this file is important for TestTBHelper.
    13  
    14  func notHelper(t *testing.T, msg string) {
    15  	t.Error(msg)
    16  }
    17  
    18  func helper(t *testing.T, msg string) {
    19  	t.Helper()
    20  	t.Error(msg)
    21  }
    22  
    23  func notHelperCallingHelper(t *testing.T, msg string) {
    24  	helper(t, msg)
    25  }
    26  
    27  func helperCallingHelper(t *testing.T, msg string) {
    28  	t.Helper()
    29  	helper(t, msg)
    30  }
    31  
    32  func genericHelper[G any](t *testing.T, msg string) {
    33  	t.Helper()
    34  	t.Error(msg)
    35  }
    36  
    37  var genericIntHelper = genericHelper[int]
    38  
    39  func testTestHelper(t *testing.T) {
    40  	testHelper(t)
    41  }
    42  
    43  func testHelper(t *testing.T) {
    44  	// Check combinations of directly and indirectly
    45  	// calling helper functions.
    46  	notHelper(t, "0")
    47  	helper(t, "1")
    48  	notHelperCallingHelper(t, "2")
    49  	helperCallingHelper(t, "3")
    50  
    51  	// Check a function literal closing over t that uses Helper.
    52  	fn := func(msg string) {
    53  		t.Helper()
    54  		t.Error(msg)
    55  	}
    56  	fn("4")
    57  
    58  	t.Run("sub", func(t *testing.T) {
    59  		helper(t, "5")
    60  		notHelperCallingHelper(t, "6")
    61  		// Check that calling Helper from inside a subtest entry function
    62  		// works as if it were in an ordinary function call.
    63  		t.Helper()
    64  		t.Error("7")
    65  	})
    66  
    67  	// Check that right caller is reported for func passed to Cleanup when
    68  	// multiple cleanup functions have been registered.
    69  	t.Cleanup(func() {
    70  		t.Helper()
    71  		t.Error("10")
    72  	})
    73  	t.Cleanup(func() {
    74  		t.Helper()
    75  		t.Error("9")
    76  	})
    77  
    78  	// Check that helper-ness propagates up through subtests
    79  	// to helpers above. See https://golang.org/issue/44887.
    80  	helperSubCallingHelper(t, "11")
    81  
    82  	// Check that helper-ness propagates up through panic/recover.
    83  	// See https://golang.org/issue/31154.
    84  	recoverHelper(t, "12")
    85  
    86  	genericHelper[float64](t, "GenericFloat64")
    87  	genericIntHelper(t, "GenericInt")
    88  }
    89  
    90  func parallelTestHelper(t *testing.T) {
    91  	var wg sync.WaitGroup
    92  	for i := 0; i < 5; i++ {
    93  		wg.Add(1)
    94  		go func() {
    95  			notHelperCallingHelper(t, "parallel")
    96  			wg.Done()
    97  		}()
    98  	}
    99  	wg.Wait()
   100  }
   101  
   102  func helperSubCallingHelper(t *testing.T, msg string) {
   103  	t.Helper()
   104  	t.Run("sub2", func(t *testing.T) {
   105  		t.Helper()
   106  		t.Fatal(msg)
   107  	})
   108  }
   109  
   110  func recoverHelper(t *testing.T, msg string) {
   111  	t.Helper()
   112  	defer func() {
   113  		t.Helper()
   114  		if err := recover(); err != nil {
   115  			t.Errorf("recover %s", err)
   116  		}
   117  	}()
   118  	doPanic(t, msg)
   119  }
   120  
   121  func doPanic(t *testing.T, msg string) {
   122  	t.Helper()
   123  	panic(msg)
   124  }
   125  

View as plain text