unit-testing - Go 单元测试 fatal error 并测试 main()

标签 unit-testing go

我对使用 PHPUnit 测试进行 PHP 测试非常陌生。

在 PHP 中,人们几乎都相信您需要 100% 的覆盖率。 在 Go 中,我读到的有关测试的大多数内容似乎都很少,没有诸如引发错误之类的内容。

比如我的小程序:

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")
    }
}

现在在我的示例中,我会遇到覆盖问题,因为单元测试中根本没有覆盖 main() (应该如何?)

并且 2 个 log.Fatal() 根本没有被覆盖。

我的问题是如何在 go 中准确地编写测试?我是否以不太严格的方式进行操作,而不是测试所有可能的场景,或者我可以像在 php 中那样进行注释吗 @expectedException\InvalidArgumentException 我可以或者应该测试主要功能吗?如果不是,我可以通过某种方式从覆盖工具中忽略它吗?我应该考虑测试框架吗? 大多数测试教程都很好,但很短,只介绍简单的测试。

最佳答案

这本身不是 Go 的事情,这取决于您的偏好,但是:

a.不要测试 main。 main 应该只调用经过测试的代码,最好是在其他包中。为这些包提供尽可能多的代码覆盖率,并让 main 尽可能简单。无论覆盖范围如何,这都是一个很好的做法。所以这并不是什么问题。

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

所以你的代码可能看起来像:

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 完全可测试。

关于unit-testing - Go 单元测试 fatal error 并测试 main(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37907679/

相关文章:

javascript - 使用 ava 测试访问全局命名空间

string - 如何用随机替换词有效地替换字符串中的词?

mongodb - 无法从 `[]string` 断言类型 `[]interface{}`

go - time.Parse in Go 具有不同的小数秒长度

unit-testing - 我应该为每个断言创建一个新的测试方法吗?

javascript - mocha done() 和 async await 的矛盾问题

php - 使用 Simpletest 对 CodeIgniter 进行单元测试 - 很少的测试

c++ - 代码生成工具测试

mysql - GoLang 的配置返回 "non-name"错误

go - 在任何 : 中找不到包 "golang.org/x/net/context"