添加一个测试

本文翻译自《Add a test》。

现在你已经将代码放到了一个稳定的位置(顺便说一句,做得很好),接下来添加一个测试。在开发期间测试你的代码,可以发现更改代码造成的Bug。在本文中,你将为Hello函数添加一个测试。

注意:本主题是从《创建一个Go模块》开始的多部分教程的一部分。

Go对单元测试的内置支持使你可以轻松地进行测试。具体来说,使用命名约定、Go的testinggo test命令,你可以快速编写和进行测试。

1 在greetings目录中,创建一个名为greetings_test.go的文件。

以_test.go结尾的文件名告诉go test命令该文件包含测试函数。

2 在greetings_test.go中,粘贴以下代码并保存文件。

package greetings

import (
    "testing"
    "regexp"
)

// TestHelloName函数使用一个名字name调用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.Fatalf(`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.Fatalf(`Hello("") = %q, %v, want "", error`, msg, err)
    }
}

在此代码中,你:

  • 在与被测代码相同的包中实现测试函数。
  • 创建两个测试函数来测试greetings.Hello函数。测试函数的名字的形式为TestName,其中Name表示有关特定测试的信息。此外,测试函数将指针指向testing包的testing.T类型作为参数。你可以使用此类型的方法在测试中进行报告和记录各种信息。
  • 实现两个测试函数:

TestHelloName函数调用Hello函数,传递一个name值,应该能够返回有效的响应消息。如果返回一个错误或一个意外消息(不包含你传入的name值),你可以使用t参数的Fatalf方法将消息打印到控制台并结束执行。

TestHelloEmpty函数使用空字符串调用Hello函数。此测试旨在确认你的错误处理是否有效。如果返回非空字符串或没有错误,则使用t参数的Fatalf方法将消息打印到控制台并结束执行。

3 在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

4 破坏greetings.Hello函数以查看失败的测试结果。

测试TestHelloName函数检查你传递name参数给Hello函的返回值。要查看失败的测试结果,请更改greetings.Hello函数,使返回值中不再包含name参数的值。

在greetings/greetings.go中,粘贴以下代码代替Hello函数。请注意,突出显示的行更改该函数返回的值,就好像name参数被意外删除一样。

// Hello函数返回对指定名字的人员的一句问候语。
func Hello(name string) (string, error) {
    // 如果name参数的值为空字符串,返回一个错误信息。
    if name == "" {
        return name, errors.New("empty name")
    }
    // 使用一个随机格式创建一个消息。
    // message := fmt.Sprintf(randomFormat(), name)
    message := fmt.Sprint(randomFormat())
    return message, nil
}

5 在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

在下一个(也是最后一个)主题中,你将了解如何编译和安装代码以在本地运行它。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注