# 【译】Go 中如何进行单元测试

2017-10-08 10:12:44 发布
 您的评价: 0
1收藏
 文件夹 请选择... ------------- 新增文件夹... 新增文件夹 标签 (多个标签用逗号分隔)

## 编写一个程序测试

``````func Sum(numbers []int) int {
sum := 0
// 这个 bug 是故意的
for n := range numbers {
sum += n
}
return sum
}``````

``````package main

import (
"fmt"

"calhoun.io/testing101"
)

func main() {
testSum([]int{2, 2, 2, 4}, 10)
testSum([]int{-1, -2, -3, -4, 5}, -5)
}

func testSum(numbers []int, expected int) {
sum := testing101.Sum(numbers)
if sum != expected {
message := fmt.Sprintf("Expected the sum of %v to be %d but instead got %d!", numbers, expected, sum)
panic(message)
}
}``````

``for n := range numbers {``

``for _, n := range numbers {``

## 通过 go test 进行测试

``````package testing101

func Sum(numbers []int) int {
sum := 0
// 这个 bug 是故意的
for _, n := range numbers {
sum += n
}
return sum
}``````

``````package testing101

import (
"fmt"
"testing"
)

func TestSum(t *testing.T) {
numbers := []int{1, 2, 3, 4, 5}
expected := 15
actual := Sum(numbers)

if actual != expected {
t.Errorf("Expected the sum of %v to be %d but instead got %d!", numbers, expected, actual)
}
}``````

``go test -v``

=== RUN TestSum

— PASS: TestSum (0.00s)

PASS

ok calhoun.io/testing101 0.005s

=== RUN TestSum

— FAIL: TestSum (0.00s)

sum_test.go:14: Expected the sum of [1 2 3 4 5] to be 18 but instead got 15!

FAIL

exit status 1

FAIL calhoun.io/testing101 0.005s

## 每个函数多个测试用例

``````package testing101

import (
"fmt"
"testing"
)

func TestSum(t *testing.T) {
t.Run("[1,2,3,4,5]", testSumFunc([]int{1, 2, 3, 4, 5}, 15))
t.Run("[1,2,3,4,-5]", testSumFunc([]int{1, 2, 3, 4, -5}, 5))
}

func testSumFunc(numbers []int, expected int) func(*testing.T) {
return func(t *testing.T) {
actual := Sum(numbers)
if actual != expected {
t.Error(fmt.Sprintf("Expected the sum of %v to be %d but instead got %d!", numbers, expected, actual))
}
}
}``````

=== RUN TestSum

=== RUN TestSum/[1,2,3,4,5]

=== RUN TestSum/[1,2,3,4,-5]

— PASS: TestSum (0.00s)

— PASS: TestSum/[1,2,3,4,5] (0.00s)

— PASS: TestSum/[1,2,3,4,-5] (0.00s)

PASS

ok calhoun.io/testing101 0.005s

## 示例作为测试

``````func ExampleSum() {
numbers := []int{5, 5, 5}
fmt.Println(Sum(numbers))
// Output:
// 15
}``````

Go 使用在 ExampleXxx() 函数底部的 “Output 注释” 部分来确定预期的输出是什么，然后在运行测试时，它将实际输出与注释中的预期输出进行比较，如果不匹配，将触发失败的测试。这样，我们可以同时编写测试和示例代码。

## 更复杂的例子

``````flag.Parse()
os.Exit(m.Run())``````

``````package testing101

import (
"flag"
"fmt"
"os"
"testing"
)

var db struct {
Url string
}

func TestMain(m *testing.M) {
// Pretend to open our DB connection
db.Url = os.Getenv("DATABASE_URL")
if db.Url == "" {
db.Url = "localhost:5432"
}

flag.Parse()
exitCode := m.Run()

// Pretend to close our DB connection
db.Url = ""

// Exit
os.Exit(exitCode)
}

func TestDatabase(t *testing.T) {
// Pretend to use the db
fmt.Println(db.Url)
}``````

## 总结

https://semaphoreci.com/community/tutorials/how-to-test-in-go

## 扩展阅读

Effective Scala 中文版

## 为您推荐

Go语言极速入门手册.go
Go 语言简介（上）— 语法
Java8 lambda表达式10个示例
Effective Go 中文版