正确的包命名用于使用Go语言进行测试

Dan*_*Dan 85 unit-testing go

我在Go中看到了几种不同的测试包命名策略,并想知道每种方法的优缺点以及我应该使用哪种方法.

策略1:

文件名:github.com/user/myfunc.go

package myfunc
Run Code Online (Sandbox Code Playgroud)

测试文件名:github.com/user/myfunc_test.go

package myfunc
Run Code Online (Sandbox Code Playgroud)

有关示例,请参阅bzip2.

策略2:

文件名:github.com/user/myfunc.go

package myfunc
Run Code Online (Sandbox Code Playgroud)

测试文件名:github.com/user/myfunc_test.go

package myfunc_test

import (
    "github.com/user/myfunc"
)
Run Code Online (Sandbox Code Playgroud)

有关示例,请参见电线.

策略3:

文件名:github.com/user/myfunc.go

package myfunc
Run Code Online (Sandbox Code Playgroud)

测试文件名:github.com/user/myfunc_test.go

package myfunc_test

import (
    . "myfunc"
)
Run Code Online (Sandbox Code Playgroud)

请参阅字符串以获取示例.

Go标准库似乎使用了策略1和2的混合.我应该使用哪三个?这是一个痛苦附加package *_test到我的测试包,因为它意味着我无法测试我的包私有方法,但也许有一个我不知道的隐藏的优势?

Mat*_*kin 105

您列出的三种策略之间的根本区别在于测试代码是否与被测代码位于同一个包中.使用的决定package myfuncpackage myfunc_test在测试文件取决于你是否要执行白盒黑箱测试.

在项目中使用这两种方法没有任何问题.例如,你可以拥有myfunc_whitebox_test.gomyfunx_blackbox_test.go.

测试代码包比较

  • 黑盒测试:使用package myfunc_test,这将确保您只使用导出的标识符.
  • 白盒测试:使用package myfunc以便您可以访问未导出的标识符.适用于需要访问非导出变量,函数和方法的单元测试.

问题所列策略的比较

  • 策略1:文件myfunc_test.go使用package myfunc- 在这种情况下,测试代码myfunc_test.go将与正在测试的代码位于同一个包中myfunc.go,myfunc在本例中.
  • 策略2:文件myfunc_test.go使用package myfunc_test- 在这种情况下,myfunc_test.go"中的测试代码将被编译为单独的包,然后链接并与主测试二进制文件一起运行." [来源:test.go源代码中的第58-59行]
  • 策略3:文件myfunc_test.go使用package myfunc_testmyfunc使用点表示法导入- 这是策略2的变体,但使用点表示法导入myfunc.

  • 应该注意的是,使用策略 1 也会将带有 `_test.go` 的文件与正在测试的包分开(与策略 2 的行为相同)。这似乎没有记录在 https://github.com/golang/go/issues/15315 中 (2认同)
  • 我分叉了一个包并进行了更改,现在我的测试都试图导入原始存储库而不是我的分叉包。使用策略 3,我不必将“github.com/original/link”更改为“github.com/my/fork”,因为它只是引用“.” 反而。 (2认同)

mdw*_*ott 18

这取决于您的测试范围.高级测试(集成,验收等)应该放在一个单独的包中,以确保您通过导出的API使用该包.

如果你有一个包含大量内部组件的大型软件包需要进行测试,那么请使用相同的软件包进行测试.但这不是邀请您的测试访问任何私有状态.这将使重构成为一场噩梦.当我在go中编写结构时,我经常实现接口.我从测试中调用的是那些接口方法,而不是单独的所有辅助方法/函数.


gue*_*fey 15

您应该尽可能使用策略1.您可以使用特殊foo_test包名称来避免导入周期,但这主要是因为标准库可以使用相同的机制进行测试.例如,strings由于testing程序包依赖,因此无法使用策略1进行测试strings.正如您所说,使用策略2或3,您无权访问程序包的私有标识符,因此除非必须,否则通常最好不要使用它.

  • 如何在测试中访问私有标识符并不是一种美德? (8认同)
  • 根据良好的测试实践,您不会测试代码工件的内部实现细节;做儿子,是一种_代码味道_ (3认同)
  • 它并不总是代码味道。您可以使用最适合您的任何策略。 (2认同)