Upgrade to Pro — share decks privately, control downloads, hide ads and more …

無理なく始めるGoでのユニットテストの並行化戦略

 無理なく始めるGoでのユニットテストの並行化戦略

テストの並列実行によって、テストにかかる時間の削減が期待できます。標準パッケージのtestingには、並列実行をサポートする仕組みが用意されていますが、その導入や適切な使い方には課題があります。

例としては、以下のようなトピックです。
・一定規模以上のアプリケーションのテストをすべて対応させるのが大変なこと
・テストを並列実行することで新たなバグが発生すること
・データベースと接続するテストの並行化

このセッションでは、これらの問題を解消するために作成したツールや私が所属しているチームでの事例の紹介を交え、テストの並行化を無理なく導入・運用する方法についてお話しします。

Shoki Hata

June 02, 2023
Tweet

More Decks by Shoki Hata

Other Decks in Technology

Transcript

  1. 無理なく始める
    Goでのユニットテストの並
    行化戦略
    Shoki Hata
    Go Conference 2023 Spring
    June 2nd Fri

    View Slide

  2. Copyright Kanmu, Inc. All right reserved. 2
    畠 翔紀
    software engineer at Kanmu, Inc.
    @sho-hata
    @sho_hata_
    自己紹介

    View Slide

  3. Copyright Kanmu, Inc. All right reserved. 3
    本発表の目的
    Goのユニットテスト並行化を
    無理なく導入・運用するための情報を提供すること

    View Slide

  4. Copyright Kanmu, Inc. All right reserved. 4
    カンムという会社
    Goのユニットテスト並行化とは
    テスト並行化に伴う課題
    無理なく導入するためのツールと事例紹介
    1
    2
    3
    目次
    4

    View Slide

  5. Copyright Kanmu, Inc. All right reserved.
    カンムという会社
    5
    1

    View Slide

  6. Copyright Kanmu, Inc. All right reserved.
    ヘンなバイナリをパースして
    いる人達だな
    入社一ヶ月後
    無事自分もバイナリを読み書きするよう
    に!
    カンムという会社
    💻
    入社前(去年のGo Con) 入社後
    1

    View Slide

  7. Copyright Kanmu, Inc. All right reserved.
    Goのユニットテスト並行化とは
    2

    View Slide

  8. Copyright Kanmu, Inc. All right reserved.
    「個々のテストを独立に実行できる構成にすること」
    と本発表では定義します
    Goのユニットテスト並行化とは
    2

    View Slide

  9. Copyright Kanmu, Inc. All right reserved.
    並列・並行という用語について
    9
    2
    テキストを入れたり。テキストを入れたり。テキストを入れた
    り。テキストを入れたり。テキストを入れたり。テキストを入
    れたり。テキストを入れたり。テキストを入れたり。
    ・並行:複数の処理を独立に実行できる構成のこと
    ・並列:複数の処理を同時に実行すること
    参考: “Concurrency is not Parallelism”, Heroku’s Waza conference,Rob Pike(2012)

    View Slide

  10. Copyright Kanmu, Inc. All right reserved.
    テストを並行化すると、どのようなメリットがある?
    10
    2
    テキストを入れたり。テキストを入れたり。テキストを入れた
    り。テキストを入れたり。テキストを入れたり。テキストを入
    れたり。テキストを入れたり。テキストを入れたり。
    ・テスト時間の短縮が期待できる
    ・テスト対象/テストコードが並列実行に対応している
     ことを担保できる
    ・システムリソースの効率的な利用ができる
    ・CI/CDパイプラインを最適化できる

    View Slide

  11. Copyright Kanmu, Inc. All right reserved.
    どうやってテストは並列実行される?
    11
    2
    テストの並列実行を支える
    「go test」コマンドの実行時オプション
    -p オプション -parallel オプション
    パッケージごとの並列実行を
    サポート
    パッケージ内のテストごとの
    並列実行をサポート

    View Slide

  12. Copyright Kanmu, Inc. All right reserved.
    並列実行するパッケージ数を指定する -p オプション
    12
    2
    Aパッケージ Bパッケージ
    Aパッケージ
    Bパッケージ
    ※マルチコア環境を想定

    View Slide

  13. Copyright Kanmu, Inc. All right reserved.
    Aパッケージ
    パッケージ内のテストの並列実行数を指定する-parallel オプション
    13
    2
    TestX TestY
    Aパッケージ
    TestX
    TestY
    ※マルチコア環境を想定

    View Slide

  14. Copyright Kanmu, Inc. All right reserved.
    -parallelは「t.Parallel」を呼んでいるテスト関数のみ対象
    14
    2
    case3
    case1
    case2
    テストコード
    テスト実行
    ※マルチコア環境を想定

    View Slide

  15. Copyright Kanmu, Inc. All right reserved.
    2つのオプションはデフォルトで最適化されている
    15
    2
    ただし、-parallelオプションは
    「t.Parallel」を呼び出しているテスト関数のみ対象
    きめ細やかな最適化をするには、
    テストコードに「t.Parallel()」を埋め込む必要がある
    ※論理CPU数=環境変数GOMAXPROCSの
     デフォルト値

    View Slide

  16. Copyright Kanmu, Inc. All right reserved.
    テスト並行化に伴う課題
    3

    View Slide

  17. Copyright Kanmu, Inc. All right reserved.
    ・並行化コードを記述するのが面倒
    ・テストコード上での並行化特有の挙動
    ・データベース接続テストの並行化
    テスト並行化に伴う課題
    3

    View Slide

  18. Copyright Kanmu, Inc. All right reserved.
    課題①:並行化コードを記述するのが面倒
    18
    3
    テスト関数にt.Parallel()を
    チマチマ記述していかないといけない

    View Slide

  19. Copyright Kanmu, Inc. All right reserved.
    課題②:テストコード上での並行化特有の挙動①
    🙆 < 異なるテストレベルであ
    ればOK
    19
    3
    環境変数を設定するテストには注意が必要!
    ❌ os.Setenvの使用
    ❌ 同じテストレベルでのt.Parallelとt.Setenvの併用
    󰢁 < t.Setenv と同時に使用しては
    ならない

    View Slide

  20. Copyright Kanmu, Inc. All right reserved. 20
    3 課題②:テストコード上での並行化特有の挙動②
    テーブルドリブンテストで、ループ変数の再定義を忘れると一部の
    ケースしかテストできない!

    View Slide

  21. Copyright Kanmu, Inc. All right reserved. 21
    3 課題③:データベース接続テストの並行化
    id name
    1 “NIGHT FISHING”
    2 “KikUUiki”
    3 “DocumentaLy”
    4 “GO TO THE FUTURE”
    5 ????
    album テーブル
    並列実行
    テストA
    テストB
    あるテストの変更が他のテストケースに影響を及ぼしてしまう!
    ※マルチコア環境を想定

    View Slide

  22. Copyright Kanmu, Inc. All right reserved.
    無理なく導入するためのツールと事
    例紹介
    4

    View Slide

  23. Copyright Kanmu, Inc. All right reserved.
    ・並行化コードを記述するのが面倒!
    ・テストコード上での並行化特有の挙動
    ・データベース接続テストの並行化
    テスト並行化の導入・運用のアプローチ
    4
    人力ではなく、ツールで一気に
    テストを並行化する

    View Slide

  24. Copyright Kanmu, Inc. All right reserved.
    Goのテストコードを一気に
    並行化するツール「tparagen」

    View Slide

  25. Copyright Kanmu, Inc. All right reserved. 25
    4 tparagenの紹介
    ・https://github.com/sho-hata/tparagen
    ・対象ディレクトリ配下のGoファイルのテスト関数  に
    t.Parallelを埋め込む
    ・ソースコードを静的解析。テスト関数が並行化
     できる条件に一致していればASTをいじって埋め込む

    View Slide

  26. Copyright Kanmu, Inc. All right reserved. 26
    4 tparagenの紹介:動作

    View Slide

  27. Copyright Kanmu, Inc. All right reserved. 27
    4 tparagenの紹介:サポート機能
    ・ループ変数の再定義(tt := tt忘れ)も自動でやる
    ・t.Setenvが呼ばれているテストはスキップする
    ・-ignoreオプションで特定のディレクトリを除外

    View Slide

  28. Copyright Kanmu, Inc. All right reserved.
    並行化し忘れを防止する静的解析ツール

    View Slide

  29. Copyright Kanmu, Inc. All right reserved. 29
    4 t.Parallel し忘れを防止する静的解析ツール
    ・https://github.com/kunwardeep/paralleltest
    ・t.Parallelを呼び出していないテスト関数を報告する
    ・CIに組み込むことでレビュー時負担を軽減

    View Slide

  30. Copyright Kanmu, Inc. All right reserved.
    ・並行化コードを記述するのが面倒!
    ・テストコード上での並行化特有の挙動
    ・データベース接続テストの並行化
    データベース接続テスト並行化に対してのアプローチ
    4
    各テストケースごとに独立した
    データ操作環境にする

    View Slide

  31. Copyright Kanmu, Inc. All right reserved.
    事例紹介:Pool開発チーム

    View Slide

  32. Copyright Kanmu, Inc. All right reserved.
    データベースと接続するテストの並行化には、
    テストケースごとに独立した環境の
    構築がポイント

    View Slide

  33. Copyright Kanmu, Inc. All right reserved. 33
    4 事例紹介:テストケースごとに独立した環境の構築
    実現したいこと
    ・テスト終了後にデータ変更が残らない
    ・並列実行時に他のテストに影響を与えない
    方針
    ・テストケースごとにトランザクションを貼る
    ・テストケース終了後、ロールバック
    ・テスト対象がトランザクション処理をしている場合、
     動作をモック化

    View Slide

  34. Copyright Kanmu, Inc. All right reserved. 34
    4 事例紹介:pgtxdbを利用したテスト環境の構築
    https://github.com/achiku/pgtxdbを使う
    以下の特徴をもつDBコネクションを生成する
     ・接続が開かれるとトランザクションを開始
     ・接続が閉じるとロールバック
     ・トランザクションがモック化される
       ・BEGIN -> SAVEPOINT
       ・COMMIT -> 何もしない
       ・ROLLBACK -> ROLLBACK TO SAVEPOINT
    どうやるか?

    View Slide

  35. Copyright Kanmu, Inc. All right reserved. 35
    4 事例紹介:pgtxdbを利用したテスト環境
    テストA
    テストB
    トランザクションは互いに独立。並列実行時にも問題なし

    View Slide

  36. Copyright Kanmu, Inc. All right reserved. 36
    4 事例紹介:テスト全体のライフサイクル

    View Slide

  37. Copyright Kanmu, Inc. All right reserved.
    まとめ
    ・テスト並行化は、開発サイクルの速度向上や並列実行時の動作 担
    保が期待できる
    ・無理なく導入・運用するには、並行化コードの自動挿入ツール や静
    的解析ツールを駆使する
    ・データベースと接続するテストを並行化するには、
     テストケースごとに独立したデータ操作環境を整備する

    View Slide

  38. Copyright Kanmu, Inc. All right reserved.
    一緒に良いプロダクトを作りませんか!
    https://team.kanmu.co.jp/

    View Slide