机上テスト、継続的テスト、その中間のすべて: さまざまなテストをどれくらい自動化するべきか

この記事はCameron Lairdによるゲスト投稿です。

自動化の労力に見合うテストがあります。開発者のデスクトップで実行する価値のあるテストがあります。さらに—まれには—テストする必要のないコードもあります。

それぞれのケースで「赤信号」から「青信号」に変える方法を紹介します。

完全に自動化されたテスト

一般的に、単体テストは完全に自動化する価値があります。通常、単体テストは実行時間が短く(多くは1秒未満)、ネットワーク接続やパスワードなどのシークレットに依存せず、開発、ステージング、運用など別の環境で実行できる可搬性を備えていることが多く、大部分は並行実行が可能です。テスト駆動型開発(TDD)では、通常、この種の単体テストを生成します。

ただし、単体テストには固有の難しさもあります。ネイティブモバイルアプリケーションやWebアプリケーションを含むグラフィカルユーザーインターフェイス(GUI)は、ライブラリやサービスなどの他の派生物と比べて動かすのが難しいと言われますが、おおむねそのとおりです。GUIを動かすためのツールやフレームワークや装備のエコシステムがいろいろあります。こういったものはまた別の機会に検討し、ここでは次の1つだけを取り上げたいと思います。GUIのテストは、分解するのがよい場合が多くあります。

たとえば、アプリケーションに新規ユーザーを登録する機能があるとします。エンドユーザーはカーソルのポイントやクリックなどの一連のアクションを通じて1つのプロファイルのデータベースレコードを作成します。この要件に対応するテストを定義するのは自然なことであり、GUIがもたらす困難を考慮しても、これを可能にするテストツールやプラットフォームもいくつかあります。

しかし、この1つの要件を次の2つに分解することを検討してみましょう。

  • GUIによるユーザープロファイルの収集
  • データベースへのユーザープロファイルの保存

3つ以上のステップに分解することも考えられるでしょう。

  • GUIによるユーザープロファイルの収集
  • ユーザープロファイルの検証(ユーザー名とパスワードが制約を満たしているかなど) 
  • データベースへの検証済みユーザープロファイルの保存

GUIを通じた収集-保存ステップ全体を完全に自動化できる場合でも、GUIなしのサブセットは依然として価値があるかもしれません。後者は、継続的テスト(CT)の一環として実行できるほど高速な可能性があり、おそらく、GUIが関係するテストに比べて並行実行が容易で、保守も容易でしょう。

テストを難しくする「柔軟性がない性質」はGUIだけではありません。時間や場所に縛られた要件もテスト時にリファクタリングし分割する価値があります。毎日午前1時に実行されることになっているバックアップについて、または国によって異なるコンテンツルール等について考えてみてください。前者に適しているのはエンドツーエンドテストではないことはほぼ間違いないでしょう。要件のバックアップ部分はいつでも正しく動作することをテストするべきです。いっぽう、別の検証でバックアップが実際に午前1時に開始されるかを確認します。この例は、より一般化して検討すると、作成とメンテナンスが容易になるテストもあるということも示しています。いつでも正しく機能するバックアップをテストするほうが、毎日1回に制限されているバックアップをテストするよりも易しいのはほぼ確実です。

このように、完全に自動化テストされたテストの1つのバリエーションとなるのが、いくつかの部分に分かれ、それぞれの部分が完全にまたは部分的に自動化されたテストです。

ポリシーによる部分的な自動化

私たちがよく遭遇する部分的に自動化されたテストのもう1つの例は、ポリシーによって人間の判断に依存するテストです。

特定のデータベースアクションのテストは、原理的には自動化できる可能性がありますが、パスワードなどの認証情報をテストフレームワークから切り離しておくという判断がなされています。このようなテストは完全な自動化が可能であっても、例外として個々のテスターが認証情報を入力する必要があります。

システム管理の第一人者であるTom Limoncelliは、その場限りの体系化されていないものから、完全に自動化されたものまで、すべてのテストはスペクトラム上にあると強調しています。私たちにできる最も健全なことの1つは、テストをライフサイクルの観点で考えることです。つまり、テストはアイデアとして始まり、人間が読むことのできるスクリプトに進み、いずれ完全な自動化に至ります。

もう1つよくある部分的な自動化の例は、負荷テストを完全に自動化できるが、ネットワークや関連する実行時条件が整っていることをシニアエンジニアが認可したときにだけ実行できるというものです。これを人間が読める形で漏れなく整理しておくとよいでしょう。

  • $ROLE ロールを付与されたエンジニアが $NETWORK-LOAD-1 テストを許可する。
  • テスター$TESTER が$NETWORK-LOAD-1を開始する。

