技術的なシステム知識の重要性

このブログは「The Importance of Technical System Knowledge」を翻訳・一部加筆したものです。

システムを理解することで、その自動化をより効果的に行うことができます。

テスト自動化の世界では、戦略、ツール、不安定性、フレームワーク、カバレッジ、パイプライン、環境などについてよく話題になります。しかし、私たちの考えでは、効果的なテスト自動化の基盤であるにもかかわらず、見過ごされがちなトピックがあります。それは、技術的なシステムの知識です。

理解していないものを効果的に自動化することはできません。このシリーズの前回の記事で説明したように、さまざまな種類の自動テストがありますが、最も適切なものを選択するにはどうすればよいでしょうか?
最も一般的なアプローチは、システムをブラックボックスとして扱い、ユーザーインターフェース(UI)を通じてのみ操作や検査を行うことです。しかし、テストの不安定さや実行速度の遅さに関する多くの事例から、このアプローチが機能しないことはわかっています。これらのテストが悪いわけではありません。リスクがUI層にあり、適切に実装されていれば、価値を提供します。しかし、UIが自動化の対象層の唯一の場合、より良い方法があるかもしれません。

実は、私はそのエンジニアだったのです。スプリントごとに数百の UI テストを追加しても、期待した価値を得ることができませんでした。しかし、過去 10 年間で、他の多くの人たちと同様に戦術を変更し、自動化からより大きな価値を得られるようになりました。その理由は、自分が取り組んでいるシステムについて深い理解を持っているからです。具体的には、そのアーキテクチャ、実装、データ構造、レイヤー、コンポーネント、UIが機能するすべての要素です。私が目にした最も価値のある自動化努力は、この知識を活用してターゲットを絞った自動テストを作成したケースです。

そこで、この記事では、技術的なシステムの知識がなぜ重要なのかを探ります。自動テストの信頼性や効果を向上させ、よくある落とし穴を回避する方法、そしてテストの取り組みをより的確にターゲットに絞る方法について見ていきます。私は、自動テストを「ターゲットを絞った」「信頼性の高い」「情報豊富な」「維持可能な」ものにすることで、テストの最適化を支援します。これにより、テスト自動化のスピードアップと、チームが提供する貴重な洞察を迅速に得られるようになります。

技術的なシステムの知識とは何を指すのでしょうか?

まず最初の単語「技術的」から始めましょう。私は、アーキテクチャ、データフロー、使用される技術、システム統合などについて言及しています。コードを書くことについては話していません。コードは技術的なシステムを学ぶための良い場所の一つではありますが、多くの方法の一つに過ぎません。システムとはテスト対象のシステムであり、特にそのシステムの技術的な知識を指します。同じアーキテクチャやツールを使用する他のシステムに関する経験がある場合でも、このシステムでどのように使用されているかを調査することが不可欠です。

常に追求している技術的な知識:

  • システムを構成する技術
  • システムアーキテクチャ、主な構成要素とその数(DB、API など)
  • 構成要素間の通信方法
  • データの保存場所と取得方法
  • UI での操作がシステムの低レベルなアクティビティにどのように反映され、再び UI に戻ってくるか
  • 自社システムおよびサードパーティシステムとの統合
  • 利用可能な設定オプション

すべてのコードや設定を1行1行覚える必要はありませんが、データの流れを誰かに説明できる程度の技術的な知識は身につけておく必要があります。たとえば、ユーザーがフォームに入力すると、そのデータがAPIに送信され、APIがそれを型に変換してメッセージキューに送信し、最終的にDBに保存されます。リスクを軽減するために、そのリスクがどこにあるかを判断するための十分な知識が必要です。

別の言い方をすれば、誰かがあなたにこのシステムの構成図を描いてほしいと頼んだ場合、十分な具体的な情報を含む高レベルの図を簡単に作成することができるでしょう。

システム知識の不足が自動化取り組みを妨げる理由

チームがよく直面する、システム知識の不足が原因と思われる一般的な状況について、いくつか見ていきましょう。

大規模なテスト

UIの下でシステムがどのように機能しているかを理解していない場合、自動テストの代替アプローチを見出すことができません。APIの存在を知らない場合、APIテストを作成しようとは思わないでしょう。もちろん、APIテストの作成方法も必要ですが、システムにAPIが存在することを理解することが先決です。この理解の欠如は、複数の画面を移動し、システム全体を「エンドツーエンド」で実行する大規模なUIテストにつながりがちです。これはよく誤解される用語ですが、これには2つの定義があります。一つは、自動化対象の流れに関する「エンドツーエンド」です。例えばショッピングカートから注文を確認するまで。そしてもう一つは、システムの「エンドツーエンド」です。例えばUIからデータベースまで、通常は複数回 横断することを意味します。

これらのテストは、作成、維持、実行に時間がかかり、システムを複数回横断するため、絶えず変更や不安定さが生じやすい傾向があります。

不安定なテスト

