添加测试
现在你的代码已经进入一个稳定的状态(顺便说一句,做得很好),接下来添加一个测试。在开发过程中测试你的代码可以暴露在你修改代码时可能引入的错误。在本主题中,你将为 Hello
函数添加一个测试。
Go 对单元测试的内置支持让你在开发过程中更容易进行测试。具体来说,通过使用命名约定、Go 的 testing
包和 go test
命令,你可以快速编写和执行测试。
- 在 greetings 目录下,创建一个名为 greetings_test.go 的文件。
文件名的结尾使用 _test.go 会告诉
go test
命令该文件包含测试函数。 - 在 greetings_test.go 中,粘贴以下代码并保存文件。
package greetings import ( "testing" "regexp" ) // TestHelloName calls greetings.Hello with a name, checking // for a valid return value. 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 calls greetings.Hello with an empty string, // checking for an error. func TestHelloEmpty(t *testing.T) { msg, err := Hello("") if msg != "" || err == nil { t.Errorf(`Hello("") = %q, %v, want "", error`, msg, err) } }
在此代码中,你
- 在与你正在测试的代码相同的包中实现测试函数。
- 创建两个测试函数来测试
greetings.Hello
函数。测试函数名采用TestName
的形式,其中 Name 说明了特定测试的目的。此外,测试函数接受指向testing
包的testing.T
类型的指针作为参数。你使用此参数的方法来报告和记录测试结果。 - 实现两个测试
- 在 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 returns a greeting for the named person. func Hello(name string) (string, error) { // If no name was given, return an error with a message. if name == "" { return name, errors.New("empty name") } // Create a message using a random format. // 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
在下一个(也是最后一个)主题中,你将了解如何编译和安装你的代码以便在本地运行。