Heim >Backend-Entwicklung >Golang >Wie kann ich mit Goveralls eine 100-prozentige Testabdeckung für die os.Exit()-Szenarien von Go erreichen?

Wie kann ich mit Goveralls eine 100-prozentige Testabdeckung für die os.Exit()-Szenarien von Go erreichen?

Barbara Streisand
Barbara StreisandOriginal
2024-12-20 04:19:13137Durchsuche

How Can I Achieve 100% Test Coverage for Go's os.Exit() Scenarios with Goveralls?

Testen von Go os.Exit-Szenarien mit Abdeckungsinformationen (coveralls.io/Goveralls)

Die Möglichkeit, Szenarien mit os.Exit( ) ist in der Go-Entwicklung von entscheidender Bedeutung. Es ist jedoch schwierig, os.Exit() direkt abzufangen. Eine gängige Methode besteht darin, die Binärdatei erneut aufzurufen und den Exit-Status zu überprüfen.

Dieser Ansatz weist Einschränkungen auf, vor allem das Fehlen von Abdeckungsinformationen mit Goveralls und die potenzielle Fragilität einer erneuten Ausführung der Testbinärdatei.

Eine 100-prozentige Abdeckung erreichen

Um diese Herausforderungen anzugehen, sollten Sie eine Umgestaltung der Tests in Betracht ziehen Code:

package foo

import (
    "fmt"
    "io"
    "log"
    "os"
    "testing"
)

var (
    osExit = os.Exit
    logFatalf = log.Fatalf
)

// Tester interface for mocking os.Exit() and log.Fatalf()
type Tester interface {
    Fatal(string, ...interface{})
    Exit(int)
}

type realTester struct{}

func (r realTester) Fatal(s string, v ...interface{}) {
    log.Fatalf(s, v...)
}

func (r realTester) Exit(code int) {
    os.Exit(code)
}

func Crasher() {
    fmt.Print("Going down in flames!")
    logFatalf("Exiting with code: %d", 1)
}

// TestCrasher simulates os.Exit() and log.Fatalf()
func TestCrasher(t *testing.T) {
    tests := []struct {
        name string
        f    func(t *testing.T, original Tester, tester *mockTester)
    }{
        {"Test os.Exit()", func(t *testing.T, orig, test *mockTester) {
            orig.Exit(1)
            if test.exitCode != 1 {
                t.Errorf("expected exit code 1, got %d", test.exitCode)
            }
        }},
        {"Test log.Fatalf()", func(t *testing.T, orig, test *mockTester) {
            orig.Fatalf("Exiting after a test failure")
            if test.format != "Exiting after a test failure" {
                t.Errorf("expected format \"Exiting after a test failure\", got %s", test.format)
            }
        }},
    }

    for _, test := range tests {
        t.Run(test.name, func(t *testing.T) {
            var orig Tester = realTester{}
            var mr mockTester

            test.f(t, orig, &mr)

            mr.Verify()
        })
    }
}

// Mock tester simulates os.Exit() and log.Fatalf()
type mockTester struct {
    format    string
    values    []interface{}
    exitCode  int
    exitCalls int
}

func (m *mockTester) Fatal(s string, v ...interface{}) {
    m.format = s
    m.values = v
    m.exit()
}

func (m *mockTester) Exit(code int) {
    m.exitCode = code
    m.exit()
}

func (m *mockTester) exit() {
    m.exitCalls++
}

// Verify checks that mockTester was called appropriately
func (m *mockTester) Verify() {
    if m.exitCalls != 1 {
        panic("expected 1 call to Exit() or Fatal(), got %d", m.exitCalls)
    }
}

Dieser Ansatz wandelt den Testcode in eine wiederverwendbare Tester-Schnittstelle um und ermöglicht das Verspotten von os.Exit() und log.Fatalf(). Durch den expliziten Aufruf von Exit() oder Fatal() im Mock-Objekt und die Simulation des Verhaltens können Sie eine 100-prozentige Abdeckung dieser Szenarien erreichen.

Das obige ist der detaillierte Inhalt vonWie kann ich mit Goveralls eine 100-prozentige Testabdeckung für die os.Exit()-Szenarien von Go erreichen?. 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