英文:
golang generate code coverage of functional test
问题
我有一个Go Web服务(一个REST API),我们有单元测试,并且Go覆盖率工作正常。
现在我们有一个用Python编写的测试套件,它启动服务器实例,运行测试,然后停止服务器。
我想知道是否有一些工具可以让我使用特定标志运行我的服务器二进制文件,以便最后打印出由我的“黑盒”测试执行的测试覆盖率?
谢谢。
英文:
I have a go webservices (a REST Api) for which we have unit test, and for which go cover works fine.
Now we have a test suite written in python that launch a instance of the server, run the test , stop the server.
I would like to know if there's some tools that would permit me to run my server binary with a specific flag , so that at the end it prints coverage of the tests executed by my "blackbox" testing ?
Thanks.
答案1
得分: 4
根据这篇帖子,我做了以下操作:
- 创建了一个名为
main_test.go
的文件,内容如下:
package main
// 代码基于这里解释的技术:
// https://www.elastic.co/blog/code-coverage-for-your-golang-system-tests
// 如果你想看如何在运行单元测试时不执行此测试,可以去那里看看。
// 这个文件是必需的,否则 packetbeat.test 二进制文件将无法正确生成。
import (
"testing"
)
// 当测试二进制文件启动时开始测试。只调用 main 函数。
func TestSystem(t *testing.T) {
main()
}
- 由于它是一个 Web 服务(因此处于无限循环中),我需要一种优雅地在 SIGTERM 信号下退出的方式(而不被视为失败),所以我使用了
go get gopkg.in/tylerb/graceful.v1
包,并在 main.go 中用以下代码替换了(我使用go-restful
):
- log.Fatal(http.ListenAndServe(":"+port, nil))
+ graceful.Run(":"+port, 10*time.Second, nil)
- 然后我会像这样运行测试:
go test -c -covermode=count -coverpkg ./... -o foo.test
./foo.test -test.coverprofile coverage.cov & echo $! > /tmp/test.pid
- 运行我的测试套件
kill "$(cat /tmp/test.pid)"
英文:
Based on this post here's what I did:
-
created a
main_test.go
with this content:package main // code based on technique explained here: // https://www.elastic.co/blog/code-coverage-for-your-golang-system-tests // you can look there if you want to see how not to execute this test // when running unit test etc. // This file is mandatory as otherwise the packetbeat.test binary is not generated correctly. import ( "testing" ) // Test started when the test binary is started. Only calls main. func TestSystem(t *testing.T) { main() }
-
as it was a web services (and hence in an infinite loop), I needed a way to gracefully exit on SIGTERM (without it being considered a failure), so I used the package
go get gopkg.in/tylerb/graceful.v1
and replaced (I usego-restful
) in main.go the line- log.Fatal(http.ListenAndServe(":"+port, nil)) + graceful.Run(":"+port, 10*time.Second, nil)
-
then I would run the test like this
go test -c -covermode=count -coverpkg ./... -o foo.test
./foo.test -test.coverprofile coverage.cov & echo $! > /tmp/test.pid
- run my test suite
kill "$(cat /tmp/test.pid)"
答案2
得分: 0
你可能不想这样做。使用覆盖率、竞争检测或其他工具运行代码会增加二进制文件的大小,并且使其运行速度变慢。在我的电脑上,同时运行竞争检测器和代码覆盖率测试要慢25倍。
在测试时,只需使用go test -cover -race
命令,部署时使用go build
命令即可。这样可以得到你想要的输出,尽管不完全符合你的要求。
英文:
You probably don't want to do that. Running code with coverage, race detection and/or other tools increases the binary size and makes it much slower. Running both the race detector and code coverage is 25 times slower on my computer.
Simply use go test -cover -race
for testing, and go build
when deploying. This will give you the output you want, albeit not in exactly the way you wanted it.
答案3
得分: 0
go test -c -cover
的解决方案有一些缺点,比如在生成代码覆盖率文件时,被测试的服务必须停止运行。而且它还会向被覆盖的二进制文件中注入一些不必要的标志,比如"-test.v",这可能会破坏服务的原始启动方式。
相反,我们使用goc来收集系统测试(API测试或端到端测试)的代码覆盖率,它可以在运行时轻松实现,我认为这更加优雅。
英文:
go test -c -cover
solution has some disadvantages like the service under tests must be stopped when to generate the code coverage profile. and it would also inject some unnecessary flags into the covered binary like "-test.v", which may break the service's original starting way.
We use goc instead, it help us collect code coverage of system tests (API tests or e2e tests) at runtime easily, i think it's more elegant.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论