仓库源文站点原文


layout: post title: "go test单元测试" categories: Go tags: 单元测试

author: 张乘辉

编写测试程序

$ cd $GOPATH/src
$ mkdir leetcode
$ cd leetcode
$ echo '
package leetcode
func TwoSum(nums []int, target int) []int {
    m := make(map[int]int)
    for i, num := range nums {
        key := target - num
        if j, ok := m[key]; ok {
            return []int{j, i}
        }
        m[nums[i]] = i
    }
    return []int{}
}' > two_sum.go
$ echo '
package leetcode
import "testing"
func TestTwoSum(t *testing.T) {
    t.Log(TwoSum([]int{2, 7, 11, 15}, 9))
}' > two_sum_test.go

文件名格式必须是name_test.go,测试函数名称必须以Test开头,并且传入参数必须是*testing.T,格式如下:

func TestName(t *testing.T) {
    // ...
}

运行测试程序

$ go test two_sum_test.go

这里运行特定测试文件必须与源码文件关联一起,不然会报找不到源码函数的错误:

# command-line-arguments
./two_sum_test.go:6:8: undefined: TwoSum
FAIL    command-line-arguments [build failed]

这是因为运行go test时,go默认将源码文件和测试文件编译成一个临时执行文件,函数只能在这个临时文件中寻找

所以我们需要将源码文件与测试文件关联一起运行:

$ go test two_sum_test.go two_sum.go

得到运行结果:

ok      command-line-arguments  (cached)

如果想看到运行详细结果,可以加上-v参数:

$ go test -v two_sum_test.go two_sum.go

得到运行结果:

=== RUN   TestTwoSum
--- PASS: TestTwoSum (0.00s)
        two_sum_test.go:6: [0 1]
PASS
ok      command-line-arguments  0.006s
$ go test

得到运行结果:

PASS
ok      leetcode        0.005s

运行以上命令,go就默认执行整个项目测试文件,同样,加-v可以得到详细的运行结果:

=== RUN   TestTwoSum
--- PASS: TestTwoSum (0.00s)
        two_sum_test.go:6: [0 1]
PASS
ok      leetcode        0.006s

参数-run对应一个正则表达式,只有测试函数名被它正确匹配的测试函数才会被go test测试命令运行:

$ go test -v -run="TestTwo"

得到运行结果:

=== RUN   TestTwoSum
--- PASS: TestTwoSum (0.00s)
        two_sum_test.go:6: [0 1]
PASS
ok      leetcode        0.006s

其它参数

go test 还可以从主题中分离出来生成独立的测试二进制文件,因为go test命令中包含了编译动作,所以它可以接受可用于go build命令的所有参数。

参数 作用
-c 生成用于运行测试的可执行文件,但不执行它。这个可执行文件会被命名为“pkg.test”,其中的“pkg”即为被测试代码包的导入路径的最后一个元素的名称。
-i 安装/重新安装运行测试所需的依赖包,但不编译和运行测试代码。
-o 指定用于运行测试的可执行文件的名称。追加该标记不会影响测试代码的运行,除非同时追加了标记-c-i
$ go test -c
$ go test -v -o leetcode.test