为什么你写的代码总是有 Bug?用它来保证 Go 代码质量( 五 )


清单 12// TestAdd tests the Add function.func TestAdd(t *testing.T) {    tt := []struct {        Name     string        Operands []int        Sum      int    }{        {            Name:     "NoOperands",            Operands: []int{},            Sum:      0,        },        {            Name:     "OneOperand",            Operands: []int{10},            Sum:      10,        },        {            Name:     "TwoOperands",            Operands: []int{10, 5},            Sum:      15,        },        {            Name:     "ThreeOperands",            Operands: []int{10, 5, 4},            Sum:      19,        },    }    for _, test := range tt {        fn := func(t *testing.T) {            if e, a := test.Sum, Add(test.Operands...); e != a {                t.Errorf("expected sum %d, got sum %d", e, a)            }        }        t.Run(test.Name, fn)    }}测试清单 12 中,使用匿名声明的结构体定义了不同的情况 。遍历这些情况,执行这些测试用例 。比较实际返回值和预期值,如果不等,则调用 t.Errorf,返回测试失败的信息 。清单中,遍历调用 t.Run 执行每个测试用例 。
t.Helper() 和 t.Parallel()标准库中的 testing 包提供了很多有用的程序(函数)辅助测试,而不用导入之外的第三方包 。其中我最喜欢的两个函数是 t.Helper() 和 t.Parallel(),它们都定义为 testing.T 接收者,它是在 _test.go 文件中每个 Test 函数都必需的一个的参数 。
清单 13// GenerateTempFile generates a temp file and returns the reference to// the underlying os.File and an error.func GenerateTempFile() (*os.File, error) {    f, err := ioutil.TempFile("", "")    if err != nil {        return nil, err    }    return f, nil}在代码清单 13 中,为特定的测试包定义了一个辅助函数 。这个函数返回 os.File 指针和error 。每次测试调用这个辅助函数必须判断 error 是一个 non-nil。通常情况这也没什么,但是有一个更好的方式:使用 t.Helper(),这种方式省略了 error 返回 。
清单 14// GenerateTempFile generates a temp file and returns the reference to// the underlying os.File.func GenerateTempFile(t *testing.T) *os.File {    t.Helper()    f, err := ioutil.TempFile("", "")    if err != nil {        t.Fatalf("unable to generate temp file: %v", err)    }    return f}


推荐阅读