Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

テストオートメーションと末長くお付き合いするための17のこと

eiji.ienaga
September 28, 2024
370

 テストオートメーションと末長くお付き合いするための17のこと

XP祭り2024年の資料
https://confengine.com/conferences/xp2024/proposal/20309/n

関連ブログに関してはこちらのリンク集から
https://www.agile-studio.jp/post/twop-tdd

eiji.ienaga

September 28, 2024
Tweet

More Decks by eiji.ienaga

Transcript

  1. テストオートメーションの目的 ① 仕様をまとめるとき 期待する振る舞い(仕様の具体例)の会話を密にして理解を合わせるため Tests as Documentation, Tests as Specification、Expressive

    Tests, etc ② コード修正し、動作確認するとき 問題箇所をすぐ特定できるようにするため、セーフティネット、バグよけのため Defect Localization、 Tests as Safety Net, Bug Repellent, etc ③ 新たな要望が後から出てきても 自信を持って修正し、リリースし続けるため。変更に強いテスト! Robust Test, Simple Tests, Separation of Concerns, etc 参考にしつつ大きく再編成 ピックアップ
  2. ① 仕様をまとめるとき 期待する振る舞い(仕様の具体例)の会話を密にして理解を合わせるため Tests as Documentation, Tests as Specification、Expressive Tests,

    etc… ② コード修正し、動作確認するとき 問題箇所をすぐ特定できるようにするため。セーフティネット、バグよけのため Defect Localization、 Tests as Safety Net, Bug Repellent, ③ 新たな要望が後から出てきても 自信を持って修正し、リリースし続けるため。変更に強いテスト! Robust Test, Simple Tests, Separation of Concerns, etc.. テストオートメーションの目的 参考にしつつ大きく再編成 ピックアップ
  3. 複雑なドメインロジックの問題を シンプルなユニットテストを使って 紐解く 本当に大事な問題箇所をすぐに特定できる大事 UI バックエンド サービスA バックエンド サービスB 手動やEnd2Endテストに頼りすぎると、Slow

    TestやFlaky Testなどなど別の問題に 足を引っ張られ、ロジックの核心に辿り着けない 手動・E2E テスト 測定結果から ABC判定 ユニット テスト ネットワーク 通信エラーでたまに失敗 テストしたい 前提データの 準備操作が大変 非同期処理の要因 で、たまに失敗
  4. ① 仕様をまとめるとき 期待する振る舞い(仕様の具体例)の会話を密にして理解を合わせるため Tests as Documentation, Tests as Specification、Expressive Tests,

    etc ② コード修正し、動作確認するとき 問題箇所をすぐ特定できるようにするため、セーフティネット、バグよけのため Defect Localization、 Tests as Safety Net, Bug Repellent, etc ③ 新たな要望が後から出てきても 自信を持って修正し、リリースし続けるため。変更に強いテスト! Robust Test, Simple Tests, Separation of Concerns, etc.. テストオートメーションの目的 参考にしつつ大きく再編成 ピックアップ
  5. Obscure Test(曖昧なテスト) 事象 • テストコードを読んでも、すぐに理解できない 放置すると • 読んで理解するまでの時間がかかり、メンテナンスコスト高&ストレスUP • ドメインエキスパートとのコミュニケーション不全

    • 仕様の抜け漏れや矛盾に気づかずバグをリリースしてしまう 典型的な原因例 • 1つのテストメソッドに多数のテストケースを熱心に書きすぎ • テスト結果に無関係な情報が記載されすぎて、Arrangeのどの部分がAssertの結果に 関係しているかわからない • 逆に謎の準備メソッドや巨大な共通フィクスチャが覆い隠しすぎて、Assertの結果 になる理由が読んでわからない • モジュールの仕様や振る舞いではなく、実装詳細に依存したテスト https://www.agile-studio.jp/post/twop-tdd-obscure-test
  6. Fragile Test(脆いテスト) 事象 • 機能修正やリファクタリングの際に多数のテストが意図せず失敗し、修復を強いられる 放置すると • 意図せず失敗したテスト修復に時間がかかり、 メンテナンスコスト高でストレスフルな開発(コスパ&タイパ&ウェルパ悪化) •

    リファクタリングを妨げるテストで、だんだんと負債を増やし、修正の自信を喪失 典型的な原因例 • テストコードが実装詳細に密結合。インタフェースと実装の分離が不十分 • =>UI のEnd2Endの場合は、テストコードがUIの実装詳細に触れすぎる • =>モック利用の場合は、モックがテスト対象の詳細に触れすぎ • 複数のテストケースが共通のフィクスチャ依存で互いに影響し合う。テストの独立性不足 • etc https://www.agile-studio.jp/post/twop-tdd-fragile-test
  7. Erratic Test/Flaky Test(信頼不能テスト) 事象 • コード以外の要因でテスト結果が非決定・不安定(RedにもGreenにもなってしまう) 放置すると • テストのリトライや失敗原因の特定に時間がかかり、メンテナンスコスト高でストレスフルな 開発環境

    (コスパ&タイパ&ウェルパ悪化) • チーム内外でテストに対する信頼性が喪失してしまう由々しき事態に! 原因 • ネットワークや外部サービスなど環境依存で結果が変わる • 非同期処理の箇所で、待ち時間などで結果が変わる • 並列処理の箇所で、実行タイミングなどで結果が変わる • 複数のテストで共有されたデータやファイルが干渉し合って、 テストの実行順序によっては結果が変わる • 実行の時間やランダム要素で結果が変わる • リソース枯渇のタイミングで結果が変わる • etc…
  8. 日頃の事前予防や発生してからの対策は 日頃のFlaky Testの予防策としては • 信頼不能テストを招きがちなEnd2Endテスト(Largeテスト)を減らす。 ネットワーク通信や外部サービスや非同期処理や共有されたファイルアクセ スなしでテストする範囲を増やす。 • ランダム要素、実行時間など信頼不能につながる箇所に強く依存したコード 減らし、繰り返しテスト可能になるように設計改善

    • DBアクセスありのMedium Testの作戦を取る場合は、トランザクションロー ルバック、不変のFixture、データorスキーマorデータベースを隔離して独 立性を上げる、適切な知識をもって対策を施す 発生してからは、 • 実行結果が不安定なテストを隔離や混入タイミングを調べ、原因を特定する
  9. 注意のチェックリスト ❏ 実行結果がGreenにもRedにもなり、非決定・不安定である ❏ テスト実行結果が出るまでに時間がかかる ❏ テスト失敗時に問題箇所の特定までに時間がかかる ❏ 失敗した理由を特定したはいいが、非同期処理のテストの書き方などが原因で、 テスト対象の問題ではなかった

    … ❏ End2End(Large)テストの失敗原因特定と対処で メンテナンスコスト高が発生している ❏ ステークホルダーやエンジニアの間でテスト結果に対して信頼が 喪失している (チームで評価してみてね) もしも、現在End2Endテストが多めの場合
  10. 後から発見したバグは、本来は何によって補足するの がよかったのだろうか? • 市場障害による損害は許容範囲内と判断する? • リリース直前のまとめての手動テストでカバー? • End2EndのLarge Testでカバー? •

    外部サービスには接続しないが、DB接続して確認す るバックエンドのMedium Testでカバー? • ドメインロジックにフォーカスしたバックエンドの Small Testでカバー? • etc… (チームで評価してみてね)
  11. 何を検証したい?どのテストを使って検証したい? 例: A: 複数マシンでUIからDB、外部サービスAとも 連携するEnd2End。 (Large Test) B: フロントエンドの表示用モジュール(Small Test)

    C: バックエンド。特にDDDでいうところの集約 (Small Test) D: バックエンド。特にWebAPIのリクエストから DBを介してレスポンスまで。ただし外部サービス 連携はモック・スタブを使用 (Meduim Test) … ページ WebAPI-B WebAPI-A コンポーネント 集約 A B C D
  12. 1. コスパやタイパだけでなく、ウェルパ大事 2. テストコードを使って対象ドメインの理解の解像度を あげていこう 3. 本当に重要な問題箇所を特定し修復するまでの時間が 短くなるよう工夫を続けよう 4. 最大の効果は「根拠ある自信」

    5. テストを使ってリファクタリングを続けて、いつまで も自信を持って修正&リリースできる状態を保とう 6. Obscure Testには気をつけよ! 7. Fragile Testには気をつけよ! 8. Flaky Testには気をつけよ!
  13. 9. 人が読んで理解できる、対話を促進するテストコードに書き 換えよう 10. POやドメインエキスパートと会話している時、 すでにテスト活動は始まっている! 11. テスト書く際も疎結合は大事! 12. Flaky

    Testだらけ状態に陥らないために、日頃から 予防的処置に取り組もう 13. ユーザビリティテスト、探索的テスト、非機能要件のテストなど を忘れずに 14. Large、Medium、Smallなど言葉の理解をチームで揃えよう