繁体   English   中英

在Go中进行良好的单元测试

[英]Good unit testing in Go

我一直认为好的单元测试,是独立的测试。 通过'独立',我的意思是当函数'A'使用'B',并且我们测试函数'A'时,我们模拟/存根'B'以防'B'不能正常工作它不会失败'A' 。

但是当我们检查golang包的来源时,原则是不受尊重的。

例如,让我们在url包中检查url.go和url_test.go:

url.go:

func parseQuery(m Values, query string) (err error) {
    for query != "" {
    ...
    key, err1 := QueryUnescape(key)
    ...

url_test.go:

func TestParseQuery(t *testing.T) {
    for i, test := range parseTests {
        form, err := ParseQuery(test.query)
        ...

我们可以看到parseQuery使用QueryUnescape 在测试中, QueryUnescape不以任何方式存根。 因此,如果QueryUnescape工作错误, parseQuery测试将失败。

所以包的作者并不总是满足'独立'单元测试的要求。 在这种情况下不理解这个原则的原因是什么,是否有一些规则允许程序员接受这种形式的单元测试?

在python中编写独立测试后,我对编写完美测试(在golang中对代码设计有很大影响)与结果之间的平衡感到困惑。

你的问题实际上是关于在“单元测试”时定义“单元”的范围,这可能很棘手。 “单元” 并不一定意味着一个功能或结构。 这可能意味着一些功能/结构一起工作。 但它肯定意味着你不会跨越进程边界(比如使用真实的文件系统或通过网络,访问数据库等等)。 边界使用集成测试进行测试,或使用测试双精度(模拟,存根,间谍等)进行模拟。

我是GoConvey的作者, GoConvey是一个构建在内置go“测试”软件包之上的测试工具。 GoConvey有一套全面的单元测试。 项目核心的测试中,我没有编写调用每个导出和非导出函数的测试。 我用面向公众的API(导出的函数/结构)编写了测试。 该API的实现不是我的单元测试的关注,但结果是。 通过阅读一些测试,你可以看到我的意思。 我只调用一些面向公众的方法并断言结果是正确的。 实际上有很多结构和函数被调用,但是该软件包中的测试覆盖率非常高(目前为92.8% - 不像我想的那么高,但它非常好)。

对于GoConvey中的convey包,该单元是整个包装及其组件。 一开始我记得测试更精细,这使我能够更快地进入红绿重构循环。 随着代码的增长,那些较小范围的测试被更广泛的测试所取代,这些测试似乎更合适。 因此套件将随着生产代码而发展。 如果直接测试每种方法都会感觉到很多摩擦和惯性,因为如果不打破一堆测试就无法改变任何东西。

这是关于如何辨别单元测试范围的另一个有趣的总结:

http://blog.8thlight.com/uncle-bob/2014/01/27/TheChickenOrTheRoad.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM