测试是避免事故的最后一道屏障;
测试
测试大致分为三种类型:
- 回归测试:使用软件
- 集成测试:对功能的测试
- 单元测试:测试开发阶段,对单独的函数、模块做验证
从上1到3,覆盖率逐层增大,成本逐层降低;
单元测试:
单元测试---规则:
- 所有的测试文件以_test.go结尾
- 函数名:
func TestXxx(*testing.T) - 初始化逻辑放到
TestMain中
代码覆盖率:
在 Go 语言中,代码覆盖率是衡量测试质量的一个重要指标,它表示测试用例覆盖了多少代码逻辑。
- go test 命令配合 - cover 参数:这是 Go 语言自带的一种简单方便的获取代码覆盖率的方式。- 它会输出一个覆盖率的百分比,同时还会输出一些详细的覆盖信息,如哪些文件被覆盖,哪些函数没有被完全覆盖等。 例如:
$ go test -cover PASS coverage: 80.0% of statements
2. 使用更高级的工具 - gocov 和 gocov-xml 等
gocov是一个第三方工具,它可以提供更详细的代码覆盖率信息。它可以生成多种格式的覆盖率报告,如文本格式、JSON 格式等。- 例如,使用
gocov和gocov -xml可以将覆盖率信息以 XML 格式输出,这种格式对于与其他工具集成(如 CI/CD 系统)非常有用。安装gocov后,可以通过gocov命令和相关参数来获取和处理覆盖率数据。
Tips
- 一般覆盖率:50%~60%,较高覆盖率80%+;
- 测试分支相互独立、全面覆盖;
- 测试单元粒度足够小,函数单一职责;
单元测试---依赖
在 Go 语言单元测试中,依赖是指被测试单元(函数、方法、结构体等)所依赖的外部因素,包括其他函数、全局变量、外部服务(如数据库、网络服务)等。
外部依赖=>稳定&幂等
Mock
在 Go 语言单元测试中,Mock(模拟对象)是一种用于替代真实依赖的测试替身。它的主要作用是模拟被测试单元(如函数、方法)所依赖的外部组件的行为,使得测试能够独立于这些外部组件进行。这样可以更好地控制测试环境,聚焦于被测试单元本身的逻辑验证。
快速Mock函数:
- 为一个函数打桩
- 为一个方法打桩
创建 Mock 对象的方法:
1.手工创建简单 Mock 对象: 可以通过定义一个结构体来实现简单的 Mock 对象,该结构体实现了与真实依赖相同的接口。
- 例如,假设有一个接口
DataFetcher,定义如下:
type DataFetcher interface {
FetchData() ([]string, error)
}
- 我们可以创建一个手工 Mock 对象来模拟这个接口的行为。
type MockDataFetcher struct {
mockData []string
mockErr error
} func (mdf *MockDataFetcher) FetchData() ([]string, error) {
return mdf.mockData, mdf.mockErr
}
2.使用第三方 Mock 框架(如 testify/mock)