gotests

作者: jason24L | 来源:发表于2022-05-27 11:57 被阅读0次

    Go单元测试

    go 程序中一般使用官方的go test 做测试,面对一些复杂情况和紧急需求写单元测试就变得有些仓促,今天介绍一款利器gotests来写单元测试

    安装

    go get -u github.com/cweill/gotests/...
    

    以一个不同类型比较相等的列子做个测试,下面是一个simple.go文件

    package simple
    
    import "reflect"
    
    type Point struct {
        X int
        Y int
    }
    
    type Circular struct {
        Point
        Peri float32
    }
    
    
    type PointCollect struct {
        Points []Point
    }
    
    // 数组相等
    func TArrayEqual(a, b [10]int) bool {
        if a == b {
            return true
        }
    
        return false
    }
    
    // 切片相等
    func TSliceEqual(a, b []int) bool {
        if reflect.DeepEqual(a, b) {
            return true
        }
    
        return false
    }
    
    // 字典相等
    func TMapEqual(a, b map[string]string) bool {
        if reflect.DeepEqual(a, b) {
            return true
        }
    
        return false
    }
    
    // 结构体相等
    func TPointEqual(a, b Point) bool {
        if a == b {
            return true
        }
    
        return false
    }
    
    // 结构体相等
    func TCircularEqual(a, b Circular) bool {
        if a == b {
            return true
        }
    
        return false
    }
    
    // 切片结构体相等
    func TPointCollect(a, b PointCollect) bool  {
        if reflect.DeepEqual(a, b) {
            return true
        }
    
        return false
    }
    
    

    执行

    gotests -all -w simple.go
    

    执行这个命令会自动生成simple_test.go文件 -all命令为所有的函数生成测试函数

    func TestTArrayEqual(t *testing.T) {
        type args struct {
            a [10]int
            b [10]int
        }
        tests := []struct {
            name string
            args args
            want bool
        }{
            // TODO: Add test cases.
        }
    
        for _, tt := range tests {
            t.Run(tt.name, func(t *testing.T) {
                if got := TArrayEqual(tt.args.a, tt.args.b); got != tt.want {
                    t.Errorf("TArrayEqual() = %v, want %v", got, tt.want)
                }
            })
        }
    }
    ...
    

    只需要填写对应的test cases 就可以了

    package simple
    
    import "testing"
    
    func TestTArrayEqual(t *testing.T) {
        type args struct {
            a [10]int
            b [10]int
        }
        tests := []struct {
            name string
            args args
            want bool
        }{
            // TODO: Add test cases.
            {
                name: "good case",
                args: args{
                    a: [10]int{1, 2, 3, 4},
                    b: [10]int{1, 2, 3, 4},
                },
                want: true,
            },
            {
                name: "bad case",
                args: args{
                    a: [10]int{1, 2, 3},
                    b: [10]int{1, 2, 3, 4},
                },
                want: false,
            },
        }
    
        for _, tt := range tests {
            t.Run(tt.name, func(t *testing.T) {
                if got := TArrayEqual(tt.args.a, tt.args.b); got != tt.want {
                    t.Errorf("TArrayEqual() = %v, want %v", got, tt.want)
                }
            })
        }
    }
    
    func TestTSliceEqual(t *testing.T) {
        type args struct {
            a []int
            b []int
        }
        tests := []struct {
            name string
            args args
            want bool
        }{
            // TODO: Add test cases.
            {
                name: "good case",
                args: args{
                    a: []int{1, 2, 3},
                    b: []int{1, 2, 3},
                },
                want: true,
            },
            {
                name: "bad case",
                args: args{
                    a: []int{1, 2, 3, 4},
                    b: []int{1, 2, 3},
                },
                want: false,
            },
        }
        for _, tt := range tests {
            t.Run(tt.name, func(t *testing.T) {
                if got := TSliceEqual(tt.args.a, tt.args.b); got != tt.want {
                    t.Errorf("TSliceEqual() = %v, want %v", got, tt.want)
                }
            })
        }
    }
    
    func TestTMapEqual(t *testing.T) {
        type args struct {
            a map[string]string
            b map[string]string
        }
        tests := []struct {
            name string
            args args
            want bool
        }{
            // TODO: Add test cases.
            {
                name: "good case",
                args: args{
                    a: map[string]string{"a":"1", "b":"2", "c":"3"},
                    b: map[string]string{"a":"1", "b":"2", "c":"3"},
                },
                want: true,
            },
            {
                name: "bad case",
                args: args{
                    a: map[string]string{"a":"1", "b":"2", "c":"3"},
                    b: map[string]string{"d":"4", "e":"5", "f":"6"},
                },
                want: false,
            },
        }
    
        for _, tt := range tests {
            t.Run(tt.name, func(t *testing.T) {
                if got := TMapEqual(tt.args.a, tt.args.b); got != tt.want {
                    t.Errorf("TMapEqual() = %v, want %v", got, tt.want)
                }
            })
        }
    }
    
    func TestTPointEqual(t *testing.T) {
        type args struct {
            a Point
            b Point
        }
        tests := []struct {
            name string
            args args
            want bool
        }{
            // TODO: Add test cases.
            {
                name: "good case",
                args: args{
                    a: Point{X: 1, Y: 2},
                    b: Point{X: 1, Y: 2},
                },
                want: true,
            },
            {
                name: "bad case",
                args: args{
                    a: Point{X: 1, Y: 1},
                    b: Point{X: 1, Y: 2},
                },
                want: false,
            },
        }
        for _, tt := range tests {
            t.Run(tt.name, func(t *testing.T) {
                if got := TPointEqual(tt.args.a, tt.args.b); got != tt.want {
                    t.Errorf("TPointEqual() = %v, want %v", got, tt.want)
                }
            })
        }
    }
    
    func TestTCircularEqual(t *testing.T) {
        type args struct {
            a Circular
            b Circular
        }
        tests := []struct {
            name string
            args args
            want bool
        }{
            // TODO: Add test cases.
            {
                name: "good case",
                args: args{
                    a: Circular{
                        Point: Point{X: 1, Y: 1},
                        Peri:  1.5,
                    },
                    b: Circular{
                        Point: Point{X: 1, Y: 1},
                        Peri:  1.5,
                    },
                },
                want: true,
            },
            {
                name: "good case",
                args: args{
                    a: Circular{
                        Point: Point{X: 1, Y: 1},
                        Peri:  1.5,
                    },
                    b: Circular{
                        Point: Point{X: 1, Y: 1},
                        Peri:  2.5,
                    },
                },
                want: false,
            },
        }
    
        for _, tt := range tests {
            t.Run(tt.name, func(t *testing.T) {
                if got := TCircularEqual(tt.args.a, tt.args.b); got != tt.want {
                    t.Errorf("TCircularEqual() = %v, want %v", got, tt.want)
                }
            })
        }
    }
    
    func TestTPointCollect(t *testing.T) {
        type args struct {
            a PointCollect
            b PointCollect
        }
        tests := []struct {
            name string
            args args
            want bool
        }{
            // TODO: Add test cases.
            {
                name: "good case",
                args: args{
                    a: PointCollect{[]Point{{
                            X: 1,
                            Y: 1,
                        }, {
                            X: 1,
                            Y: 2,
                        }}},
                    b: PointCollect{[]Point{{
                        X: 1,
                        Y: 1,
                    }, {
                        X: 1,
                        Y: 2,
                    }}},
                },
                want: true,
            },
            {
                name: "bad case",
                args: args{
                    a: PointCollect{[]Point{{
                        X: 1,
                        Y: 1,
                    }, {
                        X: 1,
                        Y: 2,
                    }}},
                    b: PointCollect{[]Point{{
                        X: 2,
                        Y: 2,
                    }, {
                        X: 2,
                        Y: 4,
                    }}},
                },
                want: false,
            },
        }
        for _, tt := range tests {
            t.Run(tt.name, func(t *testing.T) {
                if got := TPointCollect(tt.args.a, tt.args.b); got != tt.want {
                    t.Errorf("TPointCollect() = %v, want %v", got, tt.want)
                }
            })
        }
    }
    
    

    测试

    go test -v
    
    === RUN   TestTArrayEqual
    === RUN   TestTArrayEqual/good_case
    === RUN   TestTArrayEqual/bad_case
    --- PASS: TestTArrayEqual (0.00s)
        --- PASS: TestTArrayEqual/good_case (0.00s)
        --- PASS: TestTArrayEqual/bad_case (0.00s)
    === RUN   TestTSliceEqual
    === RUN   TestTSliceEqual/good_case
    === RUN   TestTSliceEqual/bad_case
    --- PASS: TestTSliceEqual (0.00s)
        --- PASS: TestTSliceEqual/good_case (0.00s)
        --- PASS: TestTSliceEqual/bad_case (0.00s)
    === RUN   TestTMapEqual
    === RUN   TestTMapEqual/good_case
    === RUN   TestTMapEqual/bad_case
    --- PASS: TestTMapEqual (0.00s)
        --- PASS: TestTMapEqual/good_case (0.00s)
        --- PASS: TestTMapEqual/bad_case (0.00s)
    === RUN   TestTPointEqual
    === RUN   TestTPointEqual/good_case
    === RUN   TestTPointEqual/bad_case
    --- PASS: TestTPointEqual (0.00s)
        --- PASS: TestTPointEqual/good_case (0.00s)
        --- PASS: TestTPointEqual/bad_case (0.00s)
    === RUN   TestTCircularEqual
    === RUN   TestTCircularEqual/good_case
    === RUN   TestTCircularEqual/good_case#01
    --- PASS: TestTCircularEqual (0.00s)
        --- PASS: TestTCircularEqual/good_case (0.00s)
        --- PASS: TestTCircularEqual/good_case#01 (0.00s)
    === RUN   TestTPointCollect
    === RUN   TestTPointCollect/good_case
    === RUN   TestTPointCollect/bad_case
    --- PASS: TestTPointCollect (0.00s)
        --- PASS: TestTPointCollect/good_case (0.00s)
        --- PASS: TestTPointCollect/bad_case (0.00s)
    PASS
    
    

    看到写的测试已经全部通过了

    总结

    写单元测试是很多程序员不喜欢面对了,今天介绍的gotests自动生成测试文件的工具,减少了写测试文件的负担,能够大大提高程序的健壮性和稳定性 。

    相关文章

      网友评论

          本文标题:gotests

          本文链接:https://www.haomeiwen.com/subject/glmmprtx.html