実行時解析でユニットテストをもっと効率的に

実行時解析によってユニットテストの実行をモニターし、ユニットテストの効率を改善することができます。ユニットテストの実行時解析は、テストの効果と効率を改善するうえで重要です。

ユニットテストはソフトウェアの個々のユニット/コンポーネントをテストするベストプラクティスですが、Java開発者にとって手間や負担が大きい場合もあります。手動でアサーションを作成して個々のユニットが正しく動作しているかをテストしたり、モックによって各メソッドを分離したりするのは大変なうえ、ユニットテスト自体にもバグや誤解による不正な動作が入り込む可能性があります。実行時解析ツールを使用してデータ/制御フローおよび外部依存関係の検出やテストコードのカバレッジの計測を行うと、このような状況を改善できます。Parasoft Jtestのようなエンタープライズグレードのソリューションは、実行時解析で収集されたデータを利用して、動作検証用のアサーションやテストの分離を促進するためにモック化できるメソッドを推奨するなど、開発者にテストの改善方法を示します。このように、自動ユニットテスト生成と実行時解析を統合すると、Javaのユニットテストで人手による介入の必要が少なくなります。

ユニットテストの利点

ユニットテストはよく知られたプラクティスですが、実践するとなると、多くのプロジェクトでは改善が必要です。ユニットテストを適切に実施すれば、アジャイルプロセスのアジリティが改善され、品質とセキュリティが向上し、長期的にはコスト削減が実現します。
このような利点にもかかわらず、残念ながら、開発者はよりよい結果を求めながらも依然としてユニットテストに苦労しているという状況もあります。テストの作成とメンテナンスに時間と労力がかかりすぎ、テスト作業が増えるいっぽうでメリットが感じられない場合もあるかもしれません。依存関係からのユニット/オブジェクトの分離が十分でないため、テストスイートが壊れやすいこともよくあります。依存関係を適切にモック化するのがソフトウェアテスターにとって悩みの種となりますし、プログラムロジックが正しいかどうかを判断するために必要なアサーションの作成も同様に課題となります。複数のシナリオに対応してテストをパラメータ化するのさえ、面倒で時間がかかる場合があります。
ユニットテストの恩恵を受けるには、テストの作成・分離・メンテナンスにまつわるこれらの問題に対処する必要があります。それにはまずテスト自動化ツールを利用することですが、単にテストの実行を自動化し、結果を収集するだけでは十分ではありません。実行中のモジュールを観察し、キーとなるメトリクスを記録する実行時解析は、ユニットテストの作成・モック化・テストの安定性の向上に役立つ革新的な方法です。

実行時解析がユニットテストを改善する

多くのケースで、実行時解析はユニットテストの早期ステージにおいて重要とみなされていません。たいていのツールは、ユニットテストで見逃されたエラーを捕捉したり、単にコードカバレッジを計測するためにだけ使用されています。これらの利点も重要ですが、実行時解析はユニットテストの初回の実行をモニターし、テストの改善に関する推奨事項を提示したり、テストの安定性に影響を及ぼすテスト実行環境の変化を検出したりすることもできます。JUnitなどのテストフレームワークが作成するコードは貧弱なため、開発者が記述を足す必要があります。これは単調な作業であるため、観察されたプログラムロジックに基づいてより詳細な内容まで自動で入力することができます。たとえば、Parasoft Jtestは次のユニットテストを自動生成できます。

同様に、入力がパラメータ化されたユニットテストの場合は次のようになります。

作成されたテストは最初から実行可能なため、実行時解析で結果と実行フローをモニターできます。たとえば次のように、テストが例外をスローしたために失敗するケースがあります。

実行時解析による依存関係の検出とモック化

さらに、実行時解析ツールは実行パスをモニターして依存関係を検出し、テストの分離を促進するためにモックできる可能性がある候補を提示します。テスト対象オブジェクトの視覚的な検査でも依存関係を明らかにできますが、依存関係の検出とモック化を自動化することで、退屈で誤りやすい作業の多くを省くことができます。

次のサンプルのように、Parasoft Jtestでは、ユニットテストの実行トレースに基づいて何をモック化すべきかを選択できます。

このケースでは、モック可能なメソッドのパターンを追加すると、PowerMockなどのモックフレームワークが処理するべきモックのリストにメソッドが追加されます。
次のように、静的コンストラクターをモック化することも可能です。

実行時解析によるテストの妥当性の向上

実行時解析は実行フローに加えてメソッド呼び出しで使用されたパラメーターを完全に把握しているため、テストコードを改善するのに有益な推奨事項を提示できます。テスト作成時に静的にアサーションが指定されていても、アサーションが無効だったり誤っている場合もあります。テスト実行時にアサーションが失敗したりアサーションが存在しない場合に警告を発し、後で問題を修正するための推奨事項を案内します。
たとえば、新規テストを作成した後、推奨されたアサーションのコメントが解除されていない場合、次のように表示されます。

また、アサーションが失敗した場合は次のように表示されます。

いずれの場合も、アサーションの修正アクションに関する継続的なフィードバックであり、これによってテストの作成からユニットテストの完了までのループが完成します。また、テスト対象ユニットが変更された場合、変更も同じように処理することができるため、手動でのテストのメンテナンス作業を継続的に削減できます。

実行時解析によるテストの安定性の向上

実行時解析は、後続のテストで同一のテスト環境を再現できるかどうかに影響を与える実行時のテスト環境の変化も検出できます。いったん成功したテストが後で失敗するのは、フラストレーションと時間や労力の無駄を引き起こす大きな原因になります。実行時解析で検出できる不安定性の例としては、以下が挙げられます。

  • テスト中にシステムプロパティが変更され、元の状態に戻されていない。後続のテストはこのプロパティに依存している可能性があります。
  • 別の実行スレッドがテスト実行に干渉する可能性がある
  • テスト実行中に新規ファイルが作成され、後続のファイルがそのコンテンツに依存している場合、影響を受ける可能性がある
  • 静的フィールドの変更が同じフィールドを使用する後続のテストに影響を与える可能性がある

テスト結果の信頼性を保証するには、各テストが同一の状態から実行されることが重要です。実行時解析によってテストの不安定性を防止すると、デバッグフェーズであれこれ推量する必要がなくなります。
このように、実行時解析は単にコードカバレッジを計測するにとどまりません。テスト時の実行解析は、テストの効果と効率を改善するうえで重要です。実行パスをモニターすることで、依存関係の情報が得られ、依存関係およびモックの処理が向上します。アサーションをモニターし、自動推奨を利用すると、テストの妥当性が向上します。テストの安定性に影響を与える実行時テスト環境の変化を検出することで、フラストレーションとテストコードのデバッグにかかるサイクルを軽減できます。

(この記事は、開発元Parasoft社 Blog 「Get More Benefits of Unit Testing with Runtime Analysis」2018年11月2日の翻訳記事です。)

Parasoft Jtestについて

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

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

Top