Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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 あるテストの変更が他のテストケースに影響を及ぼしてしまう! ※マルチコア環境を想定

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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