8.1 Go Modules 深入 #
我们之前用go mod init
初始化了项目。现在来看看如何管理依赖。这就像PHP的Composer
。
添加依赖: 你不需要手动编辑
go.mod
文件。只要在你的代码中import
一个第三方包,然后在终端运行go tidy
或go get
,Go工具链会自动下载它并更新go.mod
和go.sum
文件。# 假设你在代码里 import "github.com/google/uuid" go mod tidy # 或者 go get github.com/google/uuid
go.mod
会增加一行require github.com/google/uuid v1.6.0
。go.sum
则记录了依赖包的哈希校验值,保证依赖不被篡改,类似composer.lock
。更新依赖:
go get -u <package>
清理无用依赖:
go mod tidy
8.2 内置测试框架 #
Go内置了强大的测试工具,无需像PHPUnit那样单独安装。测试是Go文化的一等公民。
测试文件必须以_test.go
结尾,并与被测试的代码放在同一个包下。
示例:
假设我们有之前的mymath
包:
// mymath/calculator.go
package mymath
func Add(a, b int) int {
return a + b
}
我们可以为它编写一个测试:
// mymath/calculator_test.go
package mymath
import "testing" // 导入testing包
// 测试函数必须以 Test 开头,并接收一个 *testing.T 类型的参数
func TestAdd(t *testing.T) {
// 定义一组测试用例
testCases := []struct {
name string // 测试用例名
a, b int // 输入
want int // 期望的输出
}{
{"positive numbers", 2, 3, 5},
{"negative numbers", -2, -3, -5},
{"zero", 5, 0, 5},
}
// 遍历所有测试用例
for _, tc := range testCases {
// t.Run可以创建子测试
t.Run(tc.name, func(t *testing.T) {
got := Add(tc.a, tc.b) // 调用被测试的函数
if got != tc.want {
// 如果结果与期望不符,使用t.Errorf报告错误
t.Errorf("Add(%d, %d) = %d; want %d", tc.a, tc.b, got, tc.want)
}
})
}
}
运行测试:
在mymath
目录下,运行:
go test
如果所有测试通过,你会看到ok
。
# 查看更详细的输出
go test -v
# 查看测试覆盖率
go test -cover
# --- PASS: TestAdd (0.00s)
# --- PASS: TestAdd/positive_numbers (0.00s)
# --- PASS: TestAdd/negative_numbers (0.00s)
# --- PASS: TestAdd/zero (0.00s)
# PASS
# coverage: 100.0% of statements
# ok your_module/mymath 0.002s
编写测试是Go工程师的日常,它能极大地保证代码质量和项目未来的可维护性。