10

In Go, how would I get the name of the currently executing test, the function name starting with Test, of the current test without passing it in manually?

Kara
  • 5,996
  • 16
  • 49
  • 56
Matt Joiner
  • 106,562
  • 103
  • 351
  • 513
  • 2
    You can find in the following link some approaches to get the function name: http://stackoverflow.com/questions/10742749/get-name-of-function-using-google-gos-reflection – JesusTinoco Feb 21 '16 at 12:24
  • 1
    You should consider changing the accepted answer as it seems there's a new way of doing this. – Francesco Casula May 16 '18 at 06:14

3 Answers3

21

Just use the Name() method:

func TestSomethingReallyCool(t *testing.T) {
    t.Logf("Test name is %s", t.Name())
}

Here's the docs and here's the code.

Francesco Casula
  • 24,611
  • 13
  • 128
  • 130
4

This is an interesting question. When you define a test, you pass around a struct that represents the test itself:

func TestSomething(t *testing.T) {

testing.T is defined as follows:

type T struct {
    common
    name          string    // Name of test.
    startParallel chan bool // Parallel tests will wait on this.
}

So the struct t has the name of the test in a field called name. However, for some reason, the name is not exported and there is no public accessor that will return it. Therefore, you can't access it directly.

There is a workaround. You can use the reflect package to access the unexported name and get the test name from t:

v := reflect.ValueOf(*t)
name := v.FieldByName("name")

// name == "TestSomething"

I'm not sure if this is the best approach, but I was not able to find another reasonable solution to access name from the testing package.

Simone Carletti
  • 168,884
  • 43
  • 353
  • 360
  • Nice one. My method was to inspect the call tree, but your is much less prone to error, and will work from routines not rooted in Test callstack. https://github.com/anacrolix/missinggo/blob/master/testing.go#L12 – Matt Joiner Feb 22 '16 at 03:09
-2

The above answer is great. However, it does require an implementation on your part. In case you just need the name of the method do the following:

Lets say that t is defined as: t *testing.T and you are running from a function called: TestNetworkProbe Then calling:

t.Log("Pass",t)

Will produce (Scroll a little to the right and you shell find...)

Pass &{{{{0 0} 0 0 0 0} [] false false false {63642628359 332863663 0x9bdec0} 0 0xc82008e090 0xc82006a300} TestNetworkProbe false 0xc82006a240}
Sagi Forbes
  • 1,885
  • 2
  • 11
  • 16