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

Unit testing 在golang中使用子流程测试时,如何生成单元测试覆盖率?,unit-testing,go,Unit Testing,Go,我们的大部分代码都有单元测试。但我不知道如何在main包的main()中为某些代码生成单元测试覆盖率 主要功能非常简单。它基本上是一个选择块。它读取标志,然后调用另一个函数/执行某些操作,或者只是在屏幕上打印帮助。但是,如果命令行选项设置不正确,它将以各种错误代码退出。因此,需要进行子流程测试 我尝试了子流程测试技术,但修改了代码,使其包含覆盖率标志: cmd := exec.Command(os.Args[0], "-test.run=TestMain -test.coverprofile=/

我们的大部分代码都有单元测试。但我不知道如何在main包的main()中为某些代码生成单元测试覆盖率

主要功能非常简单。它基本上是一个选择块。它读取标志,然后调用另一个函数/执行某些操作,或者只是在屏幕上打印帮助。但是,如果命令行选项设置不正确,它将以各种错误代码退出。因此,需要进行子流程测试

我尝试了子流程测试技术,但修改了代码,使其包含覆盖率标志:

cmd := exec.Command(os.Args[0], "-test.run=TestMain -test.coverprofile=/vagrant/ucover/coverage2.out")
以下是原始代码: 对上述幻灯片的解释:

但它不会生成封面简介。我还不知道为什么不能。它确实为执行测试的主进程生成覆盖概要文件,但在子进程中执行的任何代码当然都不会标记为已执行

我试图实现尽可能多的代码覆盖率。我不确定我是否遗漏了什么,或者是否有更简单的方法来做到这一点。或者如果这是不可能的

感谢您的帮助

谢谢


Amer

我会将需要测试的逻辑从
main()
中剔除:


通过这种方式,您可以在不改变os.Args的情况下进行单元测试
start()
,我采用了另一种不涉及重构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%的代码覆盖率,甚至在使用Go 1.11的@VonC解决方案时,我发现我必须在每次重新定义标志的测试中重置flag.CommandLine,以避免“标志重新定义”恐慌

对于u,检查:=范围检查{
t、 运行(“标记”+check.arg,func(t*testing.t){
flag.CommandLine=flag.NewFlagSet(cmd,flag.ContinueOnError)
args=[]字符串{check.arg}
main()
})
}

谢谢!我非常专注于使子流程测试工作,而没有考虑重新分解。我们将要做的是在包装器函数中移动所有os.Exit()调用。这样我们就可以在测试中模拟这个函数了。你解决了我即将遇到的下一个问题。到目前为止,我在单元测试中使用:
flag.BoolVar(SHOWVERSION,“SHOWVERSION”,true,“usage”)
设置标志。只要我不使用不同的值重新定义测试标志,它就可以工作。谢谢,我将使用您的方法。@是的,我总是在
main()
中设置标志。我只在测试中设置了
args
。在Go 1.11中使用它,我发现我必须在每次重新定义标志的测试中重置flag.CommandLine,以避免“flag redefined”恐慌。
lang Go for uuuu,check:=范围检查{t.Run(“flagging”+check.arg,func(t*testing.t){flag.CommandLine=flag.NewFlagSet(cmd,flag.ContinueOnError)args=[]字符串{check.arg}main()}
@VonC using NewFlagSet还允许您使用
SetOutput
,如
flag.CommandLine.SetOutput(someBuffer)
,以便在测试中捕获stderr输出并检查sad情况的正确性。这在搜索引擎结果中被一个不太相关的标记所掩盖。请考虑修改标题,在GO/<代码>中包含<代码>单元测试命令行标志。
args = []string{"-v", "-audit", "_tests/p1/conf/gitolite.conf"}
main()