这是我参与「第五届青训营 」伴学笔记创作活动的第1天。 **注:笔记大部分图片内容及代码段为青训营课程
本节主要内容
测试
单元测试 | Mock测试 | 基准测试
本节详细知识点
质量就是“生命”
一些实际开发事故
测试是避免事故的最后一道屏障
回归测试:终端上使用
集成测试:系统功能维度做测试,利用一些接口一些自动化测试
单元测试:测试开发阶段,开发者对单独的函数模块做功能验证 单元测试的覆盖率一定程度上决定着代码的质量
单元测试
单元测试的组成
输入、测试单元、输出、校对
单元测试-规则
方便区分源代码与测试代码。以及其相关
测试函数的命名规范
单元测试提供一个TestMain函数。在包维度生效。
单元测试-例子
单元测试-运行
利用go test [flag][packages]指令运行
单元测试-assert
有很多开源的assert包可以实现比对的功能
单元测试-覆盖率
利用代码覆盖率来评估单元测试!
2/3=66.6%(return false行没有测试到)
单元测试-Tips
实际项目中覆盖率100%很难
一般50-60主流程可覆盖。一些资金相关程序尽量60%+
单元测试-依赖
幂等:重复时结果不变
| 稳定:相互隔离,在任何时间和状况正常运行
需要mock机制实现
单元测试-文件处理例子
一旦测试文件被篡改了怎么办?
单元测试-Mock
monket是一个开源的mock测试包
快速mock函数 ————为一个函数打桩(用一个函数A(打桩函数)替换B(原函数))
————为一个方法打桩
target为原函数、replacement打桩的函数
UNpatch()测试结束后卸载桩
mock的实现主要是在go运行时,将内存中函数的地址替换成打桩函数的地址。
对ReadFirstLine打桩测试,不再依赖本地文件:
基准测试
Go语言还提供了基准测试框架
基准测试指一段程序运行时的性能和cpu的损耗。
其使用方法类似于单元测试
基准测试-例子
服务器负载均衡的例子
随机选取这10个服务器中的一个
接下来我们测试Select()函数
Benchmark-开头类比于单元测试的Test开头
时间重置为了去掉init的损耗
红框内每次执行cpu的耗时。我们发现并行时有劣化。 因为并行时的rand函数持有全局锁
基准测试-优化
为了解决随机函数的性能问题。需要开源的fastrand函数 ps:fastrand舍弃了一部分随机数列的一致性。但大部分场景不受影响。
github.com/bytedance/g… (fastrand地址)
小结
单元测试 | mock测试 | 基准测试
项目实践
需求设计 | 代码开发 | 测试运行
需求描述
需求用例分析
整个页面是面向用户来消费浏览的。
主要涉及到一个功能点:浏览整个话题页面。
设计两个元素,一个是topic一个是postlist。
思考:Topic和PostLine的属性该有哪些,该如何定义其结构体?
####ER图-Entity Relationship Diagram
Post(帖子)应该带有其附属的topic的编号。
Topic对于post应该是一对多的关系。
分层结构
通用常见分层模型
数据层数据Model,外部数据的增删改查
逻辑层业务Entiy,处理核心业务逻辑输出
视图层视图View,处理和外部的交互逻辑
组件工具
go get gopkg.in/gin-gonic/gin.v1@v1.3.0
Repository
如何实现查询操作?
QueryTopicById
QueryPostByParentId
Repository-index
上述两个查询操作如何实现? :因为有文件数据,我们可以通过全扫描遍历的方式。类似于Mysql中的全盘扫描。但这样并不高效。此时
我们需要索引
将数据行映射成我们数据的map,实现内存的索引
init一个Topic Index实例:
初始化话题数据索引
任务:仿照话题索引创建一个回帖索引
实现查询操作
sync.Once在高并发状态只执行一次。单例模式。
Service
service层的函数,主要的目的就是为了pack页面信息
定义一个 页面信息 实体
service层函数实现的逻辑流程
代码流程
checkParam的实现,主要是简单的Id校验 ,实际的开发中严格校验,保护服务端的sever。
prepareInfo的实现。通过repository层的两个查询方法,获取topic以及post的数据。 需要考虑并行来提高执行效率。
controller
利用code、msg表示业务的error状态。如: code为o时成功,非0时异常
代码逻辑:构建view对象->处理业务错误码
端上传来的为string类型,我们要转化为int
Roter
我们的业务逻辑大致完成。接下来通过gin搭建web框架。
流程: 初始化数据索引->初始化引擎配置->构建路由->启动服务
运行(测试)
go run server.go
数据就以json格式化的形式展现出来。
|我们一般与端上进行交互,就是暴露给端上这些http的接口。端上拿到json化的response来渲染整个页面。至此整个服务端的实现逻辑就完成车了。
小结
项目拆解 | 代码设计 | 测试运行
实际项目会更复杂,我们可以学会将大需求拆解成小需求来处理问题。