> For the complete documentation index, see [llms.txt](https://ryanyang.gitbook.io/the-way-to-go-zh-cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ryanyang.gitbook.io/the-way-to-go-zh-cn/di-san-bu-fen-go-gao-ji-bian-cheng/13.0/13.8.md).

# 测试的具体例子

在练习 9.4 中你写了一个叫 [main\_oddeven.go](https://github.com/yangchuansheng/the-way-to-go_ZH_CN/tree/f30ab7d8c58f85840a0afb548024b93642b518d5/eBook/exercises/chapter_9/main_oddeven.go) 的程序用来测试前 100 个整数是否是偶数。这个函数属于 even 包。

下面是一种可能的方案：

示例 13.7 [even\_main.go](https://github.com/yangchuansheng/the-way-to-go_ZH_CN/tree/f30ab7d8c58f85840a0afb548024b93642b518d5/eBook/examples/chapter_13/even/even_main/even_main.go)：

```go
package main

import (
    "fmt"
    "even/even"
)

func main() {
    for i:=0; i<=100; i++ {
        fmt.Printf("Is the integer %d even? %v\n", i, even.Even(i))
    }
}
```

上面使用了 even.go 中的 even 包：

示例 13.8 [even/even.go](https://github.com/yangchuansheng/the-way-to-go_ZH_CN/tree/f30ab7d8c58f85840a0afb548024b93642b518d5/eBook/examples/chapter_13/even/even/even.go)：

```go
package even

func Even(i int) bool {        // Exported function
    return i%2 == 0
}

func Odd(i int) bool {        // Exported function
    return i%2 != 0
}
```

在 even 包的路径下，我们创建一个名为 oddeven\_test.go 的测试程序：

示例 13.9 [even/oddeven\_test.go](https://github.com/yangchuansheng/the-way-to-go_ZH_CN/tree/f30ab7d8c58f85840a0afb548024b93642b518d5/eBook/examples/chapter_13/even/even/oddeven_test.go)：

```go
package even

import "testing"

func TestEven(t *testing.T) {
    if !Even(10) {
        t.Log(" 10 must be even!")
        t.Fail()
    }
    if Even(7) {
        t.Log(" 7 is not even!")
        t.Fail()
    }

}

func TestOdd(t *testing.T) {
    if !Odd(11) {
        t.Log(" 11 must be odd!")
        t.Fail()
    }
    if Odd(10) {
        t.Log(" 10 is not odd!")
        t.Fail()
    }
}
```

由于测试需要具体的输入用例且不可能测试到所有的用例（非常像一个无穷的数），所以我们必须对要使用的测试用例思考再三。

至少应该包括：

* 正常的用例
* 反面的用例（错误的输入，如用负数或字母代替数字，没有输入等）
* 边界检查用例（如果参数的取值范围是 0 到 1000，检查 0 和 1000 的情况）

可以直接执行 go install 安装 even 或者创建一个 以下内容的 Makefile：

```bash
include $(GOROOT)/src/Make.inc
TARG=even
GOFILES=\
       even.go\
include $(GOROOT)/src/Make.pkg
```

然后执行 make（或 gomake）命令来构建归档文件 even.a

测试代码不能在 GOFILES 参数中引用，因为我们不希望生成的程序中有测试代码。如果包含了测试代码，go test 会给出错误提示！go test 会生成一个单独的包含测试代码的 `_test` 程序。

现在我们可以用命令：`go test`（或 `make test`）来测试 even 包。

因为示例 13.5 中的测试函数不会调用 t.Log 和 t.Fail，所以会得到一个 PASS 的结果。在这个简单例子中一切都正常执行。

为了看到失败时的输出，把函数 TestEven 改为：

```go
func TestEven(t *testing.T) {
    if Even(10) {
        t.Log("Everything OK: 10 is even, just a test to see failed output!")
        t.Fail()
     }
}
```

现在会调用 t.Log 和 t.Fail，得到的结果如下：

```go
--- FAIL: even.TestEven (0.00 seconds)
Everything OK: 10 is even, just a test to see failed output!
FAIL
```

**练习 13.4：**[string\_reverse\_test.go](https://github.com/yangchuansheng/the-way-to-go_ZH_CN/tree/f30ab7d8c58f85840a0afb548024b93642b518d5/eBook/exercises/chapter_13/string_reverse_test.go)

为练习 7.11 [string\_reverse.go](https://github.com/yangchuansheng/the-way-to-go_ZH_CN/tree/f30ab7d8c58f85840a0afb548024b93642b518d5/eBook/exercises/chapter_7/string_reverse.go) 写一个单元测试。

把 string\_reverse 放到自己的包 strev 中，只包含一个可导出函数 reverse。

实现并测试它。

## 链接

* [目录](https://github.com/yangchuansheng/the-way-to-go_ZH_CN/tree/f30ab7d8c58f85840a0afb548024b93642b518d5/eBook/directory.md)
* 上一节：[Go 中的单元测试和基准测试](/the-way-to-go-zh-cn/di-san-bu-fen-go-gao-ji-bian-cheng/13.0/13.7.md)
* 下一节：[用（测试数据）表驱动测试](/the-way-to-go-zh-cn/di-san-bu-fen-go-gao-ji-bian-cheng/13.0/13.9.md)
