贝利信息

Go测试是什么_Go单元测试基本概念与使用说明

日期:2026-01-13 00:00 / 作者:P粉602998670
Go测试是内置轻量级机制,需同包、_test.go文件、TestXxx签名;表驱动测试用结构体切片统一管理用例,配合t.Run定位失败项;go test常用-v、-run、-coverprofile等参数提升效率。

Go测试是内置在语言工具链里的轻量级验证机制,不是第三方库,也不需要配置文件或启动服务。它靠约定驱动:只要文件名以 _test.go 结尾、函数名以 Test 开头、参数是 *testing.Tgo test 就能自动发现并执行。

怎么写一个能跑起来的单元测试

最简路径就是三件事:同包、_test.go、TestXxx签名。别把测试文件扔到别的目录,也别用小写开头的函数名(比如 testAdd 不会被识别)。

package main

import "testing"

func Add(a, b int) int {
    return a + b
}

func TestAdd(t *testing.T) {
    got := Add(2, 3)
    want := 5
    if got != want {
        t.Errorf("Add(2,3) = %d, want %d", got, want)
    }
}

为什么表驱动测试比一堆 TestXxx 更实用

当你开始写 TestAddWithZeroTestAddWithNegativeTestAddOverflow……就该停手了。重复结构+相似逻辑=维护噩梦。表驱动把用例收进切片,一循环全跑完,加新 case 只改数据不改逻辑。

func TestAddTableDriven(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positive", 2, 3, 5},
        {"zero", 0, 0, 0},
        {"negative", -1, -1, -2},
    }
    for _, tc := range tests {
        tc := tc // 防止闭包陷阱
        t.Run(tc.name, func(t *testing.T) {
            got := Add(tc.a, tc.b)
            if got != tc.expected {
                t.Errorf("got %d, want %d", got, tc.expected)
            }
        })
    }
}

go test 命令常用参数不是摆设,而是日常刚需

go test 默认静默运行,失败才报错。但开发中你几乎每次都要加参数:查哪条失败、看覆盖率、单跑某个 case、确认是否真慢……不用白不用。

真正容易被忽略的点是:测试函数里调用 t.Fatalt.Fatalf 会终止当前测试函数,但不会影响其他测试;而 t.Error 允许继续执行后续断言——这决定了你是想“一条失败全盘放弃”,还是“一次多验几个点”。选哪个,得看被测逻辑是否相互依赖。