How can stdout be captured or suppressed for Go(lang) testing?

huangapple go评论89阅读模式
英文:

How can stdout be captured or suppressed for Go(lang) testing?

问题

如何在Go测试中捕获或抑制stdout输出?

我正在尝试学习Go语言的测试。在下面的代码中,myshow.LoadPath函数会将大量信息打印到stdout(这是一种正常的副作用)。但是,当我运行"go test"时,这会导致输出非常嘈杂。有没有办法抑制或捕获stdout输出?

作为对比,我在Python世界中考虑了类似于以下链接的解决方案:http://pytest.org/latest/capture.html#captures

package slideshow_test

import (
	"os"
	"testing"

	"github.com/golliher/go-hpf/slideshow"
)

func setupTest() {
	myshow := slideshow.Slideshow{Name: "This is my show"}
	myshow.LoadPath("..")

}

func TestStub(t *testing.T) {
	if true == false {
		t.Fail()
	}
}

func TestMain(m *testing.M) {
	setupTest()
	os.Exit(m.Run())

}

请注意,这只是翻译的部分内容,不包括代码部分。

英文:

How can stdout be captured or suppressed for Go testing?

I am trying to teach myself go(lang) testing. In the code below, myshow.LoadPath prints lots of information to stdout (which is a normal side effect). It does however make for very noisy output when I run "go test" Is there a way to suppress or capture stdout?

For comparison, I'm thinking about something like this from the python world. http://pytest.org/latest/capture.html#captures

package slideshow_test

import (
	"os"
	"testing"

	"github.com/golliher/go-hpf/slideshow"
)

func setupTest() {
	myshow := slideshow.Slideshow{Name: "This is my show"}
	myshow.LoadPath("..")

}

func TestStub(t *testing.T) {
	if true == false {
		t.Fail()
	}
}

func TestMain(m *testing.M) {
	setupTest()
	os.Exit(m.Run())

}

答案1

得分: 10

os.Stdout 是被 fmt.Printf 等函数使用的一个变量。因此,你可以随时覆盖它,并在需要时恢复它。详细信息请参考:https://golang.org/pkg/os/#pkg-variables

英文:

os.Stdout which is used by the fmt.Printf and others is just a variable. So you can overwrite it at any time and restore it back when necessary. https://golang.org/pkg/os/#pkg-variables

答案2

得分: 9

为了在测试期间抑制输出,我使用了以下代码。它修复了输出和日志记录。测试完成后,它会重置输出流。

func TestStartStowWrongCommand(t *testing.T) {
    defer quiet()()
    ...
}

func quiet() func() {
    null, _ := os.Open(os.DevNull)
    sout := os.Stdout
    serr := os.Stderr
    os.Stdout = null
    os.Stderr = null
    log.SetOutput(null)
    return func() {
        defer null.Close()
        os.Stdout = sout
        os.Stderr = serr
        log.SetOutput(os.Stderr)
    }
}

以上是要翻译的内容。

英文:

To suppress the output during the test I use the following code. I fixes output as well as logging. After test is done it resets the output streams.

func TestStartStowWrongCommand(t *testing.T) {
 defer quiet()()   
 ...                      
}

func quiet() func() {
 null, _ := os.Open(os.DevNull)
 sout := os.Stdout
 serr := os.Stderr
 os.Stdout = null
 os.Stderr = null
 log.SetOutput(null)
 return func() {
  defer null.Close()
  os.Stdout = sout
  os.Stderr = serr
  log.SetOutput(os.Stderr)
 }
}

答案3

得分: 8

输出可以通过使用go test .命令来抑制:

> $ go help test
>
> go test有两种不同的模式:本地目录模式和包列表模式。在本地目录模式下,当没有指定包参数时(例如,go test),它会编译和测试当前目录中找到的包源代码,然后运行生成的测试二进制文件。在这种模式下,缓存是禁用的。在包测试完成后,go test会打印一个摘要行,显示测试状态('ok'或'FAIL')、包名和耗时。
>
> 在包列表模式下,go test会编译和测试命令行上列出的每个包。如果一个包的测试通过,go test只会打印最终的'ok'摘要行。如果一个包的测试失败,go test会打印完整的测试输出。如果使用了-bench或-v标志,go test会打印完整的输出,即使包的测试通过,以显示请求的基准结果或详细日志记录。

英文:

The output can be suppressed
by running the tests with go test .:

> $ go help test
>
> Go test runs in two different modes: local
> directory mode when invoked with no package arguments (for example,
> 'go test'), and package list mode when invoked with package arguments
> (for example 'go test math', 'go test ./...', and even 'go test .').
>
> In local directory mode, go test compiles and tests the package
> sources found in the current directory and then runs the resulting
> test binary. In this mode, caching (discussed below) is disabled.
> After the package test finishes, go test prints a summary line showing
> the test status ('ok' or 'FAIL'), package name, and elapsed time.
>
> In package list mode, go test compiles and tests each of the packages
> listed on the command line. If a package test passes, go test prints
> only the final 'ok' summary line. If a package test fails, go test
> prints the full test output. If invoked with the -bench or -v flag, go
> test prints the full output even for passing package tests, in order
> to display the requested benchmark results or verbose logging.

答案4

得分: 4

虽然不完全符合你的要求,但可能仍然有帮助。

你可以在测试方法中使用 t.Log (http://golang.org/pkg/testing/#T.Log) 和 t.Logf (http://golang.org/pkg/testing/#T.Logf) 方法。只有当测试失败或设置了 -test.v 标志时,输出才会被打印出来。

我还建议在 myshow.LoadPath 中使用 log 包来打印到控制台。然后,你可以通过设置自定义的写入器(writer)来禁用(或捕获)测试中的输出,使用 log.SetOutput 方法。

英文:

Not exactly what you are asking for but still might be helpful.

You can use t.Log (http://golang.org/pkg/testing/#T.Log) and t.Logf (http://golang.org/pkg/testing/#T.Logf) methods in the test method. The output will be printed only if the test fails or the -test.v flag is set.

I also would suggest to use log package to print to the console in myshow.LoadPath. Then you can disable (or capture) the output in the test by setting custom writer using log.SetOutput

答案5

得分: 1

你可以按照grzegorz的建议来静音os.Stdout。

我想要补充的是,请记住一些程序会检查从fmt.Print返回的err,所以你需要将os.Stdout分配给一个可写的空设备,像这样:

os.Stdout, _ = os.OpenFile(os.DevNull, os.O_WRONLY, 0)
英文:

You can silence the os.Stdout like grzegorz suggested.

The only thing I want to add is keep in mind that some programs checks the err that returns from fmt.Print, so you need to assign to os.Stdout a writable null device like so:

os.Stdout, _ = os.OpenFile(os.DevNull, os.O_WRONLY, 0)

huangapple
  • 本文由 发表于 2015年7月28日 05:00:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/31663229.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定