web-dev-qa-db-ja.com

golangテストを順次実行する方法は?

go testを実行すると、私の出力:

--- FAIL: TestGETSearchSuccess (0.00s)
        Location:       drivers_api_test.go:283
        Error:          Not equal: 200 (expected)
                                != 204 (actual)

--- FAIL: TestGETCOSearchSuccess (0.00s)
        Location:       drivers_api_test.go:391
        Error:          Not equal: 200 (expected)
                                != 204 (actual)

しかし、もう一度go testを実行すると、すべてのテストに合格しました。

Mysqlデータベースをリセットして初めてgo testを実行した場合にのみ、テストが失敗します。

すべてのGETリクエストについて、DBで作成されたデータがあることを確認する前に、POSTリクエストを実行します。

テストが順番に実行されることを確認する方法について誰かが私を助けてくれませんか?つまり、POSTリクエストはGETリクエストの前に実行されますか?

13
Varun Patro

テストの実行順序に依存することはできません。テストが実行される順序は定義されていません。 テストフラグ を使用すると、テストを実行から除外することができるため、テストが実行される保証はありません。

たとえば、次のコマンドは、'W'の文字を含む名前のテストのみを実行します。

go test -run W

また、一部のテスト関数が T.Parallel() メソッドを使用して並列実行に適格であるとマークしている場合、goツールはテストを並べ替えて、最初に非並列テストを実行し、次に並列テストを並列で実行します。特定の状況(-pのようなテストフラグによって制御されます)。この例は、この回答で確認できます: テストはGoで1つずつ並列で実行されますか?

テストは互いに独立である必要があります。テスト関数に前提条件がある場合、それを別のテスト関数で実行/実装することはできません。

テスト関数を実行する前に追加のタスクを実行するためのオプション:

  • テスト関数自体に置くことができます
  • _test.goファイル自体のパッケージinit()関数に入れることができます。これは、テスト関数の実行が始まる前に1回実行されます。
  • 最初に呼び出される TestMain() 関数を実装し、 M.Run() を呼び出す前に追加の設定を行って、テスト関数の実行をトリガーすることができます。 。
  • 上記のオプションを組み合わせることができます。

パッケージinit()またはTestMain()の場合、DBが初期化されているかどうか(テストレコードが挿入されているかどうか)を確認し、そうでない場合はテストレコードを挿入してください。

Go 1.7以降では、サブテストの実行順序を定義するサブテストを使用できることに注意してください。詳細については、ブログ投稿: サブテストとサブベンチマークの使用 、および testing パッケージのパッケージドキュメントをご覧ください。

31
icza

ConveyGinkgo のようなサードパーティのライブラリとは別に、プレーンなGolang 1.7では、テストを連続して実行できます。あなたはもっと読むことができます ここ

func TestFoo(t *testing.T) {
    // <setup code>
    t.Run("A=1", func(t *testing.T) { ... })
    t.Run("A=2", func(t *testing.T) { ... })
    t.Run("B=1", func(t *testing.T) { ... })
    // <tear-down code>
}

そして、あなたは条件付きでそれらを実行することができます:

go test -run ''      # Run all tests.
go test -run Foo     # Run top-level tests matching "Foo", such as "TestFooBar".
go test -run Foo/A=  # For top-level tests matching "Foo", run subtests matching "A=".
go test -run /A=1    # For all top-level tests, run subtests matching "A=1".

テストしたいREST apiからuserパッケージを取得したとします。ログインハンドラーをテストできるようにするには、作成ハンドラーをテストする必要があります。通常、これはuser_test.goにあります

type UserTests struct { Test *testing.T}
func TestRunner(t *testing.T) {

    t.Run("A=create", func(t *testing.T) {
        test:= UserTests{Test: t}
        test.TestCreateRegularUser()
        test.TestCreateConfirmedUser()
        test.TestCreateMasterUser()
        test.TestCreateUserTwice()
    })
    t.Run("A=login", func(t *testing.T) {
        test:= UserTests{Test: t}
        test.TestLoginRegularUser()
        test.TestLoginConfirmedUser()
        test.TestLoginMasterUser()
    })

}

次に、go testファイルの_test.goコマンドによって実行されないメソッドをUserTestタイプに追加できます

func (t *UserTests) TestCreateRegularUser() {
    registerRegularUser := util.TableTest{
        Method:      "POST",
        Path:        "/iot/users",
        Status:      http.StatusOK,
        Name:        "registerRegularUser",
        Description: "register Regular User has to return 200",
        Body: SerializeUser(RegularUser),
    }
    response := util.SpinSingleTableTests(t.Test, registerRegularUser)
    util.LogIfVerbose(color.BgCyan, "IOT/USERS/TEST", response)
}
12
CESCO

これを実現する最良の方法は、 here のようにTestMainを作成することです。

import (
  "testing"
  "os"
)

func TestMain(m *testing.M) {
   // Do your stuff here
   os.Exit(m.Run())
}
2
nouney