由于未导入的包,Go中存在不完整的代码覆盖率。

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

Incomplete Code Coverage in Go Due to Unimported Packages

问题

我正在了解Go语言。我尝试创建一个类似Python包的项目结构:

-src:
|- main.go
|- services:
|- pipeline.go
|- core:
|- utils.go
-test:
|- pipeline_test.go
-go.mod

然而,我在尝试计算代码覆盖率时遇到了问题。我运行了以下命令:

go test -coverprofile=coverage.out -covermode=atomic ./tests/...

但这只计算导入文件的覆盖率,即在测试文件中导入的包。未在测试中导入的包,如"main"和"core",不会被计算在内。在Python中,所有文件都会被计算在内。所以,我的问题是是否有办法扫描所有文件,即使它们在测试文件中没有被导入。

英文:

I am in the process of discovering the Go language. I tried to create a project structure that resembles a Python package:

-src:
|- main.go
|- services:
  |- pipeline.go
|- core:
  |- utils.go
-test:
|- pipeline_test.go
-go.mod

However, I am facing a problem trying to calculate code coverage. I ran the command:

go test -coverprofile=coverage.out -covermode=atomic ./tests/...

But this only calculates coverage for imported files, i.e., packages imported in the test files. Packages not imported in tests such as “main” and “core” are not being taken into account. In Python, all files are taken into account. So, my question is whether there is a solution to scan all files even if they are not imported in the test files.

答案1

得分: 1

我认为其他人可能已经在评论中提供了一些背景信息,但让我明确告诉你。在Go语言中,你不会为你没有测试的包获得代码覆盖率结果。这实际上是一个有用的特性,因为这意味着你的覆盖率结果更能预测你是否真正测试了你的代码。在其他语言中,比如C#或Python,一个包中的所有模块都会被包括在覆盖率中,这可能导致人为地得到较低的数字,因为样板代码通常不需要由单元测试覆盖,并且通常由集成测试处理。在Go中,除非你显式地为其添加测试,否则这些代码会被排除在外。这也为你作为开发者提供了一个隐含的指导:如果你正在为主模块添加测试,那么你可能应该将该代码拆分为一个可以添加测试的包。

另外,关于你的项目结构,你不应该将Python的假设应用到Go中。将你的测试放在与这些测试应该覆盖的代码相同的包中。当通过go get导入代码时,测试代码不会被包含进去,所以没有理由为测试单独创建一个包。当然,如果你有测试工具或测试支持对象需要与其他代码一起包含,你仍然可以这样做,但通常情况下,你应该将测试代码放在它应该运行的地方。

在你提供的示例中,pipeline_test.go应该移动到pipeline.go中。另外,如果你希望在utils中覆盖代码,那么你应该添加一个utils_test.go文件。

英文:

I think others have probably already provided some context in the comments, but let me tell you explicitly.

In Go, you do not get code coverage results for packages you don't test. This is actually a useful feature because it means your coverage result is more predictive of whether or not you're actually testing your code. In other languages, such as C# or Python, all modules in a package are included in coverage, which can result in artificially low numbers since boilerplate code typically doesn't need to be covered by unit tests and is normally handled by integration tests. In go, this code is excluded unless you add tests for it explicitly. This also provides an implicit guide to you, the developer: if you're adding tests to your main module, then you should probably split that code into a package that you can add tests for.

Also, about your project structure, you shouldn't apply Pythonic assumptions to Go. Put your tests in the same package as the code those tests should cover. The test code won't be included when the code is imported by doing go get so there's no reason to have a separate package for tests only. Of course, you can still do that if you have test utilities or test support objects that you do want to include with your other code, but in general you should keep test code where it's supposed to run.

In the example you provided, pipeline_test.go should be moved to pipeline.go. Also, if you have code you want covered in utils, then you should add a utils_test.go file as well.

huangapple
  • 本文由 发表于 2023年3月13日 20:31:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75721897.html
匿名

发表评论

匿名网友

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

确定