コンピューターによって自動化されていないものも含め、すべてのテストは資格のある人間によって再現可能でなければなりません。Limoncelli が説明しているとおり、自動化を達成する効果的な方法は、個々のテストを適切なステップに分割してから、個々のステップを可能なかぎり自動化することです。

手動テスト、自動化、またはその両方

コンピューターよりも人間のほうが容易に実行できるテストがあります。Webページが「読みやすい」かなどの主観的な要件、あるいは猫の写真と犬の写真を見分けるなどのパターン検出などは、訓練を受けた人間にはすばやく簡単にできますが、自動化によって捕捉するのは困難です。

その他にも、コンピューターにとってルーティン作業のように見えても、ソリューションが従来のテストフレームワークに収まらないために予想外に困難だということがわかるかもしれません。以下のような例を考えてみましょう。

  • 6か月より古いレコードを削除する。
  • 特定の操作が20秒以上続いた場合にタイムアウトを記録し、エンドユーザーに例外を通知する。
  • 認証情報を少なくとも20時間ごとに更新する。
  • リモートサービス(残高照会、認可、在庫状況など)がどのような順序で応答しても、金融取引を確実に処理する。
  • バックエンドのホストへのネットワーク接続が一時的に失われたときでも適切なレポートを行う。

熟練したテスターなら、こういったケースに対して、手動テストを自動化する十分な手段がないとしても、有効な手動テストを考えつくでしょう——ときにはケーブルを抜くことであっても!

実際、これら個々の要件はすべて、適切な背景とツールがあれば自動化できる余地があります。しかし、自動化が面倒な状況で信頼できる手動テストがあるなら、最優先で完全な自動化を行うのは割に合わないと認めるべき時です。

あまり頻繁に実行されないコードや、アプリケーションの中で失敗を容易に取り戻せる部分の要件は、最初の作成時に軽くテストすることで切り抜けられるかもしれません。自動化のための労力は、少なくともアプリケーションのより脆弱な部分が一定の信頼性に達するまで、そのような部分だけに集中させてかまいません。

適切な検査の習慣でテストを補完します。検査に対するテストの優位性を熱心に議論する人たちもいますが、賢いエンジニアは両方のテクニックを、多くの場合は組み合わせて、最大限に活用する方法を選ぶことを知っています。ソフトウェア加算器の網羅的なテストを作成するのは非現実的であり、実行に時間がかかりすぎます。しかし、少数の例(たとえば “1 + 3 = 4”、“8 + (-8) = 0”、“100,000 + 1,000 = 101,000”)の自動化された検証とよく考えられた検査を組み合わせるのは成功へのよい道筋です。

着実なアプローチをとる

手動と自動の強みを合わせたテストによって完全性を目指すのが適切なアプローチです。手動の作業が十分に文書化され、よくわかっている作業者が単独で作業を実行できるようにします。また、要件をテスト可能なセグメントに分割します。

時間をかけて、より多くの手動テストを自動化によって取り込み、テスターの時間と労力を開放します——そうすれば、テスターはテストと自動化のアイデアをより多く考案することができます。

Cameron Lairdは、賞を授けられたソフトウェア開発者で著述家です。Cameronは、Python Software Foundationの投票権を持つほか、いくつかの業界のサポートや標準化組織に参加しています。長くTexas Gulf Coastに住み、農場自動化アプリケーションがお気に入りです。

(この記事は、開発元Gurock社の Blog 「Desk Tests, Continuous Tests, and Everything Between: How Much Automation Different Tests Deserve」2020年5月28日の翻訳記事です。)

関連する製品

テスト管理ツール TestRail

テスト管理をシンプルにするWebベーステスト管理ツールのトップブランド

Webベースのテスト管理ツールのトップブランドであるTestRail。テストケースの管理やテスト結果の記録、チームでの情報共有、REST APIを用いた外部ツールとの連携など、テスト活動の本質的ではない作業に時間を取られていませんか?TestRailはシンプルで使いやすいUIを提供し、テストにかかるさまざまな管理コストの削減に貢献します。

TestRailの詳細はこちら>>>

Java対応静的解析・単体テストツール Jtest

静的解析によるセキュリティ脆弱性などの致命的な問題の検出、単体テストの導入や運用の障壁の除去

Jtestは、テスト工数の大幅削減とセキュアで高品質なJavaシステムの開発を強力にサポートするJava対応テストツールです。2,000個以上のコーディング規約をもとにソースコードを静的に解析し、プログラムの問題点や処理フローに潜む検出困難なエラーを検出します。さらに、JUnitを用いた単体テストについて、作成、実行、テストカバレッジ分析、テスト資産の管理といった単体テストに係る作業をサポートし、単体テストの効率化を促進します。

Jtestの詳細はこちら>>>

eBook 公開中

Paul Gerrard著 効果的なテスト管理12の秘密 (日本語)

テスト計画やテスト管理に役立つ12のトピックを解説します。

詳細はこちら