Slide 1

Slide 1 text

テストデータを貯めて 感じたこと 〜テストの健全性とコンテキストに紐づく重要度〜 Aug 2023 toRuby Presented by Yoshiori Shoji

Slide 2

Slide 2 text

2 2 @yoshiori

Slide 3

Slide 3 text

テストのデータを 貯めている 3

Slide 4

Slide 4 text

ビルドのデータや、テスト実行結果の データなどいろいろなデータを僕たち は蓄積している。 このデータをもっと活用できるので は? 4

Slide 5

Slide 5 text

5 コード一行だけ修正した。 なんで全件テストを通す必要 があるの?? “

Slide 6

Slide 6 text

あなたはちょっとした修正で影響範囲 はないと思っているかもしれない。 でも、予想外の部分でエラーが出る可 能性はある。 6

Slide 7

Slide 7 text

ではそのエラーが出る可能性は 何%ですか? 7

Slide 8

Slide 8 text

8 あー、そのテストたまに失敗 するから再実行してみて! “

Slide 9

Slide 9 text

ではそのたまに失敗する可能性は 何%ですか? 9

Slide 10

Slide 10 text

テストの健全性 10

Slide 11

Slide 11 text

テストのデータを貯めて見えてきたもの ▶ 不安定なテスト(Flaky Tests) 変更がないのに成功したり失敗したりするテスト Googleですら全体の16%はFlakyだと言っている(多すぎん?) ▶ 失敗したことがないテスト(Never Failing Tests) 今まで失敗したことがないテスト ▶ 時間掛かるテスト(Longest Tests) 純粋にコスパ悪い ▶ 良く失敗するテスト(Most Failed Tests) Flakyとは違い変更が無ければ結果は変わらないが、よく失敗する 依存関係や変数が多すぎるのかもしれない 11 11

Slide 12

Slide 12 text

このへんがテストの健全性、 つまりそのテストが有効かどうかに 繋がっているのではないか? 12

Slide 13

Slide 13 text

健全性を取り戻すための指針 より良いテストコードを書く ▶ 不安定なテスト(Flaky Tests) 不安定指数が高いもの、解決方法は様々 ▶ 失敗したことがないテスト(Never Failing Tests) 本当に必要か、他でテスト出来ていないか ▶ 時間掛かるテスト(Longest Tests) これは全てに乗算で影響しそう ▶ 良く失敗するテスト(Most Failed Tests) 依存関係や変数を見直す。テストしないで良いこともテストしていない か 13 13

Slide 14

Slide 14 text

このへんを指針に テストの健全性を保つために たまにメンテナンスしたい 14

Slide 15

Slide 15 text

コンテキストによる テストの重要性 15

Slide 16

Slide 16 text

テストの 重要度 優先度が 状況によって違う 16

Slide 17

Slide 17 text

テストの重要度?優先度?が 状況によって違う みんなで共通認識持てるように下記のよう環境を想像して ▶ 全部のテストを実行すると2時間かかる ▶ テストを実行するタイミングは2つ ▶ PullRequestレビュー時のテスト(pre-merge) ▶ いわゆるトピックブランチ ▶ リリース直前のテスト(post-merge) ▶ mainブランチとかreleaseブランチとか言われるやつ 17 17 * 気になってモヤモヤしている人に先に伝えるとスモークテストについては後でちょっとだけ触れます

Slide 18

Slide 18 text

PullRequestレビュー時のテスト テストの信頼度 < 時間 ▶ 今まで落ちたことがないテストとか実行する必要あんまりない ▶ 時間がかかるテストもコスパ悪い ▶ 単純に同じ失敗率なら10分かかるテスト1個より1分で終わ るテスト10個実行したい(失敗率とかわかるなら) ▶ 壊れやすいテストもそれなりに有用 ▶ もちろん時間との兼ね合いだけど ▶ 不安定なテスト(Flaky Tests)はノイズ 18 18

Slide 19

Slide 19 text

リリース直前のテスト テストの信頼度 > 時間 ▶ 100%の信頼度が欲しい ▶ 全てのテストを実行したい気持ちが強い ▶ ちょっと政治的だけどテストしたという事実が重要なことも ▶ 例: 金融系なのでお客さんの環境に出す前に確認をしたかが大事 ▶ 不安定なテスト(Flaky Tests)はノイズ 19 19

Slide 20

Slide 20 text

という環境で PR時には実行したくないけど リリース時には実行して欲しいテスト とかある 20

Slide 21

Slide 21 text

例: DBのRead-Write splittingのテスト ▶ 特性 ▶ このテストは最初にマージされてから失敗したことがない ▶ 実際のDBを使うので1テストあたりにかかる時間は多い 21 21

Slide 22

Slide 22 text

例: DBのRead-Write splittingのテスト 関係なさそうな場所の修正のとき例えば文言修正のPR ▶ PullRequestレビュー時のテスト ▶ 実行しなくていい、数秒で終わるならまだしも時間のかか るテストだしコケたこと無いし時間の無駄 ▶ リリース直前のテスト ▶ 結構ロジックの根っこ部分なので必ずテストしておきたい ▶ 壊れていない事を確認したい 22 22

Slide 23

Slide 23 text

例: DBのRead-Write splittingのテスト 関係ある場所の修正のとき例えばsplitのロジック変更 ▶ PullRequestレビュー時のテスト ▶ めっちゃ重要 ▶ ただ、ローカルで絶対テストしてからpushしてる? ▶ だったらもしかしてPRでは実行しなくてよい? ▶ まぁ、流石に実行したい。人はミスするしローカルで実は違う奴テスト実行してた とかあるある ▶ シェルの履歴から実行してて実は違うの実行してたとか 23 23

Slide 24

Slide 24 text

100%コケるテストはわかりやすく邪魔 だけど 100%成功するテストもある意味ノイズ になりうる (今の例の関連していないPRのように) 24

Slide 25

Slide 25 text

昔から所謂スモークテストとかサニ ティテストとかの概念はあった。 受け入れテストの前に浅くとか一部と かテストしたい。ので人が選別して一 部をテストしていた。 25

Slide 26

Slide 26 text

ここからCM 26

Slide 27

Slide 27 text

もっとハッキリ言うと 失敗するテストだけ実行したい -> それLaunchableで出来るよ 27 広告

Slide 28

Slide 28 text

失敗するテストだけ 実行するは誇大広告 だけど、失敗率の高 いテストを実行でき るので例えば10分テ ストすれば97%の信 頼度ですよとか選択 できる 28 広告

Slide 29

Slide 29 text

CMおわり 29

Slide 30

Slide 30 text

どのようなテストが 良いテストなのか? (ここからまだ答えなく悩んでる話) 30

Slide 31

Slide 31 text

さて、状況によって優先度が違うのは 理解した。 だんだんテスト書くときも 色々なことを意識するようになった。 31

Slide 32

Slide 32 text

例えばよく失敗するテスト ▶ 不安定なテスト(FlakyTest)とは違う ▶ 何かしらの変更がないと結果は変わらない ▶ Flakyなテストは同じコミットハッシュで成功したり失敗し たりする ▶ 依存関係が多いテストとも言える ▶ ちょっと変更するだけで失敗する ▶ テストに関連する変数が多い 32 32

Slide 33

Slide 33 text

これは良いテスト? 33

Slide 34

Slide 34 text

依存関係の大小への個人的想い 依存関係の多いテスト ->基本嫌い 依存関係の少ないテスト->素晴らしい 34

Slide 35

Slide 35 text

依存関係の少ないテストは素晴らしい ▶ Unit test とか ▶ 一つのことをテストする大事 ▶ きちんと設計すれば依存少なく書ける ▶ 美しいと感じる ▶ しかし別の場所を修正しているときは重要度低い ▶ その場所を弄っているとき以外は無駄なテストになりがち ▶ 依存少なく書いていれば 35 35

Slide 36

Slide 36 text

例: メールアドレスをマスクする処理のロジックのテスト ▶ y*****[email protected] 的なやつ ▶ 最初の実装時には絶対に書きたい ▶ 例えば1文字の時とか2文字のときとかの境界値のテスト ▶ 不安を元に書くテスト ▶ 所謂 Development Test ▶ ここ以外を弄っているときはまず壊れない ▶ 他の部分の修正のPRでは極論実行する価値がない 36 36

Slide 37

Slide 37 text

依存関係がそれなりにあるテスト ▶ もちろんすぐに壊れるようなテストはメンテコスト高すぎなので論外 ▶ なんとなく俺の中ではRailsで言うController testくらいのやつ ▶ postアクセスしてアサインされている変数が適切かとか ▶ System testになるとちょっと壊れやすすぎな気がする ▶ 動作確認が面倒くさいから書くことが多い ▶ フォームの複数の項目により処理が色々変わるとか ▶ つまり変数が多い ▶ 毎回ブラウザでポチポチが面倒くさいからテスト書く 37 37

Slide 38

Slide 38 text

依存関係がそれなりにあるテスト ▶ どちらにしても僕個人としてはあまり美しさを感じない ▶ 不安ではなく面倒くさいから書くテスト ▶ ユーザー影響ある時に適切に失敗するので役に立つ ▶ これは結構PullRequestのときも重要度高い ▶ もちろんリリース直前のときも重要度高い 38 38

Slide 39

Slide 39 text

これは良いテスト? な気もする 39

Slide 40

Slide 40 text

何となく僕の中でモヤモヤと下記が成り立ちつつある ▶ 不安を元に書くテスト ▶ 依存関係少ない ▶ 美しいと感じる ▶ 動作確認めんどくさいから書いたテスト ▶ 依存関係多め、変数多め ▶ 美しくないと感じる ▶ でもPullRequestの時とかは特に後者のほうが重要なことが多い ▶ 美しいと思ってないほうが重要なのでちょっと嫌悪感 ▶ まぁしょうがないんだけど 40 40

Slide 41

Slide 41 text

でもController Test落ちた時に 原因箇所のUnit Testなかったら ムカつく!!!! 41

Slide 42

Slide 42 text

さて 42

Slide 43

Slide 43 text

テストのデータを集めて色々やるの楽しい ▶ データを見るようになったことで今までテスト書いていた時に比べて 重要度とか依存度とかを意識するようになった ▶ 書いたテストの健全性的な側面 ▶ 時間とともに変わってくる ▶ 昔はそうでなかったものがFlakyになってきたり ▶ 見える化はとても良い ▶ それLaunchableで(ry ▶ 色々妄想捗る 43 43

Slide 44

Slide 44 text

テストのデータを集めて色々やるの楽しい ▶ 一方でまだモヤモヤ言語化出来ていないことも多い ▶ ピーキーなテストと適切に落ちるテストの境目とか ▶ あまり美しくないと思っているテストのほうが 俺のことを助けているという事実とか ▶ 開発時には美しいテスト助かってるのよ!! 44 44

Slide 45

Slide 45 text

オチはなし! モヤモヤを吐き出しに来たので! 45

Slide 46

Slide 46 text

最後に ▶ やっぱりSoftware TestingとかDevelopment Test とか楽しい ▶ 今は趣味と仕事が一致していてとても楽しい ▶ 一方で会社の業務と繋がってるとこういう話を出来る場 所が少ない ▶ 会社の話が出るならスポンサーセッションでとか言われる ▶ ということで今日は本当にありがとうございます!!! 46 46

Slide 47

Slide 47 text

Thank you! 47