Home  >  Article  >  Backend Development  >  How to achieve comprehensive coverage profiles without blind spots for functional tests interacting with a compiled Go binary?

How to achieve comprehensive coverage profiles without blind spots for functional tests interacting with a compiled Go binary?

Susan Sarandon
Susan SarandonOriginal
2024-10-25 07:14:29523browse

How to achieve comprehensive coverage profiles without blind spots for functional tests interacting with a compiled Go binary?

Showing Coverage of Functional Tests Without Blind Spots

Problem:

In order to generate coverage profiles for functional tests written in a non-Go language that interact with a compiled Go binary, the main_test.go file includes a Test_main function that modifies the main() method to send the exit code to a channel. However, the if flag.Lookup("test.coverprofile") != nil condition in the exit() function creates a blind spot in the coverage results, as os.Exit(code) may never be executed when a coverage profile is requested.

Solution:

To write coverage profiles without blind spots, it is recommended to exclude the main.go file from testing. This can be accomplished using build tags by adding the line // build !test to the top of the main.go file. This will instruct the Go compiler to ignore the file during test builds.

The following is a modified version of the example code that incorporates this approach:

<code class="go">// dofunc.go
package main

import (
    "fmt"
    "math/rand"
    "time"
)

var seed int64 = time.Now().UTC().UnixNano()

func doFunc() int {
    rand.Seed(seed)
    var code int
    for {
        i := rand.Int()
        fmt.Println(i)
        if i%3 == 0 {
            code = 0
            break
        }
        if i%2 == 0 {
            fmt.Println("status 1")
            code = 1
            break
        }
        time.Sleep(time.Second)
    }
    return code
}

// main.go
//+build !test
package main

import "os"

func main() {
    os.Exit(doFunc())
}

// dofunc_test.go
package main

import (
    "testing"
    "flag"
    "os"
)

var exitCode int

func TestMain(m *testing.M) {
    flag.Parse()
    code := m.Run()
    os.Exit(code)
}

func TestDoFuncErrorCodeZero(t *testing.T) {
    seed = 2

    if code := doFunc(); code != 0 {
        t.Fail()
    }
}

func TestDoFuncErrorCodeOne(t *testing.T) {
    seed = 3

    if code := doFunc(); code != 1 {
        t.Fail()
    }
}</code>

Usage:

  1. Build the coverage binary with tags: go test -c -coverpkg=. -o myProgram -tags test
  2. Run the coverage binary: ./myProgram -test.coverprofile=/tmp/profile
  3. Generate the coverage HTML report: go tool cover -html /tmp/profile -o /tmp/profile.html

By excluding main.go from testing, the exit() function is no longer part of the coverage analysis, and the coverage profiles will accurately reflect the behavior of the functional tests.

The above is the detailed content of How to achieve comprehensive coverage profiles without blind spots for functional tests interacting with a compiled Go binary?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn