Golang は比較的新しいプログラミング言語ですが、開発者の間ではすでに非常に人気があります。これは、高パフォーマンスの Web サービスを構築するのに特に適しているだけでなく、信頼性とシンプルさも兼ね備えているためです。経験豊富な開発者にとって、コードを書くことは難しくありませんが、コードを書くときにプログラムの品質を確保する方法、特にコードをテストする方法が重要な問題です。
この記事では、Golang でテストする方法を探り、単体テストと統合テストについて紹介します。同時に、test や goconvey などの人気のあるテスト ライブラリについても調査します。
単体テストとは、開発者がソフトウェア内のテスト可能な最小単位をテストして、それらが適切に機能していることを確認することを指します。 Golang では、これは通常、関数とメソッドを指します。
単体テストは自動化されているため、コードをテストするにはコードを作成する必要があります。コードが実行され、テストが失敗した場合は詳細なエラー レポートが提供されます。テストは自動化されているため、手動介入なしで実行できます。
例を見てみましょう。 2 つの数値を加算する「Add()」という関数が含まれる「adder.go」というファイルがあるとします。以下は、「adder.go」の「Add()」関数をテストするために使用される「adder_test.go」の内容です。
package main import ( "testing" ) func TestAdd(t *testing.T) { expected := 4 actual := Add(2, 2) if actual != expected { t.Errorf("Add(): expected %d but got %d", expected, actual) } }
単体テストの焦点は、機能と、それが期待どおりに一貫して動作するかどうか。 「Add()」関数が 2 つの数値の合計を正しく計算するかどうかをテストすることに加えて、それが期待値と一致するかどうかもテストします。テストが失敗した場合は、探している結果を示すエラー メッセージが表示されるため、バグを簡単に見つけて修正できます。
統合テストは、複数のコンポーネントをテストしてコンポーネント間の相互作用を確認するために使用されるソフトウェア テストの種類を指します。 Web アプリケーションの場合、これには通常、Web サービスが完全に統合され、実際の環境で実行できる状態であることを確認するためのサーバーのエンドツーエンドのテストが含まれます。
Golang では、通常、統合テストには HTTP ハンドラーまたは RPC メソッドのテストが含まれます。以下は、HTTP ハンドラー関数が HTTP リクエストを正しく処理できるかどうかをテストするサンプル統合テストのコードです。
package main import ( "io/ioutil" "net/http" "net/http/httptest" "testing" ) func TestHelloHandler(t *testing.T) { req, err := http.NewRequest("GET", "/", nil) if err != nil { t.Fatal(err) } rr := httptest.NewRecorder() handler := http.HandlerFunc(HelloHandler) handler.ServeHTTP(rr, req) if status := rr.Code; status != http.StatusOK { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) } expected := "Hello, World!" if rr.Body.String() != expected { t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected) } }
統合テストでは、通常、httptest パッケージを使用してそのようなリクエストを処理します。これにより、ダミーの HTTP リクエストを作成し、それをテストしたい Web サービスに渡すことができます。
testing は Go 言語の公式テスト フレームワークです。このフレームワークは Go 言語の標準ライブラリに組み込まれているため、追加のインポートは必要ありません。単体テストと統合テストを作成するためのいくつかの単純な関数と型が提供されます。
以下は、「Square()」と呼ばれる関数をテストするテスト ライブラリのサンプル コードです。
package main import ( "testing" ) func TestSquare(t *testing.T) { cases := []struct { name string input, want int }{ { "positive", 3, 9, }, { "zero", 0, 0, }, { "negative", -2, 4, }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { got := Square(tc.input) if got != tc.want { t.Errorf("For (%d), got (%d), expected (%d)", tc.input, got, tc.want) } }) } }
さて、テスト ライブラリは、次のことを可能にする便利な関数を提供します。複数のテスト ケースで同じテスト方程式を実行します。これは t.Run() 関数で、子テストを作成し、それを親テストに関連付けます。すべてのテスト ケースで最も優れたパフォーマンスを発揮したのは Square() のどのバージョンですか? t.Run() を使用してテスト ケースごとに個別のテストを実行することで確認できます。
Goconvey は、関数やメソッドがどのように動作するかをテストし、どのテストが成功し、どのテストが失敗したかを迅速に把握できる、人気のあるサードパーティのテスト フレームワークです。
テスト ライブラリとは異なり、goconvey では関数を作成するのではなく、テキストをコピーすることでテスト コードのコンテキストを作成できます。これは、毎回同じテスト ケース コードを記述する必要がないことを意味します。 goconvey は自動的にテストを生成し、結果の概要を提供するため、使いやすくなっています。
以下は、「Greet()」という関数をテストする goconvey フレームワークのサンプル コードです。
package main import ( . "github.com/smartystreets/goconvey/convey" "testing" ) func TestGreet(t *testing.T) { Convey("Given a name and a greeting message", t, func() { name := "John" greeting := "Hello" Convey("When we pass the name and greeting to Greet()", func() { message, err := Greet(name, greeting) Convey("Then there is no error", func() { So(err, ShouldBeNil) Convey("And the message contains the name and greeting", func() { So(message, ShouldEqual, "Hello, John") }) }) }) }) }
「Run」または「Test」の代わりに「Convey」を使用していることに注意してください。 「 」は、テストするシナリオを説明します。これは、goconvey が動作駆動型の開発スタイルを使用しているためです。この例では、「Convey()」は単体テストのシナリオを記述する関数です。各シナリオは、発生する可能性のあるさまざまな状況を説明し、チェックする結果を定義します。テスト ライブラリと同様に、So/ShouldBeNil などの関数を使用して結果を変更し、期待が満たされていることを確認できます。
単体テストと統合テストは、Golang 開発プロセスの不可欠な部分です。これらは、コードが期待どおりに動作することを確認するのに役立ちます。 testing と goconvey は、関数とメソッドをテストするための高速で使いやすい関数と型を提供する 2 つの強力なライブラリです。これらのライブラリを使用したことがなく、Go でのテストについて詳しく知りたい場合は、試してみてください。
以上がgolang で人気のあるテスト ライブラリをいくつか調べてみるの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。