golang从源代码自动生成测试用例插件库gotests的使用

gotests的使用指南

gotests是一个让编写Go测试变得简单的命令行工具,它能基于目标源文件的函数和方法签名生成表驱动测试。测试文件中的任何新依赖项都会自动导入。

安装

最低Go版本要求: Go 1.6

使用go get命令安装和更新:

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

使用示例

gotests可以从命令行生成特定源文件或整个目录的Go测试。默认情况下,它将输出打印到stdout。

$ gotests [options] PATH ...

常用选项

  -all                  为所有函数和方法生成测试
  
  -excl                 正则表达式。为不匹配的函数和方法生成测试
  
  -exported             为导出的函数和方法生成测试
  
  -i                    在错误消息中打印测试输入
  
  -only                 正则表达式。只为匹配的函数和方法生成测试
  
  -nosubtests           禁用子测试生成(适用于Go >= 1.7)
  
  -parallel             启用并行子测试生成(适用于Go >= 1.7)
  
  -w                    将输出写入测试文件而不是stdout
  
  -template_dir         包含自定义测试代码模板的目录路径
  
  -template             指定自定义测试代码模板,例如testify

完整示例

假设我们有一个简单的Go源文件math.go

package math

// Add 两个整数相加
func Add(a, b int) int {
    return a + b
}

// Subtract 两个整数相减
func Subtract(a, b int) int {
    return a - b
}

我们可以使用gotests为这个文件生成测试:

$ gotests -w -all math.go

这将生成一个math_test.go文件,内容类似于:

package math

import "testing"

func TestAdd(t *testing.T) {
    type args struct {
        a int
        b int
    }
    tests := []struct {
        name string
        args args
        want int
    }{
        // TODO: 添加测试用例
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := Add(tt.args.a, tt.args.b); got != tt.want {
                t.Errorf("Add() = %v, want %v", got, tt.want)
            }
        })
    }
}

func TestSubtract(t *testing.T) {
    type args struct {
        a int
        b int
    }
    tests := []struct {
        name string
        args args
        want int
    }{
        // TODO: 添加测试用例
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := Subtract(tt.args.a, tt.args.b); got != tt.want {
                t.Errorf("Subtract() = %v, want %v", got, tt.want)
            }
        })
    }
}

然后我们可以填充测试用例:

tests := []struct {
    name string
    args args
    want int
}{
    {
        name: "positive numbers",
        args: args{a: 1, b: 2},
        want: 3,
    },
    {
        name: "negative numbers",
        args: args{a: -1, b: -2},
        want: -3,
    },
    {
        name: "zero values",
        args: args{a: 0, b: 0},
        want: 0,
    },
}

自定义模板

gotests支持使用自定义模板生成测试代码。例如,要使用testify风格的断言:

$ gotests -w -all -template=testify math.go

许可证

gotests采用Apache 2.0许可证发布。


更多关于golang从源代码自动生成测试用例插件库gotests的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang从源代码自动生成测试用例插件库gotests的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用gotests自动生成Golang测试用例

gotests是一个强大的工具,可以自动为Go代码生成测试用例框架,大大提高了编写单元测试的效率。下面我将详细介绍gotests的使用方法和最佳实践。

安装gotests

首先需要安装gotests工具:

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

安装完成后,gotests命令就可以在终端使用了。

基本使用方法

为单个文件生成测试

gotests -all -w your_file.go

这会在当前目录下生成一个your_file_test.go文件,包含所有可测试函数的测试框架。

为整个目录生成测试

gotests -all -w ./...

这会递归地为当前目录及其子目录中的所有Go文件生成测试文件。

常用选项

  • -all: 为所有可导出的和不可导出的函数生成测试
  • -w: 将生成的测试写入文件而不是标准输出
  • -only <regexp>: 只生成匹配正则表达式的函数的测试
  • -excl <regexp>: 排除匹配正则表达式的函数的测试
  • -exported: 只为导出的函数生成测试(默认)
  • -template_dir: 指定自定义模板目录

示例

假设我们有一个calculator.go文件:

package calculator

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

func Subtract(a, b int) int {
    return a - b
}

运行gotests -all -w calculator.go会生成calculator_test.go:

package calculator

import "testing"

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

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

自定义模板

gotests支持使用自定义模板来生成测试代码。首先创建一个模板目录,例如test_templates,然后在该目录下创建模板文件。

例如,创建test_templates/function.tmpl:

func Test{{.Name}}(t *testing.T) {
    {{range .Params}}
    {{.Name}} := {{.ExampleValue}}
    {{end}}
    {{if .Returns}}
    want := {{.ExampleValue}}
    got := {{.Name}}({{range $i, $p := .Params}}{{if $i}}, {{end}}{{$p.Name}}{{end}})
    if got != want {
        t.Errorf("{{.Name}}() = %v, want %v", got, want)
    }
    {{else}}
    {{.Name}}({{range $i, $p := .Params}}{{if $i}}, {{end}}{{$p.Name}}{{end}})
    {{end}}
}

然后使用模板生成测试:

gotests -template_dir test_templates -w your_file.go

集成到开发环境

gotests可以很好地集成到各种编辑器和IDE中:

VS Code

  1. 安装Go扩展
  2. 在设置中添加:
"go.generateTestsFlags": ["-all", "-w"]
  1. 右键点击函数名,选择"Go: Generate Unit Tests For Function"

Goland

  1. 右键点击文件或函数
  2. 选择"Generate" > “Test for file"或"Test for function”

最佳实践

  1. 不要完全依赖自动生成:生成的测试只是框架,需要手动添加有意义的测试用例
  2. 结合表格驱动测试:gotests生成的表格驱动测试结构非常适合多种测试场景
  3. 定期更新测试:当代码变更时,记得更新相应的测试
  4. 测试覆盖率:使用go test -cover检查测试覆盖率

高级用法

测试依赖的mock

gotests可以与mock生成工具如mockgen结合使用:

gotests -all -w -template_dir test_templates -mock_names="DB=MockDB" your_file.go

并行测试

可以在生成的测试中添加并行测试支持:

func TestAdd(t *testing.T) {
    t.Parallel()
    // 测试代码...
}

gotests是一个强大的工具,可以显著提高编写Go测试的效率,但记住它只是起点,编写有意义的测试用例仍然需要开发者的思考和设计。

回到顶部