さまざまな種類のソフトウェア テスト

単体テスト、統合テスト、機能テスト、受け入れテストなど、さまざまな種類のソフトウェアテストを比較しましょう!

Sten Pittet Sten Pittet

コードに対する変更が想定どおり動作するかどうかを確認するには、さまざまな種類のテストを使用できます。しかしすべてのテストが同等であるとは限らないため、ここではいくつかの主なテストの実践がそれぞれどのように異なるかを見ていきます。

手動テストと自動化テスト

手動テストと自動化テストを大まかに区別する必要があります。手動テストは、アプリケーションの中をクリックしたり、適切なツールを使用してソフトウェアおよび API とのやり取りを行ったりするなどして、人間が実行します。この方法は、誰かが環境を設定して自らテストを実行する必要があり、非常に高額になる場合があります。また、テスターがタイプミスをしたり、テストスクリプトの手順を省略したりするなど、ヒューマンエラーが発生しやすい方法です。

一方、自動化テストは事前に記述されたテスト スクリプトを実行するマシンによって実行されます。これらのテストは、クラス内の 1 つのメソッドの確認から UI で一連の複雑な操作を実行することで同じ結果が得られることの確認まで、複雑性が大きく異なる場合があります。自動化テストよりも堅牢で信頼性が高いものの、自動化されたテストの品質は記述されたテスト スクリプトの品質に左右されます。テストに不慣れな場合は、こちらの継続的なインテグレーションのチュートリアルをご確認の上、最初のテスト スイートをお進めください。その他のテスト ツールについては、これらの DevOps テストのチュートリアルをご確認ください。

自動化テストは継続的インテグレーションおよび継続的デリバリーの主要なコンポーネントであり、アプリケーションに新しい機能を追加する際に QA プロセスを拡張する素晴らしい方法です。しかし、それでもなお探索的テストの実施と呼ばれる手動テストを行う価値があることをこのガイドで説明します。

テストの種類

ユニットテスト

単体テストは、アプリケーションのソースに近い、非常に詳細なレベルのテストです。ソフトウェアで使用されるクラス、コンポーネント、モジュールの個々のメソッドや機能のテストで構成されます。単体テストは一般に比較的安価で自動化でき、継続的インテグレーションサーバーで非常に高速に実行できます。

統合テスト

統合テストは、アプリケーションで使用されるさまざまなモジュールやサービスが全体として良好に機能することを確認します。たとえば、データベースとの相互作用のテストや、マイクロサービスが期待どおりに連携して動作することを確認する場合などを指します。この種類のテストを実行する場合は、アプリケーションの複数のパーツを稼働して実行する必要があることから、より高額になります。

機能テスト

機能テストは、アプリケーションのビジネス要件に焦点を当てています。アクションの結果を検証するだけなので、そのアクションの実行時にシステムの中間状態はチェックされません。

統合テストと機能テストはどちらも相互に作用する複数のコンポーネントを必要とすることから、紛らわしい場合があります。違いは、統合テストが単にデータベースの照会機能を検証するのに対して、機能テストは製品の要件で定義された特定の値をデータベースから取得しなければならない点です。

エンドツーエンドテスト

エンドツーエンドは完全なアプリケーション環境にあるソフトウェアを使用してユーザーの動作を再現します。さまざまなユーザーフローが期待どおりに動作し、ウェブページの取り込みやログインと同じくらい簡単に実行できることを検証し、さらに複雑なシナリオで電子メール通知やオンライン決済などを検証します。

エンドツーエンドテストは非常に便利ですが、実行が高額で、自動化された場合の維持が困難になる可能性があります。主要なエンドツーエンドテストの数を少なくして、互換性を破る変更をすばやく識別できるよう、より詳細レベルのテスト (単体テストや統合テスト) への依存を増やすことをお勧めします。

受け入れテスト

受け入れテストは、システムがビジネス要件を満たしているかを確認するために実行する正式なテストです。これらのテストはアプリケーション全体を起動して実行する必要があり、ユーザーの動作の再現に焦点を当てます。しかし、さらに先に進めてシステムのパフォーマンスを計測し、特定の目標が満たされない場合に変更を却下することもできます。

パフォーマンスをテストする

パフォーマンス テストは、システムに大きな負荷がかかっている際の動作をチェックします。これらのテストは機能には関連せず、プラットフォームの信頼性、安定性、可用性を理解するためにさまざまな形式をとります。たとえば、多数のリクエストを実行するときの応答時間を観察したり、大量のデータでシステムがどのように動作するかを確認したりできます。

性能テストはその性質上実装および実行にかなりのコストがかかりますが、新しい変更がシステムの低下を引き起こすかどうかを確認するのに役立ちます。

スモークテスト

スモークテストは、アプリケーションの基本機能を確認する基本的なテストです。このテストは迅速に実行できるようになっており、その目的はシステムの主要な機能が期待どおりに動作するか確認することです。

スモーク テストは、新しいビルドが作成された直後により高価なテストを実行できるかどうかを決定したり、デプロイ直後に新しくデプロイされた環境でアプリケーションが適切に実行されていることを確認したりする場合に使用します。

テストを自動化する方法

個人が上記すべてのテストを実行することも可能ですが、非常にコストがかかり、逆効果となるでしょう。再現性と信頼性の高い方法で多数の操作を実行するには、人間には能力の限界があります。しかし、機械はそれらを高速に実行でき、ログインとパスワードの組み合わせが機能するかを 100 回テストさせたとしても不平は言いません。

テストを自動化するには、対象のアプリケーションに適したテストフレームワークを使用してプログラムとして記述する必要があります。PHPUnitMochaRSpec は、それぞれ PHP、Javascript、Ruby で使用できるテストフレームワークの例です。言語ごとに数多くの選択肢があるため、自分で調べたり、開発者コミュニティに尋ねて最も適したフレームワークを見つけることをお勧めします。

スクリプトを使用して端末からテストを実行する場合は、Bamboo のような継続的インテグレーションサーバーで実行を自動化するか、Bitbucket Pipelines のようなクラウドサービスを使用することができます。これらのツールは、リポジトリを監視し、新しい変更がメインリポジトリにプッシュされるたびにテストスイートを実行します。

Bitbucket Pipelines のおかげですべてのリポジトリへのプッシュが検証されます

テストに不慣れな場合は、こちらの継続的なインテグレーションのチュートリアルをご確認の上、最初のテスト スイートをお進めください。

探索的テスト

コードにより多くの機能や改善が加わるにつれ、システムが正しく機能するかを確認するため、より多くのテストが必要になります。また、バグを修正したら、新しいリリースで同じバグが発生しないかを確認するのが賢明です。自動化はこれを実現するキーとなり、テストを記述することは遅かれ早かれ、開発ワークフローの一部となるでしょう。

それでは、今も手動テストを行う価値はあるのでしょうか。端的に言えばその価値はあります。また、手動テストでは非明示的なエラーの発見を目的とするいわゆる探索的テストの実施に集中するべきです。

探索的テストの実施セッションは 2 時間以内に終わるようにスコープを明確にして、テスターがソフトウェアの特定の領域に集中できるようする必要があります。すべてのテスターが説明を受けた後は、各自がさまざまなアクションを試してシステムの動作を確認します。この種のテストは本質的にコストがかかりますが、UI の問題を発見したり複雑なユーザー ワークフローを検証したりするのに非常に役立ちます。特に重要な機能が新しくアプリケーションに追加された場合は、極端な例ではどのように動作するかを理解しておくことが重要です。

テストに関する注意事項

このガイドを完成するには、テストの目標について話し合うことが重要です。ユーザーがアプリケーションを使用できるかどうかをテストする (ログインができる、オブジェクトを保存できる) ことは重要であるのと同様に、不良データや予期しないアクションが生じたときにシステムが破損しないことをテストすることも重要です。ユーザーが入力ミスをしたり不完全なフォームを保存しようとしたり間違った API を使用したりした場合に、何が起こるかを予測する必要があります。誰かが簡単にデータを侵害したり許可されていないリソースにアクセスしたりすることがないかどうかを、確認する必要があります。優れたテスト スイートではアプリの破壊を試して、その制限を理解できます。

最後に、テストもコードの一種です。したがって、コード レビューが本番環境への最後の関門になることを忘れてはなりません。