在 Go 赛道上测试

学习如何在 Exercism 上测试你的 Go 练习


在你的 exercism 项目目录中,切换到练习目录并运行go test,即可运行 Go 练习。

cd exercism/project/directory/go/leap
go test

使用数据竞争检测器运行测试

除了运行go test,有些练习还应该带上数据竞争检测器的标志来运行,以检查你提交的解答是否引入了数据竞争 bug。 在相关练习中,你会看到一条提醒,让你使用数据竞争检测器的标志-race来运行测试。 运行go test -race可以检查数据竞争。 例如:

cd exercism/project/directory/go/bank-account
go test -race

运行基准测试

大多数练习都包含基准测试,你可以用它来判断对提交的解答所做的改动会如何影响性能。 要运行某个练习的基准测试,请在练习目录中使用命令go test -v --bench . --benchmem。

看看下面这段输出。

BenchmarkReverse-16       403594              2537 ns/op             176 B/op         34 allocs/op

这表示该基准测试运行了 403594 次迭代,才得到可靠的计时结果。 平均速度是每个循环 2537 ns。 每次操作发生 34 次内存分配,平均每次 176 字节。

可测试的示例

有些练习会使用示例测试,它们与标准的练习测试一起运行。 这些示例用于记录和验证练习的 API,也有助于判断预期的练习 API 应该是什么。

Go fmt

提交代码之前,请先对你的代码运行go fmt。

提示与技巧

编写练习代码

每个练习的 README.md 会给出总体说明,但 Go 测试程序会非常具体。 打开测试程序大致浏览一遍。就算这么做看起来像作弊,也照做不误。 留意有用的注释、测试数据,以及测试函数的名称。 在还没写任何代码之前先试着运行go test,看看错误信息能否给你一些从哪里入手的思路。

你的第一个目标是让代码能编译通过,即使测试不通过也没关系。 为此,你应该给函数写“桩”。 意思是把函数体留空,只填上它必须返回的内容。 写return 0或return "",或者随便什么,只要能编译通过就行。 有时为了弄清楚函数签名,你得回到测试程序,读得更仔细一些。 一旦你弄清楚了所有必需的函数签名,测试程序就会抱怨 0 是错误答案。 这时就可以开始填充函数体了。

修复错误

测试通常会在第一个错误处停下。 修好它,然后重复,直到没有错误。 go test有一些很有用的选项。 go test -v会给出更详细的输出。go test -run <regexp>只运行名称匹配<regexp>的测试。

panic 会产生大量输出。 一开始可能会让人觉得吓人,但别怕。 看 panic 输出的最上方,那里是 panic 消息。 它应该会给出问题的大致描述。 然后继续往下读,找到第一处提到你的代码的地方。 那通常正好指向问题所在。

要找出并发程序中的问题,可以试试go test -race。

整理代码

再说一遍:运行go fmt。 Golint能告诉你代码中go fmt抓不到的风格问题。 你也可以看看go vet,它会警告代码中潜在的问题。 阅读并留意代码评审中的常见意见。 对于涉及并发的练习,即使测试全都通过了,也试试go test -race。 即使为了基准测试性能做优化,也要把可读性放在心上。 有时优化能帮你发现既简洁又可读的解法,但在追求性能的过程中,也容易忍不住牺牲可读性。

附加测试

少数练习带有附加测试,只运行go test是不会执行的。 如果你在做常规练习之外还要完成附加练习,就得输入go test -tags bonus,或者测试程序文档中给出的类似命令。