golang Go中的表驱动测试

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang Go中的表驱动测试相关的知识,希望对你有一定的参考价值。

func TestBusinessDoer(t *testing.T){
    cases := []struct{
        Name string
        ExpectError bool 
        Error error
    }{
        {
            Name:"test does business logic",
            ExpectError : false,
            Error : nil,
        },
        {
            Name:"test fails when dependency errors",
            ExpectError : true,
            Error : errors.New("an error"),
        },
    }

    for _,td := range cases{
        t.Run(td.Name, func (t *testing.T){
            doer := mockDoer{Error: td.Error}
            err := mything.BusinessDoer(doer) 
            if td.ExpectError && err == nil{
                t.Fatalf("expected an error but got none")
            } 
            if ! td.ExpectError && err != nil{
                t.Fatalf("did not expect an error but got one %s ", err.Error())
            }
        })
    }
}

子目录中的 Golang 测试

【中文标题】子目录中的 Golang 测试【英文标题】:Golang tests in sub-directory 【发布时间】:2013-10-12 13:46:46 【问题描述】:

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

所有的文档总是把测试代码和其他代码放在同一个地方,这在某些方面更好还是只是约定?

【问题讨论】:

注意:go test ./... 将对当前文件夹所有子文件夹运行测试。见my answer below How to `go test` all testings in my project?的可能重复 我也在想同样的事情。无法将测试放在单独的目录中,因为同一级别的主管有子目录。 【参考方案1】:

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

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

go test ./...

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

如果导入路径包含一个或多个“...”通配符,则它是一种模式,每个通配符都可以匹配任何字符串,包括空字符串和包含斜杠的字符串。

这样的模式会扩展到在 GOPATH 树中找到的所有名称与模式匹配的包目录。

作为一种特殊情况,x/... 匹配 x 以及 x 的子目录。 例如,net/... 扩展为 net 并在其子目录中打包。


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

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

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

【讨论】:

有些人可能会争辩说,不能访问私人资料是正常的黑盒测试,而且更好。关于必须限定公共符号,您始终可以导入 _ "..."。【参考方案2】:

已编辑

基于 VonC 的回答,

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

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

go test ./...

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

跑步

go test ./.../test

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

注意

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

【讨论】:

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

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

如果 go test 工具对您来说不够自动化,您可以查看 GoConvey,它有一个 Web UI,可以自动更新和运行传统 Go 测试以及GoConvey 测试(基于行为,比传统的 Go 测试更能自我记录)。

【讨论】:

GoConvey 太棒了(我期待着新的用户界面)。我在我当前的项目中使用它,例如github.com/VonC/asciidocgo/blob/master/abstractNode_test.go)。但是,go test 也可以用于子文件夹。见my answer below 没错。事实上,它可能比我对这个问题的回答更相关。【参考方案4】:

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

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

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

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

import "../models"

【讨论】:

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

以上是关于golang Go中的表驱动测试的主要内容,如果未能解决你的问题,请参考以下文章

golang 碎片整理之MySQL

Golang 入门系列 mysql数据库的使用

Go语言(Golang)数据库编程

批量MySQL插入比PHP慢2倍

每天遇到的零散知识汇聚

golang 在Go 1.7上测试multiconfig