我对使用 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/