你有没有遇到过改了一行代码,结果整个程序崩了的情况?有时候一个小功能上线,没测全,线上报警一堆。这种情况在团队协作中尤其常见。为了解决这个问题,写单元测试就成了开发中绕不开的一环。在 Go 语言里,写单元测试不仅简单,而且几乎不用额外引入框架。
\n\nGo 的测试机制长什么样
\nGo 自带 testing 包,只要按照约定写测试文件,就能直接运行。测试文件通常和源码放在同一个目录下,名字是原文件名加上 _test.go 后缀。比如你有一个 calculator.go 文件,那测试文件就叫 calculator_test.go。
一个简单的加法测试例子
\n假设我们写了一个做加法的函数:
\npackage main\n\nfunc Add(a, b int) int {\n return a + b\n}\n\n\n接下来,在同一目录下创建 calculator_test.go 文件:
package main\n\nimport (\n "testing"\n)\n\nfunc TestAdd(t *testing.T) {\n result := Add(2, 3)\n expected := 5\n if result != expected {\n t.Errorf("期望 %d,但得到了 %d", expected, result)\n }\n}\n\n\n保存后,在终端执行:
\ngo test\n\n\n如果输出显示 OK,说明测试通过。你可以试试把期望值改成 6,再跑一次,就会看到错误提示。
表驱动测试让用例更清晰
\n实际项目中,一个函数往往要测多种输入情况。一个个写 t.Run() 太麻烦。Go 社区常用“表驱动测试”(table-driven test)来组织多个用例。
还是拿 Add 函数举例,现在我们想测几组不同的输入:
func TestAddTable(t *testing.T) {\n tests := []struct {\n name string\n a, b int\n expected int\n }{\n {"正数相加", 2, 3, 5},\n {"负数相加", -2, -3, -5},\n {"一正一负", 5, -3, 2},\n {"其中一个为零", 0, 7, 7},\n }\n\n for _, tt := range tests {\n t.Run(tt.name, func(t *testing.T) {\n result := Add(tt.a, tt.b)\n if result != tt.expected {\n t.Errorf("期望 %d,但得到了 %d", tt.expected, result)\n }\n })\n }\n}\n\n\n这样写的好处是,新增用例只需要往切片里加一行,结构清晰,维护方便。而且每个子测试都有独立名字,出错时能快速定位是哪个场景没通过。
\n\n测试覆盖率不是越高越好,但要看关键路径
\n很多人追求 100% 测试覆盖率,其实没必要。像一些简单的 getter/setter 或明显不会出错的逻辑,可以适当放过。真正该覆盖的是核心业务逻辑、边界条件和错误处理。
\n\n比如一个除法函数,除了正常计算,更要测“除以零”的情况:
\nfunc Divide(a, b float64) (float64, error) {\n if b == 0 {\n return 0, fmt.Errorf("不能除以零")\n }\n return a / b, nil\n}\n\n\n对应的测试可以这样写:
\nfunc TestDivide(t *testing.T) {\n t.Run("正常除法", func(t *testing.T) {\n result, err := Divide(10, 2)\n if err != nil {\n t.Fatal("不应该出错")\n }\n if result != 5 {\n t.Errorf("期望 5,得到 %.1f", result)\n }\n })\n\n t.Run("除以零", func(t *testing.T) {\n _, err := Divide(10, 0)\n if err == nil {\n t.Fatal("应该返回错误")\n }\n if err.Error() != "不能除以零" {\n t.Errorf("错误信息不符:%s", err)\n }\n })\n}\n\n\n这类测试虽然看起来琐碎,但在项目迭代中特别有用。别人改代码时,一旦不小心破坏了原有逻辑,测试会立刻报错。
\n\n日常开发中的小建议
\n写单元测试不一定要等到功能做完才开始。TDD(测试驱动开发)提倡先写测试,再实现功能。哪怕你不完全照做,也可以养成“写完函数顺手补个测试”的习惯。
\n\n比如你在写一个用户注册逻辑,刚写完邮箱格式校验函数,马上写几个测试用例:空字符串、普通邮箱、非法格式(如 missing@dot)。等以后重构时,这些测试就是你的安全网。
\n\nGo 的测试机制足够轻量,不需要复杂的配置。每天花十分钟写几个测试,可能就避免了半夜被线上问题叫醒。”,"seo_title":"Go语言单元测试实例详解 - 常识小站网络技术栏目","seo_description":"通过实际代码示例讲解Go语言单元测试的写法,包括基础测试、表驱动测试和错误处理,帮助开发者写出更可靠的程序。","keywords":"Go语言,单元测试,Go测试实例,Go test,表驱动测试,Golang测试"}