The different types of software testing

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

Sten Pittet Sten Pittet

There are many different types of testing that you can use to make sure that changes to your code are working as expected. Not all testing is equal, though, and we will see here how the main testing practices differ from each other.

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

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

一方、自動化テストは事前に記述されたテストスクリプトを実行するマシンによって実行されます。これらのテストは、クラス内の 1 つのメソッドの確認から、UI で一連の複雑な操作を実行することで同じ結果が得られることの確認まで、複雑性が大きく異なる場合があります。自動化テストよりも堅牢で信頼性が高いものの、自動化されたテストの品質は記述されたテストスクリプトの品質に左右されます。

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

テストの種類

ユニットテスト

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

統合テスト

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

機能テスト

Functional tests focus on the business requirements of an application. They only verify the output of an action and do not check the intermediate states of the system when performing that action.

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

エンドツーエンドテスト

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

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

受け入れテスト

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

Performance testing

Performance tests check the behaviors of the system when it is under significant load. These tests are non-functional and can have the various form to understand the reliability, stability, and availability of the platform. For instance, it can be observing response times when executing a high number of requests, or seeing how the system behaves with a significant of data.

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

スモークテスト

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

Smoke tests can be useful right after a new build is made to decide whether or not you can run more expensive tests, or right after a deployment to make sure that they application is running properly in the newly deployed environment.

テストを自動化する方法

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

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

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

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

If you're just getting started with testing, you can read our continuous integration tutorial to help you with your first test suite.

探索的テスト

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

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

An exploratory testing session should not exceed two hours and need to have a clear scope to help testers focus on a specific area of the software. Once all testers have been briefed, is up to them to try various actions to check how the system behaves. This type of testing is expensive by nature but is quite helpful to uncover UI issues or verify complex user workflows. It's something especially worth doing whenever a significant new capability is added to your application to help understand how it behaves under edge cases.

テストに関する注意事項

To finish this guide, it's important to talk about the goal of testing. While it's important to test that users can use your application (I can log in, I can save an object) it is equally important to test that your system doesn't break when bad data or unexpected actions are performed. You need to anticipate what would happen when a user makes a typo, tries to save an incomplete form or uses the wrong API. You need to check if someone can easily compromise data, get access to a resource they're not supposed to. A good testing suite should try to break your app and help understand its limit.

And finally, tests are code too! So don't forget them during code review as they might be the final gate to production.