Abdeckung von Funktionstests ohne blinde Flecken anzeigen

Ich habe einen Produktions-Golang-Code und Funktionstests dafür, die nicht in Golang geschrieben sind. Funktionstests führen kompilierte Binärdateien aus. Eine sehr vereinfachte Version meines Produktionscodes finden Sie hier:main.go:

package main

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

func main() {
    rand.Seed(time.Now().UTC().UnixNano())
    for {
        i := rand.Int()
        fmt.Println(i)
        if i%3 == 0 {
            os.Exit(0)
        }
        if i%2 == 0 {
            os.Exit(1)
        }
        time.Sleep(time.Second)
    }
}

Ich möchte ein Abdeckungsprofil für meine Funktionstests erstellen. Dazu füge ich @ hinmain_test.go Datei mit Inhalt:

package main

import (
    "os"
    "testing"
)

var exitCode int

func Test_main(t *testing.T) {
    go main()
    exitCode = <-exitCh
}

func TestMain(m *testing.M) {
    m.Run()
    // can exit because cover profile is already written
    os.Exit(exitCode)
}

Und änderemain.go:

package main

import (
    "flag"
    "fmt"
    "math/rand"
    "os"
    "runtime"
    "time"
)

var exitCh chan int = make(chan int)

func main() {
    rand.Seed(time.Now().UTC().UnixNano())
    for {
        i := rand.Int()
        fmt.Println(i)
        if i%3 == 0 {
            exit(0)
        }
        if i%2 == 0 {
            fmt.Println("status 1")
            exit(1)
        }
        time.Sleep(time.Second)
    }
}

func exit(code int) {
    if flag.Lookup("test.coverprofile") != nil {
        exitCh <- code
        runtime.Goexit()
    } else {
        os.Exit(code)
    }
}

Dann erstelle ich Coverage Binary:

go test -c -coverpkg=.  -o myProgram

Dann führen meine Funktionstests diese Coverage-Binärdatei wie folgt aus:

./myProgram -test.coverprofile=/tmp/profile
6507374435908599516
PASS
coverage: 64.3% of statements in .

Und ich erstelle eine HTML-Ausgabe mit Abdeckung:

$ go tool cover -html /tmp/profile -o /tmp/profile.html
$ open /tmp/profile.html

Proble

Methodeexit wird aufgrund der Bedingung @ niemals eine 100% ige Abdeckung anzeigif flag.Lookup("test.coverprofile") != nil. Also lineos.Exit(code) ist ein bisschen blinder Fleck für meine Abdeckungsergebnisse, obwohl in der Tat Funktionstests in dieser Zeile angezeigt werden und diese Zeile als grün angezeigt werden sollte.

uf der anderen Seite, wenn ich Zustand entfernenif flag.Lookup("test.coverprofile") != nil, die Linieos.Exit(code) beendet meine Binärdatei, ohne ein Abdeckungsprofil zu erstellen.

Wi umschreibenexit() und vielleichtmain_test.go um Berichterstattung zu zeigenohne blinde Flecken?

ie erste Lösung, die in den Sinn kommt, isttime.Sleep():

func exit(code int) {
        exitCh <- code
        time.Sleep(time.Second) // wait some time to let coverprofile be written
        os.Exit(code)
    }
}

Aber es ist nicht sehr gut, da der Produktionscode vor dem Beenden langsamer wird.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage