Go中的testing

192 阅读3分钟

这是我参与8月更文挑战的第30天,活动详情查看:8月更文挑战

package testing

在项目的开发过程中, 所有的源文件或者源代码都应该有必要的注释, 必要的测试. 这是保证代码质量的必须要做好的事情.

tesging是Go中的一个标准库, 可以用来进行单元测试, 性能测试以及自动化测试. 可以进行日志的记录和查看, 方便我们对代码的调试与修改.

在创建测试文件的时候, 必须和我们要测试的源代码在同一个包下, 文件名格式为xxx_test.go

测试文件必须是独立的文件, 和要测试的业务代码分开

以_test.go结尾的文件不会进行部署, 只有要使用go test命令时, 这种文件才会被编译执行

## testing log

Fail方法用标记该测试函数执行失败, 并继续执行下面的测试

FailNow方法标记该测试函数执行失败, 并停止执行下面的测试

Log方法用来格式化输出日志信息

Fatal方法相当于先执行Log方法, 再执行FailNow方法

Error方法相当于先执行Log方法, 再执行Fail方法

单元测试 Test

写好单元测试可以在频繁修改源代码的情况下, 保证修改的正确性, 减少手动调试代码的时间

单元测试函数格式

单元测试的函数要以Test开头, 表明这是一个单元测试函数

func TestFactorial(n, int) int

单元测试源代码

 // 使用循环实现的阶乘函数
 func Factorial1(n int) int {
    res := 1
    for i := 2; i <= n; i++ {
       res *= i
    }
    return res
 }
 ​
 // 使用递归实现的阶乘函数
 func Factorial2(n int) int {
    if n == 1 {
       return 1
    }
    return n * Factorial2(n - 1)
 }

单元测试代码

testing.T是testing包中的一个结构体类型, 用来管理单元测试过程的各种状态, 日志的输出

 // 测试循环实现方式的阶乘函数
 func TestFactorial1(t *testing.T)  {
    e := 2432902008176640000
    r := Factorial1(20)
    if e != r {
       t.Fatalf("expect: %#v, result: %#v", e, r)
    }
 }
 ​
 // 测试递归实现方式的阶乘函数
 func TestFactorial2(t *testing.T)  {
    e := 2432902008176640000
    r := Factorial2(20)
    if e != r {
       t.Fatalf("expect: %#v, result: %#v", e, r)
    }
 }

基准测试 Benchmark

基准测试函数格式

基准测试函数名要以Benchmark为前缀进行命名, 第一参数是*testing.B类型

 func BenchmarkReverse(b *testing.B)

基准测试代码

 func Benchmark1Factorial1(b *testing.B) {
    for i := 0; i < b.N; i++ {
       Factorial1(40)
    }
 }
 ​
 func Benchmark1Factorial2(b *testing.B) {
    for i := 0; i < b.N; i++ {
       Factorial2(40)
    }
 }

基准测试结果

从测试结果来看, 循环方式实现的阶乘比递归实现的阶乘真的是好太多了, 是有量级上的差距的

递归实现阶乘会造成会有大量的内存开辟释放, 因此有很大的耗时

 Benchmark1Factorial1
 Benchmark1Factorial1-4    37982160          35.20 ns/op
 Benchmark1Factorial2
 Benchmark1Factorial2-4     5202404         225.3 ns/op
 PASS