ChatGPT解决这个技术问题 Extra ChatGPT

子目录中的 Golang 测试

我想在 Go 中创建一个包,其中包含该包的测试和示例作为子目录,以保持工作空间更清洁。这可能吗?如果可以,怎么办?

所有文档总是将测试代码与其他代码放在同一个位置,这在某种程度上更好还是只是约定?

注意:go test ./... 将对当前文件夹 所有子文件夹运行测试。请参阅my answer below
我在想同样的事。无法将测试放在单独的目录中,因为同一级别的主管有子目录。

V
VonC

请注意,您可以“递归”运行go test:您需要列出所有要测试的包

如果您位于 Go 项目的根文件夹中,请键入:

go test ./...

command go”的“Description of package lists”部分描述了“./...”符号:

如果导入路径包含一个或多个“...”通配符,则它是一种模式,每个通配符都可以匹配任何字符串,包括空字符串和包含斜杠的字符串。这样的模式扩展到所有在 GOPATH 树中找到的名称与模式匹配的包目录。作为一种特殊情况,x/... 匹配 x 以及 x 的子目录。例如,net/... 在其子目录中扩展为 net 和 packages。

如果您将 _test.go 文件保存在子文件夹中,“go test ./...”命令将能够提取它们。
但是:

您需要在导出的变量和函数(在测试中使用)前加上包的名称,以便测试文件能够访问包导出的内容。

你不会访问非导出的内容。

话虽如此,我仍然希望将 _test.go 文件保留在主源文件旁边:它更容易找到。

对于代码覆盖率:

go test -coverpkg=./... ./...

请参阅 Frédéric G. MARANDfgmarand/gocoverstats 中的“How to plot Go test coverage over time”,为 Go 项目的 CI 集成生成聚合覆盖率统计信息。

go-cover-treemap.io 也很有趣。


有些人可能会争辩说,不访问私人内容是正常的黑盒测试,而且更好。关于必须限定公共符号,您始终可以导入_“...”。
如果 (a) 您在单独的文件夹中有测试,并且 (b) 您想要测量代码覆盖率,我发现 go test ./... 不能很好地工作。由于某种原因,代码覆盖率错过了被测包
@MariaInesParnisari 有趣。我最近发现了 go-cover-treemap.ioosinet.fr/go/en/articles/plotting-go-test-coverage 也可以提供帮助。
我必须添加 -coverpkg=./... 并且它有效!
@MariaInesParnisari 你的意思是在 go test -coverpkg=./... ./... 中吗?还是只是go test -coverpkg=./...
a
avi.elkharrat

已编辑

基于 VonC 的回答,

此答案在 go1.11 中有效。尚未在较高的 go 版本中进行测试。

对于那些喜欢将测试保存在子文件夹中的人,说 test,然后运行

go test ./...

将尝试在 每个 文件夹中运行测试,即使是那些不包含任何测试的文件夹,因此在随后的非测试文件夹报告中会出现 ?

跑步

go test ./.../test

而是仅针对您的 test 文件夹,因此有一个干净的报告仅关注您的测试文件夹。

警告

请注意,使用测试子文件夹会阻止覆盖率报告计算。 Go 的原理是将测试文件留在包文件夹中。


亲爱的安娜,请解释什么不起作用?你的 go 版本是什么?你想做什么?后来才知道这个方法是不允许计算代码覆盖率的,很可惜。你是这个意思吗?
go test ./.../test 返回 go: warning: "./.../test" matched no packages // 不仅针对测试文件夹。 go 版本 go1.13 darwin/amd64
我不知道go1.13。我应该准确地说这个答案我的答案在 go1.11 中是有效的。
@Madeo,这是有道理的,因为 golang 不鼓励测试和代码的分离。异常是在以前的版本中允许它。
@avi.elkharrat 实际上我已经决定不再采用这种方法,即使我喜欢将我的测试保存在一个单独的包/文件夹中 =(
M
Matt

将您的测试与您的代码一起放在名为 file_test.go 的文件中的同一目录中,其中“file”是您正在测试的源代码文件的名称。这是惯例,我发现它在我自己的经验中是最好的。

如果 go test 工具对您来说不够自动化,您可以查看 GoConvey,它有一个网络用户界面,可以自动更新和运行传统的 Go 测试以及 GoConvey 测试 (它们基于行为,并且比传统的 Go 测试更具自我记录性)。


GoConvey 很棒(我期待着新的 UI 出现)。例如,我在当前项目中使用它,例如 github.com/VonC/asciidocgo/blob/master/abstractNode_test.go )。但是,go test 也可以用于子文件夹。见my answer below
你是对的。事实上,它可能比我对这个问题的回答更相关。
k
kiddorails

我通常不做测试,但你可以将你的文件分组到目录中并使用 import like

import "./models" 如果是一级输出
import "../models 如果是一级输出和一级输入

例如,对于:
./models/todo.go
./test/todo_test.go

要从 todo_test.go 测试 todo.go,您在 todo_test.go 中的导入将是

import "../models"


这种导入代码的方法仅适用于公开的函数。即使您明确地将它们放在同一个包中,它似乎也不像它们在同一个包中一样。所以这个解决方案并没有真正解决单元测试的问题。