読者です 読者をやめる 読者になる 読者になる

単体テスト(ユニットテスト/UT)で考えること

単体テスト(ユニットテスト/UT)で考えることを雑に書きます。


コードを書くときはテストしやすい粒度でメソッドを分割する。

以下の場合、なにも意識しないと execute 内にすべての処理を書きがち。1メソッドの処理が長くなるとテストがやり辛くなる。

これをある程度まとまりのある処理で foo, bar などにメソッドを分割して execute から呼び出すようにする。そして、foo, bar に対してテストを書くようにすればテストコードにまとまりができて構造化し易くなる。 また、分割したメソッドのアクセス修飾子はパッケージプライベートにして、テストクラスは同一のパッケージに配置する。

public void execute(String arg) {
    Hoge hoge = foo(arg);
    Fuga fuga = bar(hoge);
}

Hoge foo(String arg) {
    // ...
}

Fuga bar(Hoge hoge) {
    // ...
}

ただ、メンバーのスキルだったり開発環境の要因でテストコードが十分に準備できないことがあるかもしれないので、必ずテストコードを書くということは考えない。
(そこを無理してやろうとすると、コストが膨れ上がるリスクがある気がするので無理はしたくない)

こういうときは人手でテストすることになるが、当然自動化みたいなことはできないので観点を挙げてテストすることが重要。
状況によってはスタブなどは事前に用意する必要はある。

余談

Java ではクラスやメソッド、変数に日本語 (Unicode) が使えます。まぁ、実際に使うことはないだろうと思っていましたが、『JUnit実践入門 - 体系的に学ぶユニットテストの技法』ではメソッドが日本語で書かれています。(最初、見たときは目から鱗だった...)

日本語なら書きやすいと思って「引数に xxx を指定した場合は hoge を返すこと」のようにメソッド名を付けるわけですが、日本語ですらどんな名前を付けようか迷うことがあります。

大抵、こういう場合は処理内容が複雑になり過ぎていることがあるので、リファクタリングすることを検討します。

これはテストに限った話ではなく、普段からコードを書くときに命名に迷うことがあればどこか構造的におかしい部分がある、と考えるようにしています。

あと、割と昔から JUnitJMockit の組み合わせ使っていますが、逆に言うとこれ以外はあまり使ったことがない...。