V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
ysmood
V2EX  ›  Go 编程语言

利用 snapshot 来简化测试代码

  •  
  •   ysmood ·
    ysmood · 2023-10-26 16:37:38 +08:00 · 1040 次点击
    这是一个创建于 380 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    例如,这里我们想要使用 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

    4 条回复    2023-10-27 08:31:33 +08:00
    mcfog
        1
    mcfog  
       2023-10-26 19:09:29 +08:00 via Android
    这是所谓的 golden test ,也就是用上次代码执行的结果来 assert 下次代码执行,和普遍意义的单元测试不是一回事儿
    ysmood
        2
    ysmood  
    OP
       2023-10-26 20:09:30 +08:00
    @mcfog 并不是用上次代码执行的结果来 assert 下次代码执行。
    一旦结果创建了,就不会再被覆盖了,除非你手动修改文件。这个在单元测试里很常见,很多测试框架都有 snapshot 的功能,你可以 google 下关键字。
    ysmood
        3
    ysmood  
    OP
       2023-10-26 20:16:18 +08:00
    不只是用来锁定结果保持不变。比如对于输出复杂的测试,可以先输出一个结果然后再修改 snapshot 文件到希望最终呈现的状态,再调试代码问题让输出跟 snapshot 一致。这样就不用手动写非常复杂的期望值了。
    foam
        4
    foam  
       2023-10-27 08:31:33 +08:00 via Android
    对,用快照来比对运行结果是常规测试方法。一般用在集成测试或 e2e
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2571 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 05:50 · PVG 13:50 · LAX 21:50 · JFK 00:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.