利用 snapshot 来简化测试代码

196 天前
 ysmood

例如,当您想要锁定函数返回值的复杂结果时,通常需要在测试中放置一大段数据代码块,或者手动在单独的文件中维护代码块,这对于维护者来说可能会让他们阅读实际测试逻辑变得混乱。

例如,这里我们想要使用 testify 来检查 ast 解析器的输出:

package main_test

import (
	"go/ast"
	"go/parser"
	"go/token"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestSnapshot(t *testing.T) {
	exp, err := parser.ParseExpr("(1 + 2) * 3")
	assert.Nil(t, err)

	assert.Equal(t, exp, &ast.BinaryExpr{
		X: &ast.ParenExpr{
			Lparen: token.Pos(1),
			X: &ast.BinaryExpr{
				X: &ast.BasicLit{
					ValuePos: token.Pos(2),
					Kind:     token.Token(5),
					Value:    "1",
				},
				OpPos: token.Pos(4),
				Op:    token.Token(12),
				Y: &ast.BasicLit{
					ValuePos: token.Pos(6),
					Kind:     token.Token(5),
					Value:    "2",
				},
			},
			Rparen: token.Pos(7),
		},
		OpPos: token.Pos(9),
		Op:    token.Token(14),
		Y: &ast.BasicLit{
			ValuePos: token.Pos(11),
			Kind:     token.Token(5),
			Value:    "3",
		},
	})
}

使用 snapshot ,您的代码将变得更加清晰简洁:

package main_test

import (
	"go/parser"
	"testing"

	"github.com/ysmood/got"
)

func TestSnapshot(t *testing.T) {
	g := got.T(t)

	exp, err := parser.ParseExpr("(1 + 2) * 3")
	g.E(err)

	g.Snapshot("ast", exp)
}

有关 snapshot 助手的文档: link

如果想要使用 json 作为快照文件: link

918 次点击
所在节点    Go 编程语言
4 条回复
mcfog
196 天前
这是所谓的 golden test ,也就是用上次代码执行的结果来 assert 下次代码执行,和普遍意义的单元测试不是一回事儿
ysmood
196 天前
@mcfog 并不是用上次代码执行的结果来 assert 下次代码执行。
一旦结果创建了,就不会再被覆盖了,除非你手动修改文件。这个在单元测试里很常见,很多测试框架都有 snapshot 的功能,你可以 google 下关键字。
ysmood
196 天前
不只是用来锁定结果保持不变。比如对于输出复杂的测试,可以先输出一个结果然后再修改 snapshot 文件到希望最终呈现的状态,再调试代码问题让输出跟 snapshot 一致。这样就不用手动写非常复杂的期望值了。
foam
196 天前
对,用快照来比对运行结果是常规测试方法。一般用在集成测试或 e2e

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/985706

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX