# 测试的具体例子

在练习 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)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ryanyang.gitbook.io/the-way-to-go-zh-cn/di-san-bu-fen-go-gao-ji-bian-cheng/13.0/13.8.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