私の考え方では、不安定さはシステムやツールの知識の不足と直接関係しています。多くの場合、エンジニアは使用しているツールやフレームワークに責任があると言いますが、それらが原因であることはほとんどなく、ほとんどの場合、テストの作成者に原因があります。

当社の自動テストは、与えられた指示のみに従います。指示が不十分な場合、その結果も不十分なテストとなります(ゴミを入れたらゴミが出る)。指示が不十分な理由は、UI レイヤーであっても、システムの動作を完全に理解していないためです。ロケーターが常に変更されていますか?なぜですか?どのフレームワークを使用していますか?ページが予想と異なる順序で読み込まれることがあります。なぜですか?UIでの一貫性のない動作は、何が原因ですか?これらの質問に答えるためには、システム知識を拡大する必要があります。不安定なテストは、システムを探索する良い機会です。

過剰または仮定されたテスト

システム内のロジックがどこにあるのか理解していないと、そのロジックをテストしているかどうかさえわかりません。一方、気づかないうちに、異なるレイヤーで同じロジックを何度もテストしている可能性もあります。あるいは、最終ページでの動作をテストするためだけに、非常に大規模なテストを実施している場合もあります。これにより、カバレッジが十分であるとの誤った認識が生じ、重要なパスを完全に見逃してしまう可能性があります。

システムに関する知識は、適切なテストに適切なレイヤーをターゲットにするのに役立ちます。

これらの知識の収集

この時点で、あなたは「その通りだ、私も同じ問題を抱えている。おそらく、より高度なシステム知識があれば解決できるかもしれない」と考えているかもしれません。しかし、その情報をどのように収集すればよいのか、どこから手をつければよいのか、わからないでしょう。技術的なシステム知識の習得には意図的な努力が必要ですが、テスト自動化におけるその見返りは非常に大きく、投資する価値があります。

始めるには、次の手順に従ってください

1. ソースコードを読みましょう(自分で書かいていなくても)

繰り返しますが、自分でコードを書かない場合でも、コードを読んでみてください。コードベースを探索することで、膨大な量の洞察を得ることができます。まず、フォルダ構造を探索することから始めてください。これにより、コードベース内の位置関係を把握することができます。次に、特定のファイルについて詳しく調べてみてください。目の前の内容を完全に理解できなくても心配しないでください。質問をまとめて、同僚や、許可されている場合は AI に尋ねてみてください。if文やswitch文などの条件分岐ロジックを探し、使用されているデータやパスがどのように変化するかを理解してください。

コードレビュー/プルリクエスト (PR) に参加してください。多くの場合、文脈の変化を見ることでコードの知識を容易に深めることができます。通常、これらのチケットに関連するストーリーは把握していますので、その枠組みが理解しやすいでしょう。

package.json や .nuget ファイルなどのパッケージ管理ファイルを探します。これらのファイルには、コードベースで使用されているすべてのパッケージが一覧表示されており、多くの場合、さらなる発見の糸口となります。

2. 開発者とペアを組みます

ペアプログラミングは、技術的な知識を得るのに最適な方法です。コードレビュー、プルリクエスト(PR)、ストーリーの実装など、さまざまな場面で活用できます。文脈に沿った質問をしたり、好奇心を追求したりすることで、開発者は自分の判断や知識を固めることができます。

3. フローを追跡します

ログインやフォームの送信など、単純なユーザー行動を選び、クリックからデータベースまで何が起こっているかを追跡します。どの API が呼び出されますか?バックエンドでは何が起こっていますか?どのようなログが作成されますか?メッセージは公開されますか?データはどこに保存されますか?

また、それを視覚化してください。おそらく未知の要素を発見するでしょう。それらを学ぶことは良い機会です。

4. 根本原因分析

すべてのバグやライブインシデントを学ぶのは良いことです。欠陥が見つかった場合は、ただ急いで修正するだけでなく、なぜそれが起こったのか、システムのどこから発生したのかを調査してください。これにより、システムのメンタルモデルが構築され、将来同様のギャップを回避するのに役立ちます。

5. ドキュメント / 仕様書

最近では、Open API 仕様などの堅実なドキュメントや仕様書が一般的になっています。これらは、コード自体よりも理解しやすい言葉で表現されていることが多く、技術的な知識の優れた情報源となります。コードは書けないが、コードを読むことは問題ない人向けに作成してください。

TRIM(S) 自動テスト

自動テストについて考え、この技術的なシステムの知識を最大限に活用する方法について考える際、私は TRIM(s) という記憶術を使用しています。この記憶術は、既存のテストを削減するのに役立ち、その結果、最初からより小さなテストを作成するのに役立ちます。自動テストを作成/レビューするたびに、それが TRIM であるかどうかを自問してください。

Targeted(ターゲットを絞る)

始めに、リスクと実装について考える必要があります。リスクに関しては、自動化できるものは選択的に自動化する必要があります。なぜなら、すべてを自動化することは不可能であり、自動化しても意味のないものもあるからです。自動化すべきものは100%自動化すべきです。何かを自動化すべきかどうかを判断する一つの方法は、そのテストが軽減するリスクに焦点を当てることです。そのリスクは重要なものですか?ビジネスはそのリスクを重視していますか?テストに失敗した場合、ビジネスは十分な対応を取るでしょうか?

ターゲットの 2 つ目の焦点は、テストの実装です。現在のテスト可能性で、リスクにどれだけ近づけることができるでしょうか?リスクはシステムのユニット層で軽減できる可能性があります。これは、技術的な実装について学習に投資してきたためわかったことです。しかし、この状況では、開発者はユニットテストの記述を拒否してしまいます。その問題に取り組むこともできますが、代わりにAPI層での自動化を選択することもできます。なぜなら、自動化エンジニアはその分野に慣れているからです。または、リスクはAPI層にあるものの、チームにその分野のスキルがない場合もあります。そのスキルに投資し、ツールを選択することもできますし、UIでのテストを自動化することもできます。

理想的な状況では、リスクを軽減できると思われるレイヤーで直接自動化を行うことも考えられますが、それは必ずしも可能とは限りません。しかし、それは問題ではありません。状況はそれぞれ異なるため、経験豊富な自動化エンジニアは状況に応じて対応します。私たちは、状況に応じて可能な限り的を絞った対応を目指しています。

Reliable(信頼する)

もし私たちの仕事をロボットに委任するならば、その仕事を信頼性高く一貫して実行する必要があります。そのためには、テストが確定的である必要があります。既に不安定さとその根本原因について議論してきました。テストの不安定さは回避する必要があります。テストが信頼できない場合、その価値は急速に低下し、チームの重要な意思決定能力に影響を及ぼします。テストが信頼できる場合、信頼できる迅速なフィードバックループが形成され、品質に関するチームの意思決定が大幅に加速されます。システムの技術的実装を完全に理解することは、より信頼性の高いテストを書くのに役立ちます。

Informative(豊富な情報)

自動テストは合格したり、不合格になったりします。私は「自動テストは変更を検出する」と表現するのが好きです。自動テストは変更検出器なのです。チームが順調に進んでいる場合、変更は頻繁に検出されるはずです。それは私たちにとって良いことであり、望ましいことです。しかし、変更が検出されても、誰かが調査を始めるまで、その変更が良いものなのか悪いものなのかはわかりません。

技術システムに関する知識を活用することで、その調査を大幅にスピードアップすることができます。システムのさまざまな部分に応じて、テストに適切な名前を付けることができます。ログ/可観測性データが存在することがわかっている場合は、それを自動的に取得することができます。プルリクエストから失敗したテストまで、当社の理解をマッピングすることで、コードの変更と検出された変更との関連性を把握することができます。

Maintainable(持続可能性)

この絶え間ない変化は、テストの継続的なメンテナンスが必要であることを意味し、そのメンテナンスはできるだけ簡単かつ迅速に行う必要があります。技術的な知識を活用すれば、テストの規模を大幅に縮小することができ、変更が検出されたときにメンテナンスが必要なコードも減ります。テスト対象システムの技術的な実装を十分に理解していると、計画段階でどのテストを変更する必要があるかを予測することができ、その作業をストーリー/機能に組み込むことができます。

Speedy(スピード感)

チームでは、スピードアップを図る必要があり、自動化がチームの作業効率を低下させることなく、むしろ効率化を促進するものとなるよう、その確保が求められています。技術的なシステム知識に基づいた階層的なテストは、作成、維持、実行のすべてにおいて迅速であるため、この効率化を促進する手段となるはずです。

システムの知識はもはや必須です

技術システムに関する知識は、効果的なテスト自動化の背後にある目に見えない力です。これは、遅く、不安定で大規模なテストを、迅速で焦点を絞った信頼性の高いフィードバックメカニズムに変革し、デリバリーを支援します。システムがどのように構築され、動作するかを、アーキテクチャからデータ、統合まで理解することで、効果的な自動化を構築するためのはるかに優位な立場に立つことができます。これにより、ターゲットを絞り、信頼性が高く、情報豊富で、維持可能で、高速な(TRIMS)テストを作成することが可能になります。

したがって、自動化をチームのペースに合わせ、有意義な洞察を提供したいのであれば、ツールを学ぶだけでなく、システムも学ぶ必要があります。なぜなら、技術的なシステム知識は単なるスキルではなく、現代のテストに欠かせないコアスキルだからです。

自動テスト ブログ シリーズについて

今回のブログは、自動テストシリーズの第 4 回目です。このシリーズは、Richard Bradshaw 氏とのコラボレーションによるものです。このシリーズでは、テスト自動化のさまざまな側面とその実装について詳しく説明します。

次の記事では、2025年7月8日に公開予定で、さまざまな種類のAPI自動テストとその最適な活用事例について解説します。お楽しみに!


Blog Topics:

Comments