扩展现有的类型测试。T以添加额外的检查

I realize I could pass the testing.T type to the functions that need to deal with the testing interfaces. But how about extending the struct and using it? I know I can type extend but this doesn't work unfortunately:

package test

import "testing"

type testingT testing.T

func (t *testingT) assert(val int) {
    if val == 0 {
        t.Errorf("%d is zero", val)
    }
}

func TestSomething(t *testingT) {
    t.assert(0)
}

One solution is embedding as you can see in eduncan911's answer. It's great if you want to add other fields to the new struct.

However, this is not a requirement. Creating a new type having testing.T as its underlying type (just as you did) is just enough:

type myT testing.T

func (t *myT) assert(val int) {
    if val == 0 {
        t.Errorf("%d is zero", val)
    }
}

Using it

In TestSomething() we can't just call t.assert(0) because assert() is not a method of testing.T but our myT type. So we need a value of type myT on which we can call myT.assert().

We can't use type assertion to convert a testing.T to our myT type though, because type assertion requires the expression to be of interface type! And t is not an interface type, it's a concrete type: *testing.T.

The solution is really simple, we can use simple type conversion because myT and testing.T has the same underlying type:

my := myT(*t)   // Conversion valid, but not yet enough, read on...

The above works, and we can call:

my.assert(0)

But when running tests, it won't fail! Why is that? It's because the above *t dereferencing, conversion and assignment will make a copy, and my will be of type myT but will be a copy of *t, and so when we call myT.assert(), it gets a pointer, but a pointer to the copy. And when myT.assert() calls t.Errorf(), it will register the error on a copy, so the testing framework will not see this Errorf() call.

The "final" solution is simple: use type conversion, but don't convert *t, but t itself (which is a pointer). Of course *t cannot be converted to myT, only to *myT. And this type needs to be parenthesized (to avoid ambiguity):

func TestSomething(t *testing.T) {
    my := (*myT)(t)
    my.assert(0)
}

And now we're happy, everything works as expected.

Note: You can also call myT.assert() in one line if you don't want to call multiple methods of myT:

func TestSomething(t *testing.T) {
    (*myT)(t).assert(0)
}

You can use embedding which would allow you to add your owner methods:

package test

import "testing"

type testingT struct {
    *testing.T
}

func (t *testingT) assert(val int) {
    if val == 0 {
        t.Errorf("%d is zero", val)
    }
}

func TestSomething(t *testing.T) {
    t2 := &testingT{t}
    t2.assert(0)
}