Javaによる大規模システムの開発において、従来のウォーターフォール型から、アジャイル型の開発手法を採用するプロジェクトも増えてきました。
アジャイル開発などでよく採用される、テストコードとプログラムコードを並行して書き進めていく手法を採る場合、テストを効率良く進めるためのツールとしてテストフレームワークの活用が勧められます。
今回は、Javaのテストフレームワークの中から「JUnit」「Checkstyle」「FindBugs」をご紹介。
これらを活用するメリットや導入時の注意点について解説していきます。
- もくじ
1.Javaの特徴と単体テストの重要性
Javaは、大規模システムの開発やアプリケーション開発に適した言語です。
Javaで記述されたプログラムは、Java仮想マシン(JVM:Java Virtual Machine)によって実行されるため、OSに依存せずに同じ動作をさせることができます。
この章ではjavaの特徴と、単体テストの重要性について解説します。
Javaの特徴
オブジェクト指向言語であるJavaでは、データの処理や集まりをそれぞれ1つのモノ(オブジェクト)として扱います。
開発者はプログラムの処理や手順の理解ではなく、モノそれぞれを利用することで何ができるか・どんな結果が得られるか、ということを理解すれば良いのです。
大規模なシステムを大人数で開発をする際には、プログラムの全ての内部構造や処理を理解していなくても、それぞれのモノの役割さえ分かっていれば実装を進めることができます。
Javaにおける単体テストの重要性
処理やデータの集まりを単位とし、それらが正確に動いて決められた処理を提供することが前提となるJavaにおいては、モジュールやメソッド単位のプログラムの動きが担保されることが品質保証のベースとなるため、単体テストが重要な意味を持ちます。
単体テストとは、プログラムの構成要素である関数やメソッドなどの単位(ユニット)が、それぞれ意図した通りに正しく動いているかを検証する、主に開発者が行うテストです。
単体テストを行うことで、不具合箇所の特定や修正がしやすくなります。
一方で、大規模システムではユニットの数が膨大になり、単体テストの負担が重くなることが多いため、テストの実行や結果の確認を自動化するテストフレームワークが用いられます。
次章から、Javaのコーディングや単体テストでよく使用される、「JUnit」「Checkstyle」「FindBugs」と呼ばれるテストフレームワーク、テストツールを紹介していきます。
2.単体テスト自動化フレームワーク「JUnit」
「Junit(ジェイユニット)」とは、Java開発で用いられるオープンソースのテストフレームワークです。
JUnitが提供するテストメソッドを用いて、テストの期待値とテスト結果の比較、およびコード・カバレッジの可視化ができます。
JUnitのメリット
作成したテストコードは自動で実行できる上、エラーがあった場合はエラーの場所やどのようなエラーなのかが分かるため、テストの負荷を減らすことができます。
前に実行したテストは再度実行できるため、デグレード検知のためのリグレッションテスト(回帰テスト)の自動化やリファクタリングの実施も容易です。
また、Javaの統合開発環境の1つであるEclipseをインストールすると、JUnitプラグインも一緒にインストールされるため、JUnitを導入するハードルは比較的低いでしょう。
JUnitのデメリット
JUnitにはメリットだけでなく、デメリットもあります。
例えば、JUnitにおける各テストは独立性を前提としており、他のユニットと依存関係にある関数やメソッドを続けてテスト実行する場合は、テストの実行順序を定義するために時間がかかってしまいます。
また、プログラムの例外処理が正しく機能するかをテストする際には、テストコードが複雑になり、テスト作成者はある程度テストコードを書き慣れている必要があります。
JUnitには上記のようなデメリットもありますが、基本的にJUnitは活用する対象を厳選して継続的に修正していけば、高い効果を出せるツールであり、大きな開発プロジェクトになるほどそのメリットを発揮します。
3.静的解析ツール「Checkstyle」と「FindBugs」
ここからは、静的解析ツール「Checkstyle」「FindBugs」を比較しながら双方の特徴をご紹介します。
コーディング規約のチェックツール「Checkstyle」
Checkstyleは、ソースコードにおけるコーディング規約をチェックするための静的解析ツールです。
システムのコードにおける中括弧(かっこ)や空白のスペースの記述などコーディングスタイルに関する指摘のほか、クラス名、定数、変数など命名規則がコーディング規約として定義された規則に従い、正しく記述されているかを確認します。
後ほど紹介する「FindBugs」と比べると、コーディングスタイルや命名規約のチェックが優れているツールです。
【Checkstyleの特徴】
- ソースコードが解析対象
- コーディング規約に基づいたルールの提供
- 適用するルールのカスタマイズが可能
- カスタムルールの追加が可能
ソースコードの様々な側面をチェックすることが可能です。
クラス設計問題、メソッド設計問題を見つけることもでき、コードレイアウトや書式設定の問題をチェックする機能もあります。
潜在的なバグをチェックする「FindBugs」
FindBugsは、潜在的なバグをチェックし予防することができる静的解析ツールです。
特定のコードパターンに合う部分をプログラムから抽出してバグの可能性を示すことにより、強化されたコードをチェックすることができます。
メソッドのパラメーターをnullチェックを行わずに使用しているNullPointerException(プログラミング言語Javaにおける例外の1つ)が発生する可能性などを指摘してくれるため、ケアレスミスによるバグ混入を予防することが可能です。
上段で紹介したCheckstyleに比べると、より潜在的なバグの検出を得意とするツールといえます。
【FindBugsの特徴】
- 潜在的なバグに特化したルールを提供
- バイトコードが解析対象
- 適用するルールの選択が可能
- ルールの拡張は困難
FindBugsは、バイトコードスキャンニングチェック機能を用いてカスタムルールの作成を実施することができます。
BCEL(Byte Code Engineering Library)を利用してチェックする機能を実装するため、簡単なルールの作成であっても多くの時間と検証を必要とします。
2つのツールは組合せて使用するのが効率的
2つのツールは組み合わせて使用することで効率良く扱うことができます。
あらかじめ各ツールの特性を理解した上で、不要なルールの削除やプロジェクト固有のルール作成などカスタマイズをする必要があります。
ツールができることは極力ツールで行い、目視チェックレビューへ問題を持ち越さないことが、システム開発の効果的なサポートにつながるでしょう。
4.現場でテストフレームワークを導入するためには
テストフレームワークの導入には多くの利点がありますが、導入する前提条件として以下の点を考慮しておきましょう。
- 導入に伴うテストコードの作成の負担があること
- 開発者がフレームワークに習熟していること
- メンテナンスを継続するための組織的な仕組みづくりがされていること
フレームワークを導入する際は、まずは導入したいテストと対象のプログラムを絞って部分的に導入し、状況を見ながら段階的に対象範囲を広げていくと良いでしょう。
また、特定のテストツールでは作成できない種類のテストもあるため、他のフレームワークとの併用も視野に入れておきましょう。
例えば、JUnitではデータベースの接続や操作をテストすることはできません。この場合は、DBUnitなどの別のフレームワークを利用する必要があります。
テストの品質を上げながら開発者の習得コストを下げるためにも、一般的に普及しているフレームワークを選定することをおすすめします。
フレームワークごとの特性や仕様を把握し、チーム内にノウハウを蓄積していくことが重要です。
まとめ
今回はJavaでの開発に活用できるテストフレームワーク、「Junit」「Checkstyle」「FindBugs」についてご紹介しました。
特に大規模開発における単体テストの効率化には、フレームワークの活用が有効です。
ただし、フレームワークの導入には、フレームワークの学習やテストコードの作成など、開発者の負担増加も懸念されます。
開発スケジュールやプロジェクトの規模を考慮した上で、段階的な導入および複数のフレームワークの併用をおすすめします。