英文:
How to ignore generated files from Go test coverage
问题
我在我的软件包中有一个带有顶部的DO NOT EDIT
的生成文件。我正在使用go test -coverprofile=cover.out <package>
运行软件包的测试。这将创建覆盖率文件并显示总覆盖率百分比。但是,在计算覆盖率时,它也包括生成的文件。有没有办法在计算覆盖率时忽略生成的文件?
英文:
I have a generated file in my package with DO NOT EDIT
on top. I am running tests for my package with go test -coverprofile=cover.out <package>
. This creates coverage profile and shows total coverage percentage. But it also includes generated files while calculating the coverage. Is there a way to ignore generated files in coverage calculation?
答案1
得分: 29
你可以从覆盖率文件中去除生成的代码:
go test . -coverprofile cover.out.tmp
cat cover.out.tmp | grep -v "_generated.go" > cover.out
tool cover -func cover.out
根据使用的工具,可以在流水线/Makefile中轻松实现这一点。
英文:
You could strip the generated code from the cover profiles:
go test . -coverprofile cover.out.tmp
cat cover.out.tmp | grep -v "_generated.go" > cover.out
tool cover -func cover.out
Depending on the used tools this can be implemented easily in the pipeline/make.
答案2
得分: 14
大多数Go工具都是针对包进行操作的,因为一个包本身就是一个可以完整使用的“单元”。从包中排除文件可能会很容易地“破坏”这个包:被排除的文件可能包含(关键的)包初始化代码,甚至可能导致剩余的包文件无法编译。
go test
也不例外:它也是针对包进行操作的。目前没有直接支持从包中排除文件的功能。
如果你的包可以在不包含生成的文件的情况下进行编译和测试,你可以选择将生成的文件放在一个不同的包中,这样它就不会自然地包含在你的包的(覆盖率)测试中。
另一种处理方法是仍然将其生成在同一个包/文件夹中,并在生成的文件中使用特殊的构建标签,在运行覆盖率测试时可以排除这些标签。你可以在这里了解更多关于构建标签的信息:构建约束,以及这里:https://stackoverflow.com/questions/35428963/what-is-the-right-approach-to-encapsulate-platform-specific-code-in-go/35429081#35429081
如果生成的文件需要用于编译/测试包,那么你仍然有一个选择:为生成的文件使用一个“internal”包。内部包只对以internal
文件夹为根的包树可见,这意味着你可以在内部包中导出任何标识符,编译器会确保它们不会被“意外”的使用。你可以在这里了解更多关于内部包的信息:https://stackoverflow.com/questions/45899203/can-i-develop-a-go-package-in-multiple-source-directories/45902409#45902409
此外,还可以考虑为生成的代码编写或生成测试,这可能是一个好的实践,这样你就不必使用技巧将其排除在覆盖率测试之外。
英文:
Most Go tools operate on packages, because a package itself forms a unit that may be useful in its entirety. Excluding files from a package could easily "break" the package: the excluded file may contain (crucial) package initialization code or may even cause the remaining package files fail to compile.
go test
is no exception: it also operates on packages. There is no first-hand support to exclude files from a package.
If your package may be compiled and tested without the generated file, you may opt to generate the file into a different package, and then it won't be included in your package's (coverage) test naturally.
Another way to handle this would be to still generate it in the same package / folder, and use special build tags in the generated files, which you may exclude when running the coverage test. You can read more about build tags here: Build Constraints, and here: https://stackoverflow.com/questions/35428963/what-is-the-right-approach-to-encapsulate-platform-specific-code-in-go/35429081#35429081
If the generated file is needed to compile / test the package, then you still have an option: use an internal package for the generated file. Internal packages are only available to the package tree rooted at the internal
folder, which means you may export any identifiers in an internal package, the compiler ensures they won't be used by "unintended" parties. You can read more about internal packages here: https://stackoverflow.com/questions/45899203/can-i-develop-a-go-package-in-multiple-source-directories/45902409#45902409
Also consider the option to write or generate test for the generated code, which may be good practice anyway, so you wouldn't have to use tricks to exclude them from coverage tests.
答案3
得分: 14
以下是我翻译好的内容:
根据我解决这个需求的方式。
通过排除目录/包
由于要运行测试并生成覆盖率报告,您需要指定go test命令应该在哪些包中查找文件,超出这些包的文件将自动被忽略。以下是一个示例:
project
|_______/pkg/web/app
|_______/pkg/web/mock -> 它将被忽略。
# 命令:
$go test -failfast -tags=integration -coverprofile=coverage.out -covermode=count github.com/aerogear/mobile-security-service/pkg/web/apps
然而,并非所有情况都适用。例如,如果文件是接口的模拟实现,这种方法可能效果不佳,因为服务、测试和模拟实现中所需的导入可能会形成循环,而这是不允许的。
通过在名称定义中使用“_test”
如果您想忽略在测试中使用的文件,可以在名称末尾使用“_test”。例如,my_service_mock_test.go
。以“_test”结尾的文件将默认被忽略。
通过从覆盖率文件中移除
go test . -coverprofile cover.out.tmp
cat cover.out.tmp | grep -v "_generated.go" > cover.out
tool cover -func cover.out
附注:我找不到可以排除它们的注释或标签。
英文:
Following the ways that I could solve this need.
By excluding dirs/pkgs
Since to run the test and generated the cover you will specify the pkgs where the go test command should look for the files out of this pkg will be ignored automatically. Following an example
project
|_______/pkg/web/app
|_______/pkg/web/mock -> It will be ignored.
# Command:
$go test -failfast -tags=integration -coverprofile=coverage.out -covermode=count github.com/aerogear/mobile-security-service/pkg/web/apps
However, it cannot be applied in all cases. For example, in the case of the files be mock routines of your interfaces it may not work very well because the imports which are required into the service, test and mock probably will be in a cycle and in this not allowed.
By using "_test" in the name definitions
If you would like to ignore files which are used in the tests then make sense use _test
at the end of the name. For example, my_service_mock_test.go
. The files with _test
at the end of the name will be ignored by default.
By removing from the cover file as follows
go test . -coverprofile cover.out.tmp
cat cover.out.tmp | grep -v "_generated.go" > cover.out
tool cover -func cover.out
PS.: I could not find a comment or tag which would exclude them.
答案4
得分: 10
你可以从测试中使用grep命令来筛选出那些目录。
所以,不要使用:
go test ./...
而是使用:
go test `go list ./... | grep -v ./excluded/autogen/directory/here`
另外,请确保不要添加尾部的斜杠“/”,这样不会完全起作用。
英文:
You can grep those directories out from the test.
So, instead of:
go test ./...
You do this:
go test `go list ./... | grep -v ./excluded/autogen/directory/here`
Also, make sure that you don't add a trailing /
. It doesn't work perfectly.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论