这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
1.测试
测试可大致分为三类:回归测试,集成测试,单元测试
从前到后,覆盖层逐层变大,成本逐层降低。
1.1 回归测试
1.2 集成测试
1.3 单元测试
单元测试流程
优点:保证质量,提升效率
单元测试规则:
- 一般覆盖率:50%-60%,较高覆盖率80%+
- 测试分支相互独立、全面覆盖
- 测试单元粒度足够小,函数单一职责
单元测试-依赖
单元测试-文件处理
一个Mock的前置例子
func ReadFirstLine() string {
open, err := os.Open("log") // 打开一个文件
defer open.Close()
if err != nil {
return ""
}
scanner := bufio.NewScanner(open) // 对每行进行遍历
for scanner.Scan() {
return scanner.Text()
}
return ""
}
func ProcessFirstLine() string {
line := ReadFirstLine()
destLine := strings.ReplaceAll(line, "11", "00") // 替换11为00
return destLine
}
func TestProcessFirstLine(t *testing.T) { // 执行单元测试
firstLine := ProcessFirstLine()
assert.Equal(t, "line00", firstLine)
}
一旦测试文件被修改了,需要使用mock了。
单元测试-Mock
快速Mock函数:
- 为一个函数打桩
- 为一个方法打桩
// 用函数A去替换函数B,B就是原函数,A就是打桩函数
func Patch(target, replacement interface{}) *PatchGuard {
// target就是原函数,replacement就是打桩函数
t := reflect.ValueOf(target)
r := reflect.ValueOf(replacement)
patchValue(t, r)
return &PatchGuard{t, r}
}
func Unpatch(target interface{}) bool {
// 保证了在测试结束之后需要把这个包卸载掉
return unpatchValue(reflect.ValueOf(target))
}
func TestProcessFirstLineWithMock(t *testing.T) {
monkey.Patch(ReadFirstLine, func() string {
return "line110"
})
defer monkey.Unpatch(ReadFirstLine)
line := ProcessFirstLine()
assert.Equal(t, "line000", line)
}
// 通过patch对ReadFirstLine进行打桩mock,默认返回line110,通过defer卸载mock
// 这样整个测试函数就摆脱了本地文件的束缚和依赖
2.项目实战
需求:社区话题页面
- 实现一个展示话题(标题,文字描述)和回帖列表的后端http接口;
- 本地文件存储数据(暂不考虑前端页面实现,仅实现一个本地web服务)
- 话题和回帖数据用文件存储
组件及技术点
- web框架:Gin - github.com/gin-gonic/g… 了解go web框架的简单使用
- 分层结构设计:github.com/bxcodec/go-… 了解分层设计的概念
- 文件操作:读文件pkg.go.dev/io
- 数据查询:索引www.baike.com/wikiid/5527…