ホームページ >バックエンド開発 >Golang >Goverall を使用して Go の os.Exit() シナリオのテスト カバレッジを 100% 達成するにはどうすればよいですか?

Goverall を使用して Go の os.Exit() シナリオのテスト カバレッジを 100% 達成するにはどうすればよいですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-12-20 04:19:13138ブラウズ

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

カバレッジ情報を含む Go os.Exit シナリオのテスト (coveralls.io/Goveralls)

os.Exit( ) は Go 開発において非常に重要です。ただし、os.Exit() を直接インターセプトすることは困難です。一般的な方法には、バイナリを再呼び出しして終了ステータスを確認することが含まれます。

このアプローチには、主に Goverall によるカバレッジ情報の欠如と、テスト バイナリの再実行の潜在的な脆弱性などの制限があります。

100% のカバレッジを達成する

これらの課題に対処するには、次のことを検討してください。テスト コードのリファクタリング:

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)
    }
}

このアプローチは、テスト コードを再利用可能な Tester インターフェイスにリファクタリングし、os.Exit() と log.Fatalf() の両方のモックを可能にします。モック オブジェクトで Exit() または Fatal() を明示的に呼び出して動作をシミュレートすることで、これらのシナリオを 100% カバーできます。

以上がGoverall を使用して Go の os.Exit() シナリオのテスト カバレッジを 100% 達成するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。