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

Go で `os.Exit()` を使用するときに 100% のテスト カバレッジを達成するにはどうすればよいですか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-25 03:04:13248ブラウズ

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

カバレッジ情報を使用した Go での os.Exit シナリオのテスト

os.Exit() が呼び出されるシナリオのテストは、Go では困難な場合があります。 os.Exit() を直接インターセプトすることは不可能であるためです。一般的なアプローチは、バイナリを再度呼び出して、その終了値を確認することです。ただし、この方法には次のような制限があります。

  • カバレッジ テスト (Coveralls/Coveralls.io) との非互換性: カバレッジ テスト フレームワークは、os.Exit() を含むテストを記録できない場合があります。不正確なカバレッジレポートにつながります。
  • 再実行の潜在的な脆弱性テスト バイナリ

課題の解決

これらの課題に対処するには、わずかなリファクタリングで 100% のカバー率を確保できます。

変更されましたコード

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

によってgo test -cover を実行すると、カバレッジ レポートに Crasher() の実行とその終了条件が正確に反映されるようになります。

他の関数への拡張

同じ手法で次のことができます。 log.Fatalf() など、内部で os.Exit() を呼び出す可能性のある他の関数をテストするために適用できます。単に関数をモックし、その適切な値をアサートするだけです動作:

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

このアプローチでは、 Go で os.Exit シナリオを包括的にテストし、テスト フレームワークから正確なカバレッジ情報を取得できます。

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

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