这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记
1. 依赖管理
1.1 依赖管理方式
1. GOPATH
$GOPATH用来放置项目依赖包的源代码,不区分项目,其中有以下内容:
bin,项目编译的二进制文件。pkg,项目编译的中间产物,加速编译。src,项目源码,go get下载最新版本的包到src目录下。
由于不区分项目,无法实现package的多版本控制。
-
Go Vendor
项目目录下增加 vendor 文件夹,所有依赖包副本形式放在$ProjectRoot/vendor
依赖寻址方式:先从vendor找,再从GOPATH找
通过每个项目引入一份依赖的副本,解决了多个项目需要同一个package依赖的冲突问题。
问题:不能清晰标识依赖的版本。
3. Go Module
通过go.mod文件管理依赖包版本。
通过go get/go mod指令工具管理依赖包。
可以定义版本规则和管理项目依赖关系。
1.2 依赖管理三要素
- 配置文件,描述依赖
go.mod - 中心仓库管理依赖库
Proxy - 本地工具
go get/mod
1.3 依赖配置
1. go.mod配置
module example/project/app //依赖管理单元
go 1.16 // 原生库
require{ // path+version
example/lib1 v1.0.2
example/lib2 v1.0.0 // indirect
}
2. version
// 语义化版本
// 基于 commit 的伪版本
3. indirect
关键字indirect
直接依赖、间接依赖
4. incompatible
+incompatible
5. 依赖分发
回源、Proxy
可以通过使用版本标签来发布v1.0.0版本。
git tag v1.0.0
git push --tags
6. GOPROXY
GOPROXY="https://proxy1.cn, https://proxy2.cn, direct"
7. go get
go get example.org/pkg
选项 @...
8. go mod
go mod init初始化,创建go.mod文件go mod download下载模块到本地缓存`go mod tidy增加需要的依赖,删除不需要的依赖
2. 测试
回归测试、集成测试、单元测试
2.1 单元测试
1. 规则
- 测试文件
xxx_test.go - 测试函数
func TestXxx(*testing.T) - 初始化逻辑
TestMain(m *testing.M)
2. 例子
func TestHelloTom(t *testing.T) {
output := HelloTom()
expectOutput := "Tom"
assert.Equal(t, expectOutput, output)
}
go test
3. 覆盖率
go test judgement_test.go judgement.go --cover 最后会给出覆盖率的结果
4. Tips
一般覆盖率 50%~60%,较高覆盖率 80%。
测试分支相互独立、全面覆盖。
测试单元粒度足够小,函数单一职责。
2.2 单元测试-Mock
单元测试,要求 幂等+稳定。但是如果单元测试依赖 File/DB/Cache,结果是不稳定的。
可以通过monkey包对函数进行Mock,
Patch()、Unpatch
func TestProcessFirstLineWithMock(t *testing.T) {
monkey.Patch(ReadFirstLine, func() string {
return "line110"
}) // 将一个函数替换为另一个函数
defer monkey.Unpatch(ReadFirstLine)
line := ProcessFirstLine()
assert.Equal(t, "line000", line)
}
2.3 基准测试
BenchmarkXxx(*testing.B)
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 BenchmarkFastSelectParallel(b *testing.B) {
InitServerIndex()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
FastSelect()
}
})
}
3. 项目实战
3.1 需求设计
1. 需求描述
展示话题(标题、文字描述)和回帖列表。
暂不考虑前端页面实现,仅仅实现一个本地Web服务。
话题和回帖数据用文件存储。
2. 用例分析
浏览消费用户,浏览话题页面:1、标题;2、回帖列表
3. E-R图
实体-关系图,Topic、Post,一对多
4. 分层结构
- 数据层:Repository 数据 Model,外部数据的增删改查,File
- 逻辑层:Service 业务 Entity,处理核心业务的逻辑输出
- 视图层:Controller 视图view,处理和外部的交互逻辑,Client
5. 组件工具
Gin 高性能 go web 框架
https://github.com/gin-gonic/gin#installation
Go Mod
go mod init
go get gopkg.in/gin-gonic/gin.v1@v1.3.0