写点什么

Go 入门很简单:Go 测试

作者:宇宙之一粟
  • 2022 年 1 月 21 日
  • 本文字数:1839 字

    阅读完需:约 6 分钟

介绍

编程不易;即使是最好的程序员也无法编写每次都能完全按照预期工作的程序。因此,软件开发过程的一个重要部分是测试。为我们的代码编写测试是确保质量和提高可靠性的好方法。


Go 提供了 testing 包和 go test 工具帮助我们编写自动化测试。


单元测试是编写有原则的 Go 程序的一个重要部分。测试包提供了我们编写单元测试所需的工具,go test 命令可以运行测试。为了便于演示,这段代码是在包 main 中,但它可以是任何包。测试代码通常与它所测试的代码生活在同一个包里。

测试代码结构

Go 语言推荐测试文件和源代码文件放在一块,测试文件以 _test.go 结尾。比如,当前 package 有 average.go 一个文件,我们想测试 average.go 中的 Average 函数,那么应该新建 average_test.go 作为测试文件。


example/   |--average.go   |--average_test.go
复制代码

测试我们的代码

我们将测试这个整数最小值的简单实现。通常情况下,我们要测试的代码会在一个名为 intutils.go 的源文件中,而它的测试文件会被命名为``intutils_test.go` 。


package main
import ( "fmt" "testing")
func IntMin(a, b int) int { if a < b { return a } return b}
func TestIntMinBasic(t *testing.T) { ans := IntMin(2, -2) if ans != -2 {
t.Errorf("IntMin(2, -2) = %d; want -2", ans) }}
func TestIntMinTableDriven(t *testing.T) { var tests = []struct { a, b int want int }{ {0, 1, 0}, {1, 0, 0}, {2, -2, -2}, {0, -1, -1}, {-1, 0, -1}, }
for _, tt := range tests {
testname := fmt.Sprintf("%d,%d", tt.a, tt.b) t.Run(testname, func(t *testing.T) { ans := IntMin(tt.a, tt.b) if ans != tt.want { t.Errorf("got %d, want %d", ans, tt.want) } }) }}
func BenchmarkIntMin(b *testing.B) { for i := 0; i < b.N; i++ { IntMin(1, 2) }}
复制代码


通过编写一个名称以 Test 开头的函数来创建一个测试。


t.Error* 将报告测试失败但继续执行测试。t.Fatal* 将报告测试失败并立即停止测试。


编写测试可能是重复性的,所以使用表格驱动的风格是习惯性的,测试输入和预期输出被列在一个表格中,一个单一的循环走过它们并执行测试逻辑。


t.Run 可以运行 "子测试",每个表项都有一个。当执行go test -v 时,这些子测试会分别显示出来。


以粗略模式运行当前项目中的所有测试.


运行结果:


$ go test -v== RUN   TestIntMinBasic--- PASS: TestIntMinBasic (0.00s)=== RUN   TestIntMinTableDriven=== RUN   TestIntMinTableDriven/0,1=== RUN   TestIntMinTableDriven/1,0=== RUN   TestIntMinTableDriven/2,-2=== RUN   TestIntMinTableDriven/0,-1=== RUN   TestIntMinTableDriven/-1,0--- PASS: TestIntMinTableDriven (0.00s)    --- PASS: TestIntMinTableDriven/0,1 (0.00s)    --- PASS: TestIntMinTableDriven/1,0 (0.00s)    --- PASS: TestIntMinTableDriven/2,-2 (0.00s)    --- PASS: TestIntMinTableDriven/0,-1 (0.00s)    --- PASS: TestIntMinTableDriven/-1,0 (0.00s)PASSok      examples/testing    0.023s
复制代码


以上代码翻译自:https://gobyexample.com/testing

测试平均分代码

比如,我们的计算平均分的代码 average.go 可以这样写:


package main
func GetScore(scores ...float64) (sum,avg float64, count int) { for _,values := range scores{ sum += values count++ } avg = sum/ float64((count)) return}
复制代码


package math
import "testing"
type testpair struct { values []float64 average float64}
var tests = []testpair{ { []float64{1,2}, 1.5 }, { []float64{1,1,1,1,1,1}, 1 }, { []float64{-1,1}, 0 },}
func TestAverage(t *testing.T) { for _, pair := range tests { v := Average(pair.values) if v != pair.average { t.Error( "For", pair.values, "expected", pair.average, "got", v, ) } }}
复制代码


这是一种非常常见的设置测试的方法(丰富的例子可以在 Go 软件包的源代码中找到)。我们创建一个结构来代表函数的输入和输出。然后我们创建一个这些结构的列表(对)。然后我们循环浏览每一个结构并运行该函数。

发布于: 刚刚阅读数: 3
用户头像

宇宙古今无有穷期,一生不过须臾,当思奋争 2020.05.07 加入

🏆InfoQ写作平台-第二季签约作者 🏆 混迹于江湖,江湖却没有我的影子 热爱技术,专注于后端全栈,轻易不换岗 拒绝内卷,工作于软件工程师,弹性不加班 热衷分享,执着于阅读写作,佛系不水文

评论

发布
暂无评论
Go 入门很简单:Go 测试