go test是否并发运行单元测试?

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

Does go test run unit tests concurrently?

问题

当运行go test时,它会通过运行以_test.go结尾的文件中以TestXxx格式开头并使用(*t testing.T)模块的函数来运行测试。我想知道_test.go文件中的每个函数是并发运行还是明确地分别运行?它是否为每个函数创建一个goroutine?如果它为每个函数创建一个goroutine,我能以某种方式监视这些goroutine吗?是否有可能像golibrary.GoRoutines()这样做,并为每个goroutine获取一个实例并以某种方式监视它们或类似的操作?


注意:这个问题假设你正在使用Go语言自带的测试框架(testing)。

英文:

When go test is ran it runs your files ending in _test.go by running the functions that start in the format TestXxx and use the (*t testing.T) module. I was wondering if each function in the _test.go file were ran concurrently or if it definitively ran each function separately? Does it create a go routine for each one? If it does create a go routine for each one, can I monitor the go routines in some way? Is it ever possible to do something like golibrary.GoRoutines() and get an instance for each one and monitor them some how or something like that?


Note: this question assumes you using the testing framework that comes with go (testing).

答案1

得分: 46

是的,测试是作为goroutine执行的,因此是并发执行的。

然而,默认情况下,测试不会并行运行,正如@jacobsa所指出的那样。要启用并行执行,您需要在测试用例中调用t.Parallel(),并适当设置GOMAXPROCS或提供-parallel N(默认情况下设置为GOMAXPROCS)。

在您的情况下,当并行运行测试时,最简单的解决方案是使用全局切片存储端口号,并使用全局原子递增的索引作为测试和切片中端口之间的关联。这样,您就可以控制端口号,并为每个测试分配一个端口。示例代码如下:

import "sync/atomic"

var ports [...]uint64 = {10, 5, 55}
var portIndex uint32

func nextPort() uint32 {
    return atomic.AddUint32(&portIndex, 1)
}
英文:

Yes, tests are executed as goroutines and, thus, executed concurrently.

However, tests do not run in parallel by default as pointed out by @jacobsa. To enable parallel execution you would have to call t.Parallel() in your test case and set GOMAXPROCS appropriately or supply -parallel N (which is set to GOMAXPROCS by default).

The simplest solution for your case when running tests in parallel would be to have a global slice for port numbers and a global atomically incremented index that serves as association between test and port from the slice. That way you control the port numbers and have one port for each test. Example:

import "sync/atomic"

var ports [...]uint64 = {10, 5, 55}
var portIndex uint32

func nextPort() uint32 {
    return atomic.AddUint32(&portIndex, 1)
}

答案2

得分: 34

是的,正如其他答案已经指出的那样,如果你在一个_test.go文件中添加了t.Parallel()并使用-parallel标签运行,那么其中的测试将会并行运行。

但是,默认情况下,go test命令会并行运行不同包的测试,而默认并行度是可用的CPU数量(参见go help build)。

因此,要禁用并行执行,你应该像这样运行测试:
go test -p 1 ./...

英文:

Yes, as other answers already pointed, tests inside one _test.go file are running in parallel only if you add t.Parallel() and run with -parallel tag.

BUT - by default the command go test runs in parallel tests for different packages, and default is the number of CPUs available (see go help build)

So to disable parallel execution you should run tests like this
go test -p 1 ./...

答案3

得分: 11

是的,如果你在函数中添加t.Parallel(),就可以实现并行测试。代码示例如下:

func TestMyFunction(t *testing.T) {
    t.Parallel()
    // 在这里编写你的测试代码
}

这样就可以在测试时同时运行多个测试函数,提高测试效率。

英文:

Yes if you add this :
t.Parallel() to your functions.

like this:

func TestMyFunction(t *testing.T) {
	t.Parallel()
    //your test code here

}

答案4

得分: 8

在Go语言中,有两个方面涉及到“并行测试”。

1)并行测试包(文件夹)。通过-p标志进行控制。

go help build

	-p n
		可以并行运行的程序数量,例如构建命令或测试二进制文件。
		默认值为 GOMAXPROCS,通常为可用的 CPU 数量。

2)并行测试包内的测试。通过-parallel标志进行控制,并且测试需要使用t.Parallel()启用。

go help testflag

	-parallel n
	    允许并行执行调用了 t.Parallel 的测试函数。
	    此标志的值是同时运行的最大测试数量;
	    默认情况下,它设置为 GOMAXPROCS 的值。
	    注意,-parallel 仅适用于单个测试二进制文件。
	    根据 -p 标志的设置(参见 go help build),
	    'go test' 命令也可以并行运行不同包的测试。

对于第一点,你可以通过在多个包中进行测试,并使用 sleep 强制它们运行较长时间来直接观察。然后使用 ps aux 命令并使用 grep 过滤正在运行的 go 进程,你将会看到并行运行的独立进程。

或者使用 -x 详细标志运行。这将清楚地显示正在发生的情况。测试会针对每个包启动一次(例如,给定多个包中的 *_test.go 文件)。请注意,我正在使用不同的 -p=N -parallel=M 配置运行 go test -x ./... -v -count=1 |& ruby -pe 'print Time.now.strftime("[%Y-%m-%d %H:%M:%S] ")' |& tee temp.out,你可以看到它们并行运行的情况:

[2022-05-09 17:22:26] $WORK/b065/understandinit.test -test.paniconexit0 -test.timeout=10m0s -test.parallel=1 -test.v=true -test.count=1
[2022-05-09 17:22:26] $WORK/b001/main.test -test.paniconexit0 -test.timeout=10m0s -test.parallel=1 -test.v=true -test.count=1
[2022-05-09 17:22:26] $WORK/b062/mainsub.test -test.paniconexit0 -test.timeout=10m0s -test.parallel=1 -test.v=true -test.count=1
英文:

There are two aspects of "parallel tests" in go.

  1. Testing of packages (folders) in parallel. Controlled by -p flag.

go help build:

	-p n
		the number of programs, such as build commands or
		test binaries, that can be run in parallel.
		The default is GOMAXPROCS, normally the number of CPUs available.
  1. Testing of tests within a package. Controlled by -parallel flag, and tests need this enabled with t.Parallel().

go help testflag:

	-parallel n
	    Allow parallel execution of test functions that call t.Parallel.
	    The value of this flag is the maximum number of tests to run
	    simultaneously; by default, it is set to the value of GOMAXPROCS.
	    Note that -parallel only applies within a single test binary.
	    The 'go test' command may run tests for different packages
	    in parallel as well, according to the setting of the -p flag
	    (see 'go help build').

For #1, you can observe this directly by having tests in multiple packages, and forcing them to be long running with a sleep. Then ps aux and grep for go running and you'll see separate processes in parallel.

Or run with -x detail flag. That pretty clearly shows what’s going on. The tests are launched once per package (e.g. given have *_test.go files in several package. Note I’m running go test -x ./... -v -count=1 |& ruby -pe 'print Time.now.strftime("[%Y-%m-%d %H:%M:%S] ")' |& tee temp.out with various configurations of -p=N -parallel=M, you can see in parallel them running:

[2022-05-09 17:22:26] $WORK/b065/understandinit.test -test.paniconexit0 -test.timeout=10m0s -test.parallel=1 -test.v=true -test.count=1
[2022-05-09 17:22:26] $WORK/b001/main.test -test.paniconexit0 -test.timeout=10m0s -test.parallel=1 -test.v=true -test.count=1
[2022-05-09 17:22:26] $WORK/b062/mainsub.test -test.paniconexit0 -test.timeout=10m0s -test.parallel=1 -test.v=true -test.count=1

答案5

得分: 4

你可以通过使用t.Parallel标记测试,并使用-parallel标志运行测试来同时运行它们。

你可以在这里查看其他测试标志

英文:

You can run them concurrently by flagging the test with t.Parallel
and then run the test using the -parallel flag.

You can see other testing flags here

huangapple
  • 本文由 发表于 2014年6月24日 07:06:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/24375966.html
匿名

发表评论

匿名网友

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

确定