为了账号安全,请及时绑定邮箱和手机立即绑定

在golang中使用子流程测试时如何生成单元测试覆盖率?

在golang中使用子流程测试时如何生成单元测试覆盖率?

Go
30秒到达战场 2021-08-16 19:54:19
我对我们的大部分代码进行了单元测试。但是我无法弄清楚如何为 main 包中的 main() 中的某些代码生成单元测试覆盖率。主要功能非常简单。它基本上是一个选择块。它读取标志,然后调用另一个函数/执行某事,或者只是在屏幕上打印帮助。但是,如果命令行选项设置不正确,它将以各种错误代码退出。因此,需要进行子过程测试。我尝试了子流程测试技术,但修改了代码,使其包含覆盖标志:cmd := exec.Command(os.Args[0], "-test.run=TestMain -test.coverprofile=/vagrant/ucover/coverage2.out")这是原始代码:https : //talks.golang.org/2014/testing.slide#23上面幻灯片的解释:http : //youtu.be/ndmB0bj7eyw?t=47m16s但它不会生成封面配置文件。我一直无法弄清楚为什么不。它确实为执行测试的主进程生成覆盖配置文件,但是在子进程中执行的任何代码当然不会被标记为已执行。我尝试实现尽可能多的代码覆盖率。我不确定我是否遗漏了什么,或者是否有更简单的方法来做到这一点。或者,如果这是不可能的。
查看完整描述

3 回答

?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

我会考虑需要测试的逻辑main():


func main() {

    start(os.Args)

}


func start(args []string) {

    // old main() logic

}

通过这种方式,您可以在start()不改变os.Args.


查看完整回答
反对 回复 2021-08-16
?
烙印99

TA贡献1829条经验 获得超13个赞

我采用了另一种不涉及重构 main() 的方法:请参阅此提交:


我使用全局(未导出)变量:


var args []string

然后在main(),os.Args除非var args设置了私有,否则我使用:


a := os.Args[1:]

if args != nil {

    a = args

}

flag.CommandLine.Parse(a)

在我的测试中,我可以设置我想要的参数:


args = []string{"-v", "-audit", "_tests/p1/conf/gitolite.conf"}

main()

而且我仍然实现了 100% 的代码覆盖率,甚至超过了main().


查看完整回答
反对 回复 2021-08-16
?
万千封印

TA贡献1891条经验 获得超3个赞

在 Go 1.11 中使用 @VonC 解决方案,我发现我必须在每次重新定义标志的测试中重置 flag.CommandLine,以避免“重新定义标志”恐慌。:


    for _, check := range checks {

        t.Run("flagging " + check.arg, func(t *testing.T) {

            flag.CommandLine = flag.NewFlagSet(cmd, flag.ContinueOnError)

            args = []string{check.arg}

            main()

        })

    }


查看完整回答
反对 回复 2021-08-16
  • 3 回答
  • 0 关注
  • 209 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信