Go单元测试

15 阅读2分钟

第十三章 单元测试

我强烈地意识到我余生的很大一部分时间都将用来寻找我程序中的错误。 --《Memoirs of A Computer Pioneer》 --Maurice Wilkes

unit testing:对软件中的最小可测单元进行检查和验证。 单元的含义要根据实际情况去判定具体含义,如C语言中单元指一个函数,Java中指一个类,图形化的软件中可以指一个窗口或一个菜单。。。 作用:一方面在开发过程中验证代码正确性,另一方面是对后续修改代码的保障 可以考虑:

  1. 最小单元,每个单元测试尽量只测一个方法
  2. 可重复执行,单元测试的结果应该是确定的,每次执行单元测试得到的结果一致
  3. case覆盖全面
func Division(dividend, divisor int)(float64, error){
    if divisor == 0 {
        return 0, fmt.Errorf("除数不能为0")
    }
    return float64(dividend / divisor), nil
}

func TestDivision(t *testing.T){
    type args struct{
        dividend int
        divisor int
    }
    tests := []struct{
        name string //case name
        args args //测试需要的参数
        want float64 //期望得到的结果,根据实际目标值定义
        wangtErr bool //是否希望得到Error
    } {
        {name: "2/1",
         args: args{divident: 2, divisor: 1},
         want: 2
         wangtErr: false
        }
    }
    
    //循环测试所有用例
    for _, tt := range tests{
        t.Run(tt.name, func(t *testing.T){
            got, err := Division(tt.args.dividend, tt.args.divisor)
            if (err != nil) != tt.wantErr{
                t.Errorf("error = %v, wantErr %v",err,tt.wantErr)
            }
            if got!=tt.want{
            t.Errorf("%v,%v",got, tt.want)
            }
        })
    }
}

如何做

  1. 控制变量
  2. 外部依赖:网络接口请求、db或redis等组件函数,在单元测试时应保证隔离这些外部依赖,一般mock一个函数进行单元测试,而不去真正尝试连接

外部测试包

考虑包net/url,这个包提供了URL解析功能;还有net/http,这个包提供了Web服务器和Http客户端库。高级的net/http包依赖于低级的net/url包