単体テストのベスト・プラクティスは、各テストを相互に独立した分離環境で実行し、決定論的で一貫性のある特性を示すように記述することを支援します。
優れた単体テストはテスト駆動開発(TDD)を反映し、依存関係の排除を支援するためにモック・オブジェクトとスタブを使用します。ベスト・プラクティスでは継続的インテグレーションと自動テストにも対応します。
多様なテストの中でも、単体テストはコードの最小単位(ソフトウェア・テストで評価対象となる最小の構成要素)に、ほぼ顕微鏡的な視点を与えます。適切な単体テストの鍵は分離であり、ユニットの関数を効果的に評価できるようにするために不可欠です。
単体テストの利点として、自動化によるソフトウェア開発の加速や、デバッグをソフトウェア開発ライフサイクル(SDLC)の早期に組み込むことで人件費を削減できる点が挙げられます。こうしたデバッグの取り組みは、開発中に行ったコード変更の定着を後押しし、全体を通じてコード品質を高めます。
単体テストフレームワークは、テスト担当者が個々のユニットに対してテストを実行し、コードベース全体をより強固なものにするのに役立ちます。テストで特定のコードをチェックし、テストが適切に実行され、関連するチェック(アサーションとも呼ばれます)がすべて正常に実装されていることが確認されることでテストの合格となります。テストの合格は、ユニットが期待どおりに動作していることを示しています。
IBMニュースレター
AI活用のグローバル・トレンドや日本の市場動向を踏まえたDX、生成AIの最新情報を毎月お届けします。登録の際はIBMプライバシー・ステートメントをご覧ください。
ニュースレターは日本語で配信されます。すべてのニュースレターに登録解除リンクがあります。サブスクリプションの管理や解除はこちらから。詳しくはIBMプライバシー・ステートメントをご覧ください。
単体テストは、説明が必要なさまざまな側面がある、多面的なトピックです。その1つが依存関係に関するものです。単体テストにおいて依存関係とは、コードのユニットが適切に動作するために必要な外部のサービスやコンポーネントを指します。
信頼でき、保守しやすいテスト(すなわち、コードベースの進化全体を通じて長期的に有効で柔軟かつ有用なテスト)を書くためには、依存関係を適切に管理することが重要です。
依存関係をうまく管理できれば、期待どおりに動作する、より強固で信頼性の高いテスト・スイートを構築できます。開発者は依存性の注入(Dependency Injection、DI)を用いて、依存関係に関わるコードをコードベースに挿入(「注入」)します。
ここで示す各テスト戦略はベスト・プラクティスを支え、実践的なテスト手法のスタイルを反映しています。
テスト環境では、テストに必要な深い分離を実現するために、モックやスタブの活用が欠かせません。
モック・オブジェクトは実体の重複物として機能し、深い分離下で模擬オブジェクトを用いることで、実オブジェクトの想定される挙動を評価するのに役立ちます。
スタブは、コンポーネント、ファイル・システム、データベースなどの外部依存との想定される相互作用に関するデータを提供します。
エラー検知は単体テストにおいて中核となる部分です。テスト担当者は、ユニットの動作パラメーターや境界値近くで発生する極端な使用パターンを評価します。これらはエッジ・ケースと呼ばれ、境界値外への配列アクセスなど、すぐには発見できない場合があります。そのような場合に、テスト担当者は、項目のインデックスが当該インデックスの最大許容値を超えていることを検知します。
このような場合、テスターはしばしばコードをリファクタリングする(既存の機能を保ったままコードを再構成する)必要に迫られます。
テスト機能を自動化する継続的インテグレーション/継続的デリバリー(CI/CD)パイプラインは、テストプロセスにとって非常に重要です。
CI/CDパイプラインを実行すれば、コード変更のたびに自動単体テストをいつでも走らせることができます。自動テストは開発プロセスの早期に不具合を検知し、コード品質の担保に寄与します。
テストの保守性には多くの要因が影響します。保守しやすいとみなされるために、テスト・コードには高い可読性、全体を通した明確さ、そして適切な識別(命名)手法が求められます。要するに、テストは本番コードと同等の品質基準で作成すべきです。
特定のモジュールを扱う小規模で目標が明確なテストとすることも必要です。また、テストが高速であればより迅速かつ頻繁に実施できるため、スピードを念頭に置いてテストを作成する必要があります。
適切な命名規則を守らないと、他は優れたテストであっても容易に埋もれてしまいます。テスト名は簡潔でありつつ、対象を十分に説明できる表現を含め、必要なときに検索・想起しやすいようにします。「Test-1」のようなラベルでは、何をなぜテストしているのかが分からず不十分です。
堅牢なコードベースを構築するには、楽観的シナリオと悲観的シナリオの両方を想定したテストを行う必要があります。楽観的シナリオの場合、テスト担当者は有効な入力を確認するテストを追加する必要があります。悲観的シナリオの場合、テスト担当者は予期しない、または無効な入力を予測する必要があります。
また、あらゆる状況に対応できる柔軟なコードであることを確認するために、テストカバレッジにエッジ・ケースと境界条件を含めることが重要です。
テストは、確立されたArrange-Act-Assert(AAA)などの標準的なテスト・パターンに従うべきです。
AAAパターンでは、単体テストの実施にあたってコードを整理、準備したうえで、テストの実施に必要なあらゆるステップを実行することが求められます。そして最後に、テスト・ケースを評価し、期待されるテスト結果が得られたかを確認します。
どの程度のコードをテスト可能にできるでしょうか。その割合は、組織固有の事情によって異なります。ただし、テストを目的とするなら、現実的かつ実行可能な範囲で可能な限り高い水準を目指すのが望ましいでしょう。
テスト担当者は、テストカバレッジが70~80%となるよう努め、また定期的にテストを実施する必要があります。
テストはクリーンなテスト環境で実施すべきです。つまり、テスト終了後にシステムを元の状態に戻すテアダウン(後処理)手順を順守する必要があります。
一般的なテアダウン作業には、一時ファイルの削除、グローバル変数の復元、データベース接続の停止などが含まれます。これを怠ると、残留したコード片や設定が後続のテストを妨げ、簡単に失敗を招きます。
単体テストを計画するときは、コードの想定される使用形態を念頭に置いてください。公開インターフェースに加え、コード内の公開プロパティやメソッドもテストが必要です。
テストの目的を明確にするために、公開アプリケーション・プログラミング・インターフェース(API)を構成する要素に限定してテストを実行することを推奨します。
テスト対象のコードの機能と、そのシステムに適用されるビジネス・ルールとは明確に区別されます。実施するテストは、コードの機能そのものだけを評価すべきです。
単体テストに利用できるツールはさまざまです。代表的なものを以下に示します。
現在、コンピューティング全体が人工知能(AI)の処理能力によって変革期にあることは広く認識されています。単体テストもAIの恩恵を受けています。
Javaアプリケーションを開発および配信するためのフルマネージドのシングルテナント・サービス。
DevOpsソフトウェアとツールを使用して、複数のデバイスや環境でクラウドネイティブ・アプリケーションを構築、デプロイ、管理します。
クラウド・アプリケーション開発は、一度構築すれば、迅速に反復し、どこにでもデプロイできます。