1 回答

TA贡献1811条经验 获得超6个赞
在@Volker 对我的 QI 发表评论后,我知道我必须接受挑战并直接获取 Gotesting
包的源代码。虽然@marco.m 的建议在许多情况下都有帮助,但它无法处理我公认的有点奇怪的用例。testing
与我原来的问题相关的机制如下,大大简化:
cover.go:实现
coverReport()
写入覆盖数据文件(ASCII 文本格式);如果文件已经存在(之前运行的旧版本),那么它将首先被截断。请注意,它coverReport()
有将一些“统计”信息打印到 os.Stdout 的烦人习惯。获取 CLI 参数
-test.coverprofile=
和-test.outputdir=
fromos.Args
(通过 flags 包)。如果指定的话,如果还实现toOutputDir(path)
了哪些地方覆盖配置文件-test.outputdir
。但是什么时候
coverReport()
被调用?简单地说,在结尾testing.M.Run()
。
现在有了这些知识,一个疯狂的解决方案开始出现,有点“变坏”;)
包装
testing.M
一个特殊的启用重新执行的版本reexec.testing.M
:它检测它是否在启用覆盖的情况下运行:如果它是“父”进程 P,那么它正常运行测试,然后它从重新执行的子进程 C 中收集覆盖率配置文件数据文件并将它们合并到 P 的覆盖率配置文件数据文件中。
而在 P 中,当即将重新执行新的子 C 时,会为子 C 分配一个新的专用覆盖配置文件数据文件名。然后 C 通过其“个人”
-test.coverprofile=
CLI arg 获取文件名。在 C 中,我们运行所需的动作函数。接下来,我们需要运行一个空的测试集以触发为 C 编写覆盖率配置文件数据。为此,P 中的重新执行函数添加了
test.run=
一个非常特殊的“ Bielefeld测试模式”,这很可能会导致空结果。请记住,P 将——在它运行完所有测试之后——拾取单独的 C 覆盖率配置文件数据文件并将它们合并到 P 中。如果未启用覆盖分析,则无需采取任何特殊操作。
这个解决方案的缺点是它依赖于 Go 的testing
一些关于如何以及何时编写代码覆盖率报告的非保证行为。但由于 Linux 内核命名空间发现包已经比 Docker 的 libnetwork 更难推动 Go,这只是一个超出边缘的量子。
对于测试开发人员来说,整个辣酱玉米饼馅都隐藏在“增强的”rxtst.M
包装器中。
import (
"testing"
rxtst "github.com/thediveo/gons/reexec/testing"
)
func TestMain(m *testing.M) {
// Ensure that the registered handler is run in the re-executed child.
// This won't trigger the handler while we're in the parent. We're using
// gons' very special coverage profiling support for re-execution.
mm := &rxtst.M{M: m}
os.Exit(mm.Run())
}
运行具有覆盖率的整个lxkns测试套件,最好使用go-acc(进行准确的代码覆盖率计算),然后在下面的屏幕截图中显示该函数discoverNsfsBindMounts()运行了一次 (1)。这个函数不是从 P 中的任何地方直接调用的。相反,这个函数被注册,然后在重新执行的子 C 中运行。以前,没有报告代码覆盖discoverNsfsBindMounts(),但现在在包github.com/thediveo的帮助下C 的/gons/reexec/testing代码覆盖率透明地合并到 P 的代码覆盖率中。
- 1 回答
- 0 关注
- 156 浏览
添加回答
举报