Powered By Blogger

2013年6月24日月曜日

JUnitについて改めて気になった点について書いてみる

日頃JUnitを使用していますが、改めてユニットテストについて学ぼうと思いこちらの文献を参考にしました。


日本語のメソッド名を使う

日本語でソフトウェアを開発するなら、日本語でテスト内容を把握できるほうがメリットが大きいというものです。

メソッド一覧はJavadocに出力すればテスト項目の一覧になるし、何よりもメリットなのは日本語で記述してあることによって理解しやすくなるということです。

クラスのアウトラインを利用すればテストクラスでなにを行っているか簡単に理解できるし、テストが失敗したときも失敗したメソッドが日本語で出力されるので、より理解しやすくなります。
下手な英語でメソッド名を記述しわかりにくくなるより、いっそのこと日本語で記述する方針でもいい気がしました。

テストクラスの命名規則

Hogeというオブジェクトのテストクラスを作成する場合、HogeTestとするのが一般的である。

値の比較検証はassertThatを使用する

AsserクラスにはassertEqualsやassertTrueメソッドといった多くのアサーションメソッドが定義されています。しかし、これらのアサーションメソッドはJUnitの古いバージョンとの互換性のために残っています。
JUnit4で利用するアサーションメソッドはassertThatメソッドもしくはfailメソッドの2つと考えていいでしょう。

従来のアサーションメソッドより以下のような利点があります。
  • 可読性が高く、何を比較するかがよくわかる
  • フェイラーメッセージの出力が理解しやすい
  • 比較処理の部分を他の比較処理と組み合わせ、否定、コレクションのマッピングなどとの組み合わせなど、さまざまな組み合わせを指定できる
  • 比較処理を自ら実装して使うことができる


結果が一定でないテストを避けること

ユニットテストでは常にすべてのテストが成功しているようにするというもの。
成功しないテストを放置する状態や、実行毎に成功するか失敗するかわからないテストがある状態は望ましくないということです。


ドキュメントとしてのテスト

テストケースは開発者が想定しているさまざまなユースケースを記述したものです。
テストが成功する限り、テストケースで定義されている動きは保障されます。
したがって、テストケースはもっとも正確なドキュメントであるということです。


問題の局所化

テストケースは十分小さな単位で可能な限り多く作るべきです。
何らかの原因でテストが失敗したとしても、影響範囲と条件が絞り込みやすくなるからです。


不明瞭なテスト

テストコードは可能な限りシンプルに記述するというもの。
複雑になっていると、テストコードが読みにくく、読みにくいコードはメンテナンス性も悪くテストの質に大きく影響を与えます。


独立したテスト

テストケースは可能な限りお互いに影響を与えないように定義すべきです。

テストランナー

テストの実行に関するカスタマイズ要件を満たすためにテストランナーという仕組みを提供しています。デフォルト(省略した場合)ではJUnit4クラスが利用されます。
テストランナーにはいくつかありEnclosed(構造化したテスト)、Theories(パラメータ化したテスト)などがあります。また、独自のテストランナーも実装することが可能です。


テストクラスの構造化

テストクラスの命名規則(Hogeクラスがテスト対象ならば、テストクラスはHogeTestクラスとなります)でテストクラスを作成し、テストクラスを追加していくと、テストクラスが非常に大きくなってしまいます。
テストケースが増えてきたならば、何らかの基準でグループ化し、テストクラスを構造化することによって可読性を高く保つことができます。

グループ化する方針としては大きく分けて下記のような2つがあります。

  • 検証する操作(メソッド)単位でグループ化する
  • 共通の初期化処理を含むものでグループ化する

テストクラスを横断する共通処理

テストクラスの構造化によって、テストクラス内の共通処理はきれいに整理できます。
しかしながら異なるテストクラス間で共通した処理は整理できません。
このような場合、共通処理をユーティリティクラスに抽出し、ユーティリティクラスを利用するようにします。

パラメータ化テスト

Theoriesクラスを使用して行う。

パラメータのフィルタリング

パラメータ化によるテストは強力ですが、すべての組み合わせについて実行します。
org.junit.Assumeクラスを利用すると、特定の条件を満たすパラメータをフィルタリングできます。

ルールの連鎖

RuleChainクラスによって、複数のルールを連鎖させることができます。
ルールの実行順序の制御も可能です。

スローテスト問題

テストの実行に長い時間がかかること。

テスタビリティ

テストのしやすさ。

テストダブル

依存する機能がユニットテストで扱いづらい場合や、ユニットテストの独立性を高めたい場合に、
依存するオブジェクトをスタブやモックに置き換えること。

Mockito

簡単にスタブオブジェクトを作成できるライブラリ。
また、モックオブジェクトにおるメソッド呼び出しの検証なども行うことができる。

何%のカバレッジを目標にすべきか?

カバレッジの値を高くすることを目標にしてはいけない。
カバレッジは、プロダクションコードの実行網羅率を示す指標でしかないため、カバレッジが高くても品質は保証されません。

80~90%程度に設定するプロジェクトが多い。




1 件のコメント:

  1. こんばんは。

    テスティングフレームワーク、どんどん使いたいです!

    返信削除