从项目学习 Golang (4) - 使用第三方包, test 测试

抓取 OKEx 的盘口价格 (1)

使用第三方包

早在前面已经搞过包管理的问题, 使用 dep, glide 抑或 v1.11+ 原生提供的 mod 方式.

dep 的标记是 Gopkg.tomlGopkg.lock, glide 的标记是 glide.yamlglide.lock, 原生 mod 的标记是 go.modgo.sum.

一般情况, 原来使用 dep 和 glide 的都开始逐步向 mod 转. 因为原生支持的进步, 第三方逐渐开始失去优势.

  • dep 的方式, 是在当前 $GOPATH/pkg/dep 文件夹下缓存依赖文件.
  • glide 的方式是在当前项目文件夹下, 以 vender 目录存储依赖文件.
  • 原生 mod 的方式, 是在当前 $GOPATH/pkg/mod 文件夹下缓存依赖文件.

之后的使用, 我们也逐步开始直接使用原生 mod 做依赖管理.

关于包管理的, 我们参考原来的内容: Golang 的包管理工具

使用 mod 管理依赖

使用 mod 管理的一个好处就是, 通过执行 go mod tidy 会动态的发现当前的依赖缺失, 剔除依赖冗余, 完成依赖的下载和 go.mod 文件的配置.

我们现在要依赖的一个包是 GoEx. 通过该包已经实现的很多交易所的接入, 我们期望可以更简单方便的达成我们接入交易所的目的.

通过文档, 把 GoEx 库 import 进来, 接入代码, 运行 tidy 即完成了配置.

但是在进行依赖的使用过程中, 我们发现, 在全球不同区域进行 api 接入的时候, 要使用的 api 地址是不同的, 而原生包却没有对这方面进行考虑, 这要求我们 fork 代码进行二次开发修改.

Fork 第三方代码, 修改, 测试, 提交

根据要求, 对第三方代码很快就完成了修改替换的任务, 但是对第三方代码的提交需要经过 test 测试才可以.

测试用例的编写

  • 文件名 _test.go 结尾
  • 引入 import "testing"
单元测试
  • 测试函数 func TestXxx(t *testing.T) 从上到下顺序执行, Xxx 必须首字母大写.
  • 参数 t *testing.T 可以用来记录日志, 测试状态
  • 记录日志 Log, 其他类型日志 Error, Errorf, FailNow, Fatal, FatalIf 表示测试失败.
压力测试
  • 测试函数 func BenchmarkXXX(b *testing.B), XXX 必须全大写.
  • 压力测试函数中的循环次数, 一般使用 testing.B.N (b.N) 值作为循环上限, 才能使压力测试正常工作.

测试用例的执行

  • test 测试, 使用 go test 即可运行.
  • bench 测试, 需要使用 go test -test.bench=".*" , 以正则表达式指定 bench 测试的方法.

其他配合开关

  • -bench regexp 运行 regexp 执行相应的 benchmarks
  • -cover 开启测试覆盖率
  • -run regexp 只运行 regexp 匹配的函数 test
  • -v 显示测试的详细命令

简单测试用例说明

源代码 math.go

1
2
3
4
5
package gotest

func Add(a, b float64) float64 {
return a + b
}

单元测试 math_unit_test.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package gotest

import "testing"

func Test_Add_1(t *testing.T) {
if i := Add(6,2); i != 8 {
t.Error("fail")
} else {
t.Log("pass")
}
}

func Test_Add_2(t *testing.T) {
if i := Add(6,2); i == 8 {
t.Log("pass")
} else {
t.Error("fail")
}
}

压力测试 math_bench_test.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package gotest

import(
"testing"
)

func Benchmark_Add(b *testing.B) {
// 这里的循环次数使用的是 `b.N`
for i := 0; i < b.N ; i++ {
Add(3,4)
}
}

func Benchmark_TimeConsumingFunction(b *testing.B) {
// 调用该函数停止压力测试的时间计数
b.StopTimer()

// 做一些初始化工作,这些时间不影响我们测试函数本身的性能

b.StartTimer()

// 这里的循环次数使用的是 `b.N`
for i := 0; i < b.N; i++ {
Add(5,6)
}
}

参考文档:

Donate - Support to make this site better.
捐助 - 支持我让我做得更好.