Go语言工程实践之测试|青训营笔记
这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
1. 单元测试
测试是避免事故的最后一道屏障
- 回归测试
- 集成测试
- 单元测试
从上到下,覆盖率逐层变大,成本却逐层降低
测试单元:函数,模块......
把输出和期望进行校对,保证代码质量和提升效率
1.1 单元测试-规则
所有测试文件以_test.go结尾
*func TestXxxx(testing.T)
*初始化逻辑放到TestMain(m testing.M) 中
func TestMain(m *testing.M){
//测试前:数据装载、配置初始化等前置工作
code:=m.Run()
//测试后:释放资源等收尾工作
os.Exit(code)
}
1.2 单元测试-例子
func HelloTom() string {
return "Jerry"
}
func TestHelloTom(t *testing.T){
output:=HelloTom()
expectOutput:="Tom"
if output != expectOuput{
t.Error("Expected %s do not not match actual %s",expectOutput,output)
}
}
1.3 单元测试-运行
go test [flags] [packages]
1.4 单元测试-assert
修改上述错误函数继续测试
assert.Equal(t,expectOutput,output)
1.5 单元测试-覆盖率
代码执行的覆盖率,提升单测的覆盖度
一般覆盖率:50%~60%,较高覆盖率80%+。
测试分支相互独立、全面覆盖
测试单元粒度足够小,函数单一职责
1.6 单元测试-依赖
幂等,稳定性
Mock
外部依赖=>稳定&幂等
1.7 单元测试-文件处理
一旦文件篡改,测试在特定场景下不可运行
1.8 单元测试-Mock
开源Mock测试包
monkey: github.com/bouk/monkey
快速Mock函数
- 为一个函数打桩
- 为一个方法打桩
用一个函数A去替换另一个函数B,B是原函数,A是打桩函数
2. 基准测试
- 优化代码,需要对当前代码分析
- 内置的测试框架提供了基准测试的能力
2.1 基准测试-运行
串行和并行压力测试
func BenchmarkSelect(b *testing.B) {
InitServerIndex()
b.ResetTimer()
for i := 0; i < b.N; i++ {
Select()
}
}
func BenchmarkSelectParallel(b *testing.B) {
InitServerIndex()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
Select()
}
})
}
func Select() int {
return ServerIndex[rand.Intn(10)]
}
Select用到了rand函数,rand函数为了保证全局性和并发安全持有全局锁
2.2 基准测试-优化
fastrand() 地址:github.com/bytedance/g…
func FastSelect() int {
return ServerIndex[fastrand.Intn(10)]
}
3. 项目实践
3.1 需求描述
社区话题页面
- 展示话题(标题,文字描述)和回帖列表
- 暂不考虑前端页面实现,仅仅实现一个本地Web服务
- 话题和回帖数据用文件存储
3.2 需求用例
浏览消费用户
Topic
PostList
3.3 ER图
话题-帖子
1对多
Topic
- id
- title
- content
- create_time
Post
- id
- topic_id
- content
- create_time
3.4 分层结构
- 数据层:数据Model,外部数据的增删改查
- 逻辑层:业务Entity,处理核心业务逻辑输出
- 视图层:视图view,处理和外部的交互逻辑
数据层会屏蔽下游的数据差距,Service层不需要关心具体底层的数据存储,Service层主要通过接受Repository的数据做打包封装,输出实体,对应此需求就是话题页面,Controller层包装一些数据格式,
不同项目根据不同情况进行拆分,大致思路如此
3.5 组建工具
Gin 高性能go web框架
Go Mod
go mod init
go get gopkg.in/gin-gonic/gin.v1@v1.3.0
3.6 Repository-index
索引
var (
postDao *PostDao
postOnce sync.Once
)
sync.Once
单例模式减少存储的浪费
3.7 Service
流程
- 参数校验->准备数据->组装实体
3.8 Controller
构建View对象
业务错误码
3.9 Router
- 初始化数据索引
- 初始化引擎配置
- 构建路由
- 启动服务