2 依赖管理-测试 | 青训营笔记

83 阅读3分钟

2. 依赖管理

2.1 依赖管理

GOPATH -> GO Vender -> Go Module

2.1.1 GOPATH

2023-05-24-23-08-55.png 问题:无法实现package的多版本控制(同一package只能存在一个版本)

2.1.2 GO Vendor

优先从vender目录获取,然后再GOPATH 2023-05-24-23-11-04.png 问题:无法控制依赖的版本,可能出现依赖冲突 2023-05-24-23-14-05.png

2.1.3 Go Module

通过go.mod文件管理依赖包版本;通过go get、go mod指令管理依赖包 可以定义版本规则,管理项目依赖关系 国内Go Module环境配置

# 启用 Go Modules 功能
export GO111MODULE=on
# 配置 GOPROXY 环境变量
export GOPROXY=https://goproxy.io

2.2 依赖管理的要素

2023-05-24-23-21-11.png

2.2.1 依赖配置

go.mod 2023-05-24-23-24-54.png 依赖标识[Path] [Version/Pseudo-Version]

  • //indirect 没有直接依赖

  • 主版本2+的模块增加/vN的后缀(eg.lib5/v3)

    没有go.mod文件且主版本2+的依赖添加+incompatible

  • 语义化版本

    2023-05-24-23-47-52.png

    major:大版本,版本隔离 minor:函数功能,兼容 patch:修复

  • 基于commit的伪版本

    2023-05-24-23-50-02.png 前缀-时间戳-hash码

  • 编译选择最低的兼容版本:

    2023-05-24-23-57-27.png 项目C最终使用v1.4(v1.3与v1.4兼容,1.4是兼容版本,1.3不是.没有1.5,1.4最低),而不会AB分别编译版本

  • 其他

    • replace k8s.io/api => k8s.io/api v0.0.0-20190918155943-95b840bb6a1f 用于将一个模块版本替换成另一个模块版本,前提是当前模块为主模块时

      replace ecm-sdk-go => ./vendor/go-util 也可以用于引入本地的其他模块到当前这个模块中

    • 当前项目中禁止依赖包列表

      exclude (
          github.com/go-git/go-git/v5 v5.1.0
      )
      
2.2.2依赖分发
  • Poxy开源代理工具 环境变量GOPROXY="Proxy1,Proxy1,...,direct":Proxy1->Proxy2->...->direct

  • 工具-go get

    2023-05-25-00-17-39.png

    • go get packageName:安装依赖
    • go get -u packageName:将依赖升级到最新的次要版本或修订版本
    • go get -u=patch packageName:将依赖升级到最新的修订版本
    • go get package@version:升级到指定的版本
  • 工具-go mod

    • go mod tidy:添加丢失的依赖,删除不用的依赖
    • go mod download:下载go.mod中的依赖到本地缓存,目前所有模块版本数据均缓存在GOPATH/pkg/mod和 ​GOPATH/pkg/sum下,也可以指定cache位置
    • go mod graph:显示模块依赖图
    • go mod vendor:复制依赖到vendor目录下
    • go mod verify:根据go.sum文件校验依赖
    • go mod why:解释为什么要依赖
    • go list m -json all:依赖详情
    • go list m -versions github.com/gin-gonic/gin:查看gin所有的历史版本
    • go mod edit -require="github.com/gin-gonic/gin@v1.3.0:更换依赖版本,执行完之后要执行:go mod tidy,也可以直接改go.mod文件
    • go clean -modcache:清理所有已经缓存的模块版本数据

3. 测试

回归测试:人工或自动化执行测试用例,黑盒自动化手工 集成测试:构造一个在设计中所描述的程序结构进行测试,白盒黑盒自动化静态 单元测试:单元模块接口测试,白盒自动化静态

3.1 单元测试

2023-05-25-10-39-47.png

  • 测试文件以_test.go结尾

    2023-05-25-10-43-31.png

  • func Test_nm_(t *testing.T),初始化逻辑Testmain 2023-05-25-10-52-35.png
    2023-05-25-10-52-53.png

  • go test [flags][packages] assert.Equal(t,expectOutput,output)

  • 覆盖率 - 运行的代码占比 2023-05-25-12-39-50.png 2023-05-25-12-42-01.png

3.2 mock

测试依赖本地文件,丢失改动则无法使用 -> mock:稳定、幂等 幂等:多次调用方法或者接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致。 打桩:通过“虚拟”代码替换掉依赖的方法和资源

2023-05-25-23-49-39.png

3.3 基准测试

性能测试 func Benchmark_nm_(b *testing.B)

并发调用-并行测试 func BenchmarkParallel_nm_(b *testing.B)

4. 实战-社区话题页面

4.1 需求

2023-05-26-00-01-23.png

4.2 ER图(实体关系图)

需要的实体:话题Topic 帖子Post

2023-05-26-00-04-01.png

4.3 分层结构

2023-05-26-00-08-04.png

4.4 组件工具

Gin 高性能Go Web框架 Go Mod go mod go get xx/gin

4.5 查询-index

数据索引-map TopicDao-Data Access Objects sync.Once高并发下保证行为只会被执行一次。func (o *Once) Do(f func())只有第一次调用生效

4.6 service

实体:PageInfo{Topic PostList} 参数校验->准备数据->组装实体 Topic与Post没有依赖关系,可以并行

4.7 router

r.GET("/community/page/get/:id", func(c *gin.Context) { //构建路由
    topicId := c.Param("id")
    data := handler.QueryPageInfo(topicId)
    c.JSON(200, data)
})