Heim >Backend-Entwicklung >Golang >Wie kann ich eine 100 %ige Testabdeckung erreichen, wenn ich „os.Exit()' in Go verwende?

Wie kann ich eine 100 %ige Testabdeckung erreichen, wenn ich „os.Exit()' in Go verwende?

Linda Hamilton
Linda HamiltonOriginal
2024-12-25 03:04:13252Durchsuche

How Can I Achieve 100% Test Coverage When Using `os.Exit()` in Go?

Testen von os.Exit-Szenarien in Go mit Coverage-Informationen

Testen von Szenarien, in denen os.Exit() aufgerufen wird, kann in Go eine Herausforderung sein, da ein direktes Abfangen von os.Exit() nicht möglich ist. Der übliche Ansatz besteht darin, die Binärdatei erneut aufzurufen und ihren Exit-Wert zu überprüfen. Allerdings weist diese Methode Einschränkungen auf, darunter:

  • Inkompatibilität mit Coverage Testing (Coveralls/Coveralls.io): Coverage Testing Frameworks zeichnen möglicherweise keine Tests mit os.Exit() auf. Dies führt zu ungenauen Abdeckungsberichten.
  • Potenzielle Fragilität bei der Wiederholung des Tests Binär

Die Herausforderungen meistern

Um diese Herausforderungen anzugehen, kann eine leichte Umgestaltung eine 100-prozentige Abdeckung gewährleisten:

Geändert Code

  • foo/bar.go:
package foo

import (
    "fmt"
    "os"
)

// Expose os.Exit as a variable for unit testing
var osExit = os.Exit

func Crasher() {
    fmt.Println("Going down in flames!")
    osExit(1)
}
  • foo/bar_test.go:
package foo

import (
    "testing"
    "reflect"
)

func TestCrasher(t *testing.T) {
    // Save and restore the original os.Exit() function
    oldOsExit := osExit
    defer func() { osExit = oldOsExit }()

    // Define a mock exit function that captures the exit code
    var got int
    myExit := func(code int) {
        got = code
    }

    // Set the mock exit function as os.Exit()
    osExit = myExit
    Crasher()  // Call the function being tested

    // Assert that the expected exit code was returned
    if exp := 1; got != exp {
        t.Errorf("Expected exit code: %d, got: %d", exp, got)
    }
}

Durch Ausführen von go test -cover wird der Abdeckungsbericht jetzt korrekt angezeigt spiegeln die Ausführung von Crasher() und seine Beendigungsbedingung wider.

Erweitern auf andere Funktionen

Die gleiche Technik kann angewendet werden, um andere Funktionen zu testen, die os.Exit aufrufen können () intern, wie zum Beispiel log.Fatalf(). Verspotten Sie einfach die Funktion und bestätigen Sie ihr ordnungsgemäßes Verhalten:

  • foo/bar.go:
var logFatalf = log.Fatalf

func Crasher() {
    fmt.Println("Going down in flames!")
    logFatalf("Exiting with code: %d", 1)
}
  • foo /bar_test.go:
func TestCrasher(t *testing.T) {
    // Save and restore the original log.Fatalf() function
    oldLogFatalf := logFatalf
    defer func() { logFatalf = oldLogFatalf }()

    // Define a mock fatalf function that captures the arguments
    var gotFormat string
    var gotV []interface{}
    myFatalf := func(format string, v ...interface{}) {
        gotFormat, gotV = format, v
    }

    // Set the mock fatalf function as log.Fatalf()
    logFatalf = myFatalf
    Crasher() // Call the function being tested

    // Assert that the expected format string and arguments were used
    expFormat, expV := "Exiting with code: %d", []interface{}{1}
    if gotFormat != expFormat || !reflect.DeepEqual(gotV, expV) {
        t.Error("Something went wrong")
    }
}

Mit diesem Ansatz können Sie umfassend Testen Sie os.Exit-Szenarien in Go und erhalten Sie genaue Abdeckungsinformationen von Ihren Test-Frameworks.

Das obige ist der detaillierte Inhalt vonWie kann ich eine 100 %ige Testabdeckung erreichen, wenn ich „os.Exit()' in Go verwende?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn