去单位 - 测试致命和测试main()

时间:2016-06-19 13:19:31

标签: unit-testing go

我很擅长使用PHPUnit测试从PHP的背景进行测试。

在PHP中,我们非常热切地鼓励你需要100%的覆盖率。 在Go中,我读到的关于测试的大部分内容似乎都很少,没有引发错误的东西。

例如我的小程序:

document.innerHTML

现在在我的例子中我会遇到覆盖问题,因为单元测试中根本不涉及main()(应该怎么做?)

根本没有涵盖2 log.Fatal()。

我的问题是如何在go中完全编写我的测试?我是否以不太严格的方式进行测试而不是测试每个可能的场景,或者我可以像在php中那样进行注释 func main() { config = readConfig("config.json") } func readConfig(path string) Config { var cfg Config file, err := ioutil.ReadFile(path) if err != nil { log.Fatal(err) } err = json.Unmarshal(file, &cfg) if err != nil { log.Fatal(err) } return cfg } func TestCanReadConfig(t *testing.T) { cfg := readConfig("test_data/config.json") if cfg.Broker_pass != "test" || cfg.Broker_port != "3333" { t.Error("invalid config") } } 我可以或者应该测试主要功能吗?如果没有,我可以以某种方式从覆盖工具中忽略它吗?我应该考虑一个测试框架吗? 大多数测试教程都很好但很短,只引入了简单的测试。

1 个答案:

答案 0 :(得分:5)

这不是Go的本身,这取决于你的偏好,但是:

一个。不要测试main。 main应该只调用经过测试的代码,最好是在其他包中。为这些软件包提供尽可能多的代码覆盖率,并尽可能将main保留为微不足道。无论覆盖范围如何,这都是一种很好的做法。所以这不是一个真正的问题。

湾不要将log.Fatal用于可测试代码,只返回错误。您可以将log.Fatal保留在应用程序初始化代码中,即 - 在main :)中。因此,如果主调用readConfig并且它失败,它只会返回一个错误(非常可测试!)。 log.Fatal添加的应用程序行为是主要工作 - 配置读者不应该处理决定是否应该退出应用程序的事情,对吧?它只是读取配置并告诉您它是否成功。应用程序决定如何处理它。

所以你的代码可能如下:

func readConfig(path string) (Config, error) {
    var cfg Config
    file, err := ioutil.ReadFile(path)
    if err != nil {
        return cfg, err
    }
    err = json.Unmarshal(file, &cfg)
    if err != nil {
        return cfg, err
    }
    return cfg, nil
}

func main() {
    config, err := readConfig("config.json")
    if err != nil {
        log.Fatal(err)
    }

}

现在,您已将逻辑与应用程序行为分开,readConfig完全可以测试。