2022/5/27に開催されたJaSST'22 Tohokuのレポート。 今回のテーマはテスト自動化。
今回は現地(盛岡市)とオンラインのハイブリッド開催。自分はオンライン参加。
基調講演 テスト自動化に取り組むにあたり
テストピラミッドについて
- テスト自動化を議論するときよく出てくる
- テストの量は Unit Tests > Integration Tests > UI Tests となる
- 各テストの範囲
- Unit Tests: Webサーバ、DBサーバ、クライアント(アプリ等)のシステム構成要素内でテスト
- Integration Tests: 個々のシステム構成要素を結合したテスト(クライアントーWebサーバ、Webサーバ−DBサーバなど)
- UI Tests: システム全体に対するテスト
- ピラミッドを上に登るほど依存関係が増えていくため、テスト難易度が上がり、実行速度は延びる
- テスト自動化を進めるときはピラミッドの底(Unit Tests)から取り組むのがお勧め
- 各テストの範囲
テスト逆ピラミッド
- テストの量が Unit Tests < Integration Tests < UI Tests となっている構造
- UI Testsは依存関係が多く、一番時間がかかる
- このテストで色々なテストを実施しようとするとテスト時間がかかる
デモ
- デモ内容:ブラウザを開き、jasstのサイトにアクセスし、ページ下までスクロールし、上に戻る
- 実行結果
- UI Tests 40秒
- Integration Tests 3秒
- 速度はサーバ通信に依存する(デモはアメリカから実行)
- ローカルに置いたWebページのテスト 5ミリ秒
- Unit Tests 1ミリ秒
- テスト範囲が大きくなると、テスト時間が大幅に延びる
テストの分割方法
- テストする範囲で分解する
- ネットワークを境界として区切るのがお勧め
- デモの例では、jasstサイトアクセスではサーバ側処理、ページスクロールはクライアント側処理
この範囲で区切るのがお勧め
- デモの例では、jasstサイトアクセスではサーバ側処理、ページスクロールはクライアント側処理
- Unit Testsにはnetwork通信自体は含めない。含めるのはIntegration Testsから
- ネットワークを境界として区切るのがお勧め
- スコープを限定した実行の素早いコードからスコープの広い遅いコードへ
- スイスチーズモデル*1のイメージ
- テストスコープを狭めることで、問題発生時の原因特定も容易になる
- テストする範囲で分解する
テスト自動化はテストだけではない
- 詳細は こちらの資料
これから自動化を学んでいくには
- 実際のプロジェクトにおいては、使っているツール、言語が異なる
- これから学ぶ場合、社内の助けを得ることが可能な、社内で使われている技術から始めると良い
- OSSを活用する
- OSS開発者にアプローチする
- 公式ドキュメントから始める
- Androidであれば テストの基礎 | Android デベロッパー | Android Developers がよい。
- iOS アプリのプロジェクトを作ると、テストのテンプレートが自動生成される
- 既に動くものから学んでいくのもお勧め
ランチセッション
マウスで描いたグラレコがすごかった。 (著作権とかこわいのでスクショは載せないでおく)
事例紹介
テスト自動化導入後の課題の改善ビフォーアフター
当日の資料 qiita.com
テスト自動化業務の6年間で発生した3回の問題とその対応
1 issue
- 背景
- 問題
- お互いのテストが不明確
- 仕様変更でテスト自動化の失敗が増えた
- 組織が大きくなると、テスト自動化の役割がさまよう
- 対策
- テストの責任範囲・役割を明確に
- 新規機能・既存機能の仕様変更の明確化と自動化の優先順位付け
- テスト自動化の範囲を、Project影響外の既存機能+Projectにより修正が加わる既存機能に定めた
- Project影響範囲のテストは手動テストで実施
2 issue
- 背景
- テスト対象のシステムが増えてきた
- 問題
- 対策
- テスト実行結果を可視化し、問題可能性を早期に検出できる仕組みを追加
- すべての情報をDBに保存するようにした
- テスト単位で実行時間表示できる機能追加
- Jenkins単位の実行時間推移を可視化
- スクリプト単位で実行時間の推移を可視化し、問題があるテストを検出、修正
- 背景
3 issue
- 背景
- 更にテスト対象が増えた
- 問題
- 対策
- テスト失敗の原因を機械学習させ、再実行した方がよいテストは自動で再実行させるようにした
- 運用が効率化でき、もっと知的な作業に集中できるようになった
- テスト失敗の原因を機械学習させ、再実行した方がよいテストは自動で再実行させるようにした
- 背景
リグレッションテストをほぼ100%自動化した世界
MagicPod を使用してテスト自動化した事例
- E2Eレベルの回帰テストを自動化した話
成功したこと
- ~~ 100%自動化したこと ~~
- 目的を継続的に達成できたこと
回帰テスト自動化の必要性
目的達成までにやったこと
- 現状の作業を見つめ直す
- リグレッションテスト項目から、目的がない・優先度の低いテストを削減
- 自動テスト以外(ユーザー操作、バッチ操作など)の影響を受けない環境を用意
- 確認内容が曖昧なテストケースを自動テスト用に置き換え
- 例) 「ホーム画面が表示されていること」→URLが「https://------」であること
- プルリクのレビュア、承認者にQAを追加した
- 現状の作業を見つめ直す
回帰テストを100%自動化することで
- リリース頻度: 月1回→月4回
- 回帰テストの実行時間: 32時間→2時間
- テスト結果のフィードバック: 1~3週間 → 2時間~2日
副次効果: 開発者から自動テストの信頼を得られた
- プルリクが150%増加
- 以前は複数の修正まとめてプルリクしていた
- 障害があると、どの修正によるものかの確認から必要だった
- 開発から日が経ってるため、開発者が修正内容を忘れてることもあった
- 障害があると、どの修正によるものかの確認から必要だった
- 修正結果へのフィードバックが早く得られるため、開発者が細かい単位でプルリクするようになった
- 以前は複数の修正まとめてプルリクしていた
- リファクタのプルリク数:170%増加
- 本番障害数0件
- 今まで手動回帰テスト実施していた時間を別作業に割り当てることができた
- E2E自動化をきっかけとして、UnitやIntegrationのテストが発達していった
- プルリクが150%増加
自動テストのテストは絶対にすること
- テストしないと
- バグを検知しない
- 予期せぬ動作をやってしまう
- 結果が安定しない
- テストしないと
成果が出るまでの期間
- 自動化にかかった期間: 半年間(他の作業)
- 効果が出るまで: 更に半年
初めての自動化導入は慎重に、計画的に
はじまり
未経験から来る漠然とした不安
- 原因分析
- そもそもどこから手を付けてよいのか。。
- 未経験の分野
- 「自動化は失敗する」という記事をよく目にする
- スクリプトはほとんど書いたことない
- 予算がない
- 原因掘り下げ
- どう自動化していけばよいのか分からない
- 先任者がいないため、始め方のノウハウがない
- コーディングスキル不足による不安
- 原因分析
自動化は小さな一歩から試す
- 最初から本格的にテスト自動化に取り組むと考えるから壁が高くなる
- テストに拘らず身近な作業から自動化にチャレンジ
- RPAツール(Coopel)で自動化を試してみた
- RPAツールが直感的に使えることもあり、意外と簡単に環境構築作業の自動化に成功。一歩を踏み出せた
- 手動作成: 30時間 → 自動化: 1.6時間
- 小さな一歩から成功体験を得ることによって壁が取り除かれた
過去の失敗から学ぶ(アンチパターンの研究)
ツールベンダーを活用する
不安を一つ一つ解消していくことで色々見えてくる
- 色々と見えてくれば、次のステップも明確になってくる
ワークショップ
「かま○たちの夜」風のサウンドノベル風ゲームでのワークショップ
ゲーム後の解説ピックアップ
- すべてのテストを自動化できない
- ツールがチェックできるのはツールが解釈できる結果のみ
- データ登録確認などは登録後データでチェックできるが、表示崩れの確認などは困難
- 探索的テストの自動化はできない
- 回帰テストは自動化を使用する絶好の機会
- ツールがチェックできるのはツールが解釈できる結果のみ
- テスト自動化には初期費用だけではなく固定費もかかる
- ツール所有コスト
- ツールのライセンス費用
- ツールのメンテナンスコスト
- ツールにより作成された成果物のメンテナンスコスト
- ツールのトレーニング、メンタリングコスト
- 別の環境へのツール移植
- 将来のニーズへのツールの適用
- ツールを最適に使用するための品質、プロセスの改善
- ツール所有コスト
- テスト自動化の効能
- 十分に成熟しているテストがすでにあり、そのテストが今後何年も実行される予定がある場合、自動化することでコスト削減できる
- コスト以外の効能
- 繰り返し型開発におけるセーフティネットとしての役割
- バグ修正日数の低減
- 影響範囲レビュープロセスの代替
ゲーム中のDiscordでのやり取りが面白かったが、個人的に印象に残ったのが、ゲーム中に出てくる上司についてのコメント。
自動化テストの導入に対して、上司理解が得られるかはかなり重要なポイントだと思っているが、自分も含めてみんなここに苦労してるんだなという印象だった。
招待講演 テスト自動化の成功を支えるためのチームと仕組み
当日の資料
テスト自動化の成功とは
- 妥当な対価で目的を達成すること
- 目的にもレベルがある
- テスト担当に閉じた目的<チームレベルの目的<ビジネスレベルの目的
- 自動化の目的を考えるときは広い視点で
- 自動化による主要な効果
- テストの有効性の拡大
- 手動では困難なテストを実施する
- 本質的な目的達成に貢献する
- テストの効率性の改善
- テスト活動にかかる時間やリソースを削減する
- 同じコストでできるテストを増やす
- テストの正確性と信頼性の改善
- 手動のミスを削減する
- 誤差や不安定さに対応する
- テストの保守性の改善
- テストの品質保証、維持、修正、再利用を容易にする
- テストのインテグリティやトレーサビリティの維持を助ける
- テストの有効性の拡大
- 主要な対価
- 必要なリソース(人、物、時間)
- 必要な労力の種類
- 自動テストの実現
- テスト自動化環境の構築・維持
- 自動化テストの構築・維持
- テスト自動化に付随する追加作業への対応
- テスト対象の改善/テストベースの確保
- 自動化インフラの実現
- テスト自動化を支えるマネジメントの実現・維持
- 自動テストの実現
- 目的にもレベルがある
- 妥当な対価で目的を達成すること
テスト自動化の成功を支える活動
- テスト自動化を成功させるためには?
- 適切な目的を立てる
- 経験的に多いテスト自動化失敗要因:不適切な目的や目標の設定
- 短期スパンでコスト削減を目標にする→失敗フラグ
- 中長期スパンで導入を考えないとコスト削減は難しい
- 短期スパンでコスト削減を目標にする→失敗フラグ
- チームの成功につながる目的を選ぶ
- テストのニーズ・シーズ・制約・チームの状況に応じて達成できる目的が変わる
- テスト自動化のリスクや費用対効果が変わる
- その時のチームにとって有益で実現可能な目的を設定するのが重要
- 広い活動スコープで目的を設定する
- テスト担当にスコープを限定するとしょぼい目的になりがち
- テスト自動化活動のスコープを広げると
- より本質的・効果的な目的を選択できる
- 目的達成に使える手段や関係者が増える
- ステップバイステップで目的達成を目指す
- テスト自動化活動を継続し、テスト自動化の成功や技術を蓄積すると、より難しい目的に対応できるようになる。
- 最初は必要な技術レベルが低いものから実施
- Unit Tests
- フレームワークが提供するテストツール
- 定番ツール
- ハードを含むようなテストは必要な技術レベルが高い
- 最初は必要な技術レベルが低いものから実施
- テスト自動化活動を継続し、テスト自動化の成功や技術を蓄積すると、より難しい目的に対応できるようになる。
- 経験的に多いテスト自動化失敗要因:不適切な目的や目標の設定
- コストを削減
- 自動テストにとってのテスタビリティ(テストしやすさ)を高める
- 品質特性
- 実行円滑性:円滑に自動化された処理を実行できる
- 観測容易性:自動テストがテスト対象の出力を観測しやすい
- 制御容易性:テスト対象の入力を操作しやすい
- 分解容易性:テスト対象を切り出しやすい
- 単純性:使用や構造、実行方法が単純
- 安定性:テスト対象自体のバグや不安定さが少ない
- 理解容易性:仕様や構造、実行方法が分かりやすい
- 品質特性
- テストの妥当性を高める
- 価値のあるテストケースを作る
- ゴミは自動化してもゴミ
- 価値のあるテストケースを作る
- 自動テストの内部品質を作り込む
- 拡張性: 少ない対価で自動テストのカバレッジを拡張可能にする
- モデル駆動テスト → モデルからテストを自動生成
- データ駆動テスト
- 環境仮想化
- 保守コスト悪化によるテスト自動化失敗は多い
- 拡張性: 少ない対価で自動テストのカバレッジを拡張可能にする
- テスト自動化の計画とアプローチを工夫する
- 自動テストの活用の頻度と幅を広げる
- 自動化インフラに自動テストを統合する
- デプロイメントパイプラインに自動化テストを組み込むことで、自動化テストの責任を果たせる
- 作っただけだと、適切なタイミングで実行されずに放置されることがある
- インフラ機能の活用
- デプロイメントパイプラインに自動化テストを組み込むことで、自動化テストの責任を果たせる
- 監視とコントロール、保守で自動テストを維持・改善する
- 自動テストを保守し、自動テストの効果を維持・改善するよう務める
- 自動テストにとってのテスタビリティ(テストしやすさ)を高める
- 適切な目的を立てる
- テスト自動化を成功させるためには?
テスト自動化の成功を支えるチームと仕組み
- テスト自動化の成功要素の実現には、チームと仕組みによる下支えが不可欠
- チーム
- 開発とテストがお互いのために連携・協力する体制
- プロセス
- 設計段階でもテストを考慮するプロセス
- 開発インフラ
- テスタビリティの確認・維持を支えるインフラ
- チーム
- テスト自動化を支えるチーム文化
- チームが文化を誘導する、チーム文化がチームや仕組みを生み出す
- テスト自動化の成功を支えるチーム文化の志向性
- チームのテスト自動化の能力を確保し高める
- Whole Teamでテスト自動化を推進する
- チームでの自動テストの責務を確立する
- チームにとっての自動テストの価値を高める
- チームで自動テストの持続可能性を保つ
- チームでテスト自動化の動機づけを行う
- テスト自動化の能力を持つ人材を確保
- 人材の確保
- テスト自動化人材のスキルモデルやスキル評価手段の確立
- 開発能力不足に起因する失敗は多い
- チーム構築
- 要となるロール
- テストアーキテクト:あるべき姿に推進する
- SET/SETI: 開発技術を活かして、テスト自動化およびテスト自動化インフラに注力
- 要となるロール
- チームの能力の維持・向上の仕組み化
- 人材の確保
- 自動化インフラの整備
- デプロイメントパイプラインの自動化
- 開発インフラで、テスト自動化活動をサポート可能にする
- テスト自動化のプロセスの整備
- テスト自動化の成功要素の実現には、チームと仕組みによる下支えが不可欠
当日のプログラムはいじょ
感想など
イベントが終わって
自分が今関わっているプロジェクトはテスト自動化はできておらず、取り組んでいくべきとは考えていた。 テストピラミッドを考えてUnit Testsの自動化から取り組んでいくべきだとは思っていたが、今日の講演を聞いて、そのレベルにもないチームはUI Testsから始めていくのもありかなと思った。
実際、Unit Testを自動化するには、メソッド単位でテストできるような設計・実装が必要で、腐った実装のコードにいきなり導入することはできない。
今のプロジェクトのコードもモンスターメソッドが多数あり、無理やりUnit Test自動化したところで、工数が増えるだけの意味ない作業になるのが目に見えている。
プロジェクトの文化を変えるには、まずは「テスト自動化が有効だ」ということをプロジェクトメンバーに認識してもらわないと先に進めないので、UI Testsから初めてリグレッションテストの改善から取り組むのは有効な手段と思った。
ちなみに、今のプロジェクトでも画面操作リプレイする形式でのUI Testsを試しに導入してみたが、Assertが入っておらずエラー画面に遷移してもテストOKになってしまう程度のもの。
結果、手順を自動化したけど結果の確認は人が行うという事になっていて、導入して何か改善された? というレベルのものになってる。今日の講演で出てきたアンチパターンのオンパレード。
とはいえ、プロジェクトとして「UI Testsを導入してみる」というところは入れているので、目的を整理してここから進めていくのはありかと思った。
テストツールとして、AIがメンテナンスを実施するツールがあるというのも知らなかったので確認してみる。
オンライン開催について
- PC2台用意して、1台で講演表示+メモを取る、もう一台でDiscordとTwitterを表示しながら参加。
この参加方法がヒットだった。 - Discordのコメントへのリアクションが面白い。
Twitterだとコメントへの反応は「いいね」か返信くらいしかないが、Discordはリアクションのスタンプが多くあり、コメントに対して手軽にリアクションできる。
他の人と感想を言いあいながら、共感できる事を他の人と共有できるのはオンラインセミナーならではの面白さだった。
現地参加とオンライン参加の方の両方を満足させるのは運営大変だったと思います。ありがとうございました。
関連リンク
Togetter: JaSST'22東北 テスト自動化その前に - Togetter
UI Testツール
Googleのソフトウェアエンジニアリング