如何为REST服务生成代码覆盖率

时间:2019-09-18 10:22:30

标签: go code-coverage

我想获得用Go编写的REST服务的测试范围。我正在通过goroutine生成REST服务,然后使用rest客户端发出HTTP请求,并查看HTTP响应。 测试成功通过,但是go test -cover返回0%的测试覆盖率。 有没有一种方法可以获取go lang REST服务内部使用的所有软件包的实际测试范围。

我的测试文件: main_test.go

import (
    "testing"
)

// Test started when the test binary is started. Only calls main.
func TestSystem(t *testing.T) {
    go main()    // Spinning up the go lang REST server in a separate go routine.
    http.Post("https://localhost/do_something")
}

我的输出:

go test -cover  main_test.go
ok      command-line-arguments  0.668s  coverage: 0.0% of statements 

3 个答案:

答案 0 :(得分:1)

前言

这不是涵盖所有情况的完整答案。

试图解释从OP解释中如何实现零覆盖。

测试自己

  

测试成功通过,但是进行测试-cover返回0%的测试覆盖率。

  1. 使用go main()功能内的Test开始服务
  2. 尝试http.Post进行服务而不检查错误,并且该响应不是nil
  3. 测试过程中没有惊慌,所以测试通过了

测试中的问题

  1. 不能保证在尝试http.Post之前实际上已经启动了服务
  2. 未检查http.Post的结果

第一个问题:

  • 不良/肮脏解决方案:在time.Sleep之后添加go main()
  • 良好/干净的解决方案:启动带有某种信号/监控的服务循环的仪器服务

第二个问题:

看看这种测试功能:

func TestPost(t *testing.T) {
    var b bytes.Buffer
    http.Post("http:/inexistent.com/inexistent-url", "", &b)
    t.Log("No problems!")
}

此测试将始终通过。因为它仅测试不存在的紧急情况。

要使此测试更正确:

func TestPost(t *testing.T) {
    var b bytes.Buffer
    if _, err:= http.Post("http:/inexistent.com/inexistent-url", "", &b); err!=nil{
    t.Errorf("http.Post : %v", err)
}

提案

  1. 检查http.Post结果
  2. 检查测试服务是否已真正启动

答案 1 :(得分:1)

非常感谢您的回复。 我可以通过-coverpkg获得覆盖。 不确定到底是什么真正解决了以下问题,如@Flimzy所建议的对我有用的一些更改 1.将REST服务器初始化代码从main移到了功能。然后在测试用例中,在go例程中启动REST服务器,并通过向通道发送消息来优雅地终止它

    channel := make(chan error) // create a channel will listen for error
    go func(channel chan error) {
        inithandler.InitRestServer(channel, )
        _ = <-channel // terminate the channel
    }(channel)
http.Post("https://localhost/do_something") // call the endpoint and resp verification
.
.
channel <- errors.New("stop")

使用-coverpkg触发测试

go test main_test.go -cover -coverpkg ./...

答案 2 :(得分:-2)

不管是什么根本原因,我都认为您的一般方法存在问题。

我建议您在此处测试的某些内容不是您的代码,也不要打扰。您不需要实际上测试http协议和http包,对吗?

因此,我过去处理此问题的方式是将我想测试的有意义的代码从http处理函数中分解出来。 http处理程序仅应负责验证输入,调用 actual 业务逻辑,然后格式化输出。

以这种方式分解代码后,您可以直接从测试中调用有意义的函数。您的http处理函数应该非常简单,以至于没有地方可以隐瞒错误。

不要寻求100%的测试覆盖率。测试重要的事情。