使用覆盖信息测试 Go 中的 os.Exit 场景 (coveralls.io/Goveralls)
这个问题涉及涉及 os.Exit 的测试场景。 Go 中的 Exit(),特别是如何捕获这些场景的覆盖信息。提供的示例代码演示了重新执行方法,但它受到覆盖工具和脆弱性的限制。
覆盖挑战
一个困难是覆盖框架,例如coveralls.io 可能不会记录引发 os.Exit() 的测试的覆盖范围。这是因为重新执行测试二进制文件时,不会应用覆盖率检测。
修改的重新执行方法
为了解决此问题,修改了重新执行方法可以采用exec方法。原始代码被重构以将 os.Exit 提取为名为 osExit 的变量。然后,测试代码将 osExit 替换为记录退出代码的模拟函数。这允许捕获 osExit 调用的覆盖信息。
外部调用的覆盖
可以应用相同的技术来覆盖对 log.Fatalf() 等函数的调用,它间接调用 os.Exit。 logFatalf 函数被替换为模拟函数,该函数记录消息格式和传递给它的参数。这样可以确保覆盖外部函数调用 os.Exit 的场景。
示例
修改后的代码和测试如下:
// bar.go package foo import ( "fmt" "os" ) var osExit = os.Exit func Crasher() { fmt.Println("Going down in flames!") osExit(1) }
// bar_test.go package foo import ( "reflect" "testing" ) var logFatalf = log.Fatalf func TestCrasher(t *testing.T) { // Save original functions and restore at the end oldOsExit := osExit oldLogFatalf := logFatalf defer func() { osExit = oldOsExit logFatalf = oldLogFatalf }() // Mock osExit var got int myExit := func(code int) { got = code } osExit = myExit // Mock logFatalf var gotFormat string var gotV []interface{} myFatalf := func(format string, v ...interface{}) { gotFormat, gotV = format, v } logFatalf = myFatalf // Run test Crasher() // Check results exp := 1 if got != exp { t.Errorf("Expected exit code: %d, got: %d", exp, got) } expFormat, expV := "Exiting with code: %d", []interface{}{1} if gotFormat != expFormat || !reflect.DeepEqual(gotV, expV) { t.Error("Something went wrong") } }
通过隔离与退出相关的功能并使用模拟函数,os.Exit 和触发的外部函数调用os.Exit 可以在 Go 测试中覆盖。这种方法确保了涉及进程终止的场景的准确覆盖率报告。
以上是如何使用 os.Exit() 实现 Go 代码的准确测试覆盖率?的详细内容。更多信息请关注PHP中文网其他相关文章!