単体テストのベスト・プラクティス11

2台のモニターを使用しノートパソコンで作業する男性。

執筆者

Phill Powell

Staff Writer

IBM Think

Ian Smalley

Staff Editor

IBM Think

単体テストのベスト・プラクティスとは?

単体テストのベスト・プラクティスは、各テストを相互に独立した分離環境で実行し、決定論的で一貫性のある特性を示すように記述することを支援します。

優れた単体テストはテスト駆動開発(TDD)を反映し、依存関係の排除を支援するためにモック・オブジェクトとスタブを使用します。ベスト・プラクティスでは継続的インテグレーション自動テストにも対応します。

単体テストとは何ですか?

多様なテストの中でも、単体テストはコードの最小単位(ソフトウェア・テストで評価対象となる最小の構成要素)に、ほぼ顕微鏡的な視点を与えます。適切な単体テストの鍵は分離であり、ユニットの関数を効果的に評価できるようにするために不可欠です。

単体テストの利点として、自動化によるソフトウェア開発の加速や、デバッグソフトウェア開発ライフサイクル(SDLC)の早期に組み込むことで人件費を削減できる点が挙げられます。こうしたデバッグの取り組みは、開発中に行ったコード変更の定着を後押しし、全体を通じてコード品質を高めます。

単体テストフレームワークは、テスト担当者が個々のユニットに対してテストを実行し、コードベース全体をより強固なものにするのに役立ちます。テストで特定のコードをチェックし、テストが適切に実行され、関連するチェック(アサーションとも呼ばれます)がすべて正常に実装されていることが確認されることでテストの合格となります。テストの合格は、ユニットが期待どおりに動作していることを示しています。

The DX Leaders

AI活用のグローバル・トレンドや日本の市場動向を踏まえたDX、生成AIの最新情報を毎月お届けします。登録の際はIBMプライバシー・ステートメントをご覧ください。

ご登録いただきありがとうございます。

ニュースレターは日本語で配信されます。すべてのニュースレターに登録解除リンクがあります。サブスクリプションの管理や解除はこちらから。詳しくはIBMプライバシー・ステートメントをご覧ください。

依存関係とは

単体テストは、説明が必要なさまざまな側面がある、多面的なトピックです。その1つが依存関係に関するものです。単体テストにおいて依存関係とは、コードのユニットが適切に動作するために必要な外部のサービスやコンポーネントを指します。

信頼でき、保守しやすいテスト(すなわち、コードベースの進化全体を通じて長期的に有効で柔軟かつ有用なテスト)を書くためには、依存関係を適切に管理することが重要です。

依存関係をうまく管理できれば、期待どおりに動作する、より強固で信頼性の高いテスト・スイートを構築できます。開発者は依存性の注入(Dependency Injection、DI)を用いて、依存関係に関わるコードをコードベースに挿入(「注入」)します。

アプリケーション開発

さあ、クラウドでエンタープライズ・アプリケーション開発を始めましょう

この動画では、Peter Haumer博士が、IBM Z Open Editor、IBM Wazi、Zoweなどのさまざまなコンポーネントとプラクティスを実演しながら、ハイブリッドクラウドでの最新エンタープライズ・アプリケーション開発について説明します。

単体テストの11のベスト・プラクティス

ここで示す各テスト戦略はベスト・プラクティスを支え、実践的なテスト手法のスタイルを反映しています。

1. モックとスタブを活用する

テスト環境では、テストに必要な深い分離を実現するために、モックやスタブの活用が欠かせません。

モック・オブジェクトは実体の重複物として機能し、深い分離下で模擬オブジェクトを用いることで、実オブジェクトの想定される挙動を評価するのに役立ちます。

スタブは、コンポーネント、ファイル・システム、データベースなどの外部依存との想定される相互作用に関するデータを提供します。

2. 極端な使用パターンを研究する

エラー検知は単体テストにおいて中核となる部分です。テスト担当者は、ユニットの動作パラメーターや境界値近くで発生する極端な使用パターンを評価します。これらはエッジ・ケースと呼ばれ、境界値外への配列アクセスなど、すぐには発見できない場合があります。そのような場合に、テスト担当者は、項目のインデックスが当該インデックスの最大許容値を超えていることを検知します。

このような場合、テスターはしばしばコードをリファクタリングする(既存の機能を保ったままコードを再構成する)必要に迫られます。

3. CI/CDパイプラインを活用する

テスト機能を自動化する継続的インテグレーション/継続的デリバリー(CI/CD)パイプラインは、テストプロセスにとって非常に重要です。

CI/CDパイプラインを実行すれば、コード変更のたびに自動単体テストをいつでも走らせることができます。自動テストは開発プロセスの早期に不具合を検知し、コード品質の担保に寄与します。

4. 短く、シンプルに、迅速にテストを行う

テストの保守性には多くの要因が影響します。保守しやすいとみなされるために、テスト・コードには高い可読性、全体を通した明確さ、そして適切な識別(命名)手法が求められます。要するに、テストは本番コードと同等の品質基準で作成すべきです。

特定のモジュールを扱う小規模で目標が明確なテストとすることも必要です。また、テストが高速であればより迅速かつ頻繁に実施できるため、スピードを念頭に置いてテストを作成する必要があります。

5. 命名規則に注意する

適切な命名規則を守らないと、他は優れたテストであっても容易に埋もれてしまいます。テスト名は簡潔でありつつ、対象を十分に説明できる表現を含め、必要なときに検索・想起しやすいようにします。「Test-1」のようなラベルでは、何をなぜテストしているのかが分からず不十分です。

6. あらゆる不測の事態に備えてテストを作成する

堅牢なコードベースを構築するには、楽観的シナリオと悲観的シナリオの両方を想定したテストを行う必要があります。楽観的シナリオの場合、テスト担当者は有効な入力を確認するテストを追加する必要があります。悲観的シナリオの場合、テスト担当者は予期しない、または無効な入力を予測する必要があります。

また、あらゆる状況に対応できる柔軟なコードであることを確認するために、テストカバレッジにエッジ・ケースと境界条件を含めることが重要です。

7. AAAパターンに従う

テストは、確立されたArrange-Act-Assert(AAA)などの標準的なテスト・パターンに従うべきです。

AAAパターンでは、単体テストの実施にあたってコードを整理、準備したうえで、テストの実施に必要なあらゆるステップを実行することが求められます。そして最後に、テスト・ケースを評価し、期待されるテスト結果が得られたかを確認します。

8. 完全かつ頻繁にテストする

どの程度のコードをテスト可能にできるでしょうか。その割合は、組織固有の事情によって異なります。ただし、テストを目的とするなら、現実的かつ実行可能な範囲で可能な限り高い水準を目指すのが望ましいでしょう。

テスト担当者は、テストカバレッジが70~80%となるよう努め、また定期的にテストを実施する必要があります。

9. テスト環境を復元する

テストはクリーンなテスト環境で実施すべきです。つまり、テスト終了後にシステムを元の状態に戻すテアダウン(後処理)手順を順守する必要があります。

一般的なテアダウン作業には、一時ファイルの削除、グローバル変数の復元、データベース接続の停止などが含まれます。これを怠ると、残留したコード片や設定が後続のテストを妨げ、簡単に失敗を招きます。

10. 公開インターフェースのテストを忘れずに行う

単体テストを計画するときは、コードの想定される使用形態を念頭に置いてください。公開インターフェースに加え、コード内の公開プロパティやメソッドもテストが必要です。

テストの目的を明確にするために、公開アプリケーション・プログラミング・インターフェース(API)を構成する要素に限定してテストを実行することを推奨します。

11. コードの機能に沿ったテストを実行する

テスト対象のコードの機能と、そのシステムに適用されるビジネス・ルールとは明確に区別されます。実施するテストは、コードの機能そのものだけを評価すべきです。

単体テストのツール

単体テストに利用できるツールはさまざまです。代表的なものを以下に示します。

  • Jest:経験豊富な開発者と(使いやすさを重視する)初心者の両方に好まれるJestのフレームワークは、ReactとJavaScriptのコンポーネントを分析します。最小限の設定時間と迅速なテスト作成で、設定を必要としないテスト体験の提供を目指しています。もう1つの優れた点は、テスト・カバレッジの報告と検証の対象となるコード総量の評価方法にあります。
  • JUnit: Java™のコンポーネントを評価する場合、JUnitが選ばれることが一般的です。JUnitはコードの整理を容易にし、柔軟な修正と高精度のエラー検知を可能にします。多用途性を重視する組織にとって、JUnitは大いに力を発揮します。テスト・プロセスの効率化に加え、システム全体の結合テスト機能テストでも活用できます。
  • Pytest:Pytestを使用すれば、Pythonで書かれたテストの作成と実行を簡単に管理できます。Pytestは単体テスト、結合テスト、機能テスト、エンドツーエンド・テストにも使用できます。また、テストのパラメータ化をサポートする機能を備えていることでも知られています。この機能により、コードを複製することなく、同じテストを異なる変数で実行できます。
  • xUnit:C#の開発者は、人気のあるオープンソースの単体テストフレームワークのxUnitを使用することが多いです。開発者は、コンポーネントテストに必要な、徹底的に分離された環境を構築できる点で、そのテスト環境が最適であると高く評価しています。他のテストツールとの連携もスムーズで、シームレスなテストワークフローを実現します。xUnitの構文は、テスト作成を単純化するのに役立つ。

AIが単体テストに与える影響

現在、コンピューティング全体が人工知能(AI)の処理能力によって変革期にあることは広く認識されています。単体テストもAIの恩恵を受けています。

  • 包括的なテストカバレッジ:単体テストの最も重要な点はエラーの検出であり、AIは人間のテスト担当者が見逃す可能性のあるエラーを発見することができます。さらに、AIは時間の経過とともに学習する「自己修復」テストを作成できます。これは大きな進展です。
  • テスト作成の増加:テスト担当者は、流動的かつニーズが急速に変化しやすい状況下で本番環境を構築します。幸いなことに、開発チームがスケジュールを守れるよう、一連の単体テストを開発するなど、AIは複雑なことをすばやく実行できます。
  • 継続的なフィードバック: AIを活用すると、開発環境の利用が円滑かつ強力になり、DevOpsやCI/CDパイプラインも強化されます。テスターが即座に得られる利点は継続的なフィードバックであり、それが開発サイクルの高速化につながります。
  • 専門的なテスト分析:AIを活用すれば、テスト担当者は実行できるテストの種類の幅を大きく広げることができます。たとえば、AIはテストが失敗した根本的な原因を判断するために根本原因分析を行えます。またAIは、コードパターンと履歴データを使用して将来のテスト障害を予測する、事前テスト障害分析のようなより複雑なテストを実行できます。
関連ソリューション
IBMのエンタープライズ向けJavaアプリケーション・サービス

Javaアプリケーションを開発および配信するためのフルマネージドのシングルテナント・サービス。

Javaアプリの詳細はこちら
DevOpsソリューション

DevOpsソフトウェアとツールを使用して、複数のデバイスや環境でクラウドネイティブ・アプリケーションを構築、デプロイ、管理します。

DevOpsソリューションの詳細はこちら
エンタープライズ・アプリケーション開発サービス

クラウド・アプリケーション開発は、一度構築すれば、迅速に反復し、どこにでもデプロイできます。

アプリケーション開発サービス
次のステップ

IBM Cloudアプリケーション開発コンサルティング・サービスは、クラウド戦略を合理化するための専門家のガイダンスと革新的なソリューションを提供します。IBMのクラウドおよび開発のエキスパートと提携して、アプリケーションをモダナイズ、拡張、高速化し、ビジネスに変革をもたらします。

アプリケーション開発サービスの詳細はこちら IBM Cloudを無料で構築開始