现在您的代码已经达到了一个稳定的状态(顺便说一句,做得不错),
是时候添加一个测试了。在开发过程中测试代码,可以发现在修改过程中引入的错误。
在本主题中,您将为 Hello 函数添加一个测试。
Go 内置的单元测试支持使得边开发边测试变得更加容易。
具体来说,通过使用命名约定、Go 的 testing 包以及
go test 命令,您可以快速编写和执行测试。
-
在 greetings 目录下,创建一个名为 greetings_test.go 的文件。
文件名以 _test.go 结尾会告诉
go test命令 该文件包含测试函数。 -
在 greetings_test.go 中,粘贴以下代码并保存文件。
package greetings import ( "testing" "regexp" ) // TestHelloName 调用 greetings.Hello 并传入一个名字,检查 // 返回值是否有效。 func TestHelloName(t *testing.T) { name := "Gladys" want := regexp.MustCompile(`\b`+name+`\b`) msg, err := Hello("Gladys") if !want.MatchString(msg) || err != nil { t.Errorf(`Hello("Gladys") = %q, %v, want match for %#q, nil`, msg, err, want) } } // TestHelloEmpty 用一个空字符串调用 greetings.Hello, // 检查是否返回错误。 func TestHelloEmpty(t *testing.T) { msg, err := Hello("") if msg != "" || err == nil { t.Errorf(`Hello("") = %q, %v, want "", error`, msg, err) } }在这段代码中,您:
- 在与被测代码相同的 package 中实现测试函数。
-
创建了两个测试函数来测试
greetings.Hello函数。测试函数名遵循TestName形式, 其中 Name 描述了特定测试的内容。此外,测试函数 以一个指向testing包的testing.T类型 的 pointer 作为参数。您将使用此参数的方法来从您的测试中 进行报告和日志记录。 - 实现了两个测试:
-
在 greetings 目录的命令行中,运行
go test命令 来执行测试。go test命令会执行测试文件(文件名以 _test.go 结尾) 中的测试函数(函数名以Test开头)。您可以添加-v标志来获取详细输出,该输出会列出所有测试及其结果。测试应该通过。
$ go test PASS ok example.com/greetings 0.364s $ go test -v === RUN TestHelloName --- PASS: TestHelloName (0.00s) === RUN TestHelloEmpty --- PASS: TestHelloEmpty (0.00s) PASS ok example.com/greetings 0.372s
-
破坏
greetings.Hello函数以查看失败的测试。TestHelloName测试函数会检查您作为Hello函数参数指定的名称的返回值。为了查看失败的测试结果,请修改greetings.Hello函数,使其不再包含该名称。在 greetings/greetings.go 文件中,用以下代码替换
Hello函数。请注意,高亮的行更改了函数返回的值, 就好像name参数被意外移除了一样。// Hello 为指定的人返回一个问候。 func Hello(name string) (string, error) { // 如果没有提供名字,则返回带有消息的错误。 if name == "" { return name, errors.New("empty name") } // 使用随机格式创建消息。 // message := fmt.Sprintf(randomFormat(), name) message := fmt.Sprint(randomFormat()) return message, nil } -
在 greetings 目录的命令行中,运行
go test来执行测试。这次,不带
```-v标志运行go test。 输出将只包含失败测试的结果,这在您有大量测试时会很有用。TestHelloName测试应该会失败——TestHelloEmpty仍然会通过。$ go test --- FAIL: TestHelloName (0.00s) greetings_test.go:15: Hello("Gladys") = "Hail, %v! Well met!", <nil>, want match for `\bGladys\b`, nil FAIL exit status 1 FAIL example.com/greetings 0.182s
在下一个(也是最后一个)主题中,您将了解如何编译和安装代码以在本地运行。