- テスト自動化にJUnitというものがあるらしいけどけど、どうやって使うの?
- 会社でJUnitが必須みたいだ。入門者向けに基礎から教えてほしい。
本記事はこのようなお悩みを解決します。
記事の信頼性
現在現役のJavaエンジニア Javaで開発するときは必ずJUnitでテストコードを書いています。
書いたコードが正しく動くのかテストしなければなりませんが、その際に使うフレームワークツールがJUnitです。
今回は、EcipseにおけるJUnit5の設定方法から、実際にJUnit5を使ってテストコードを書いていくまでをご紹介します。
この記事を読むことでJUnitが使えるようになり、コードの品質を担保することができるようになりますよ!
なお、こちらの記事はJavaエンジニアの勉強ロードマップ上の記事でもあります。
まだロードマップをご覧になっていない方は、ぜひ以下の記事を読んでみてくださいね。
Javaエンジニアとしてどのように学んでいったらよいのか、その全体像をつかむことができると思います。
-
初心者・未経験者のためのJavaエンジニアロードマップ
「これから会社でJavaを使うけど、何を勉強したら良いの?」 ...
続きを見る
JUnitに入門しよう
JUnitとはJavaのテスティングフレームワークです。 テストの作成の作成や実行に関する様々な機能(ライブラリ)を提供してくれます。
補足1:テスト・テストコードとは
私もテストのお話を初めて聞いたときは、どのようなものを指しているのか全くわかりませんでした。
そのため、「Javaのテストって何?」と思った方もいらっしゃると思います。
テストとは、自分が書いたソースコードが正しいかを確かめることですよね。
すると、テストコードとはテストの役割を果たしてくれるソースコードになります。
分かりやすく説明するために、以下のコードを考えてみたいと思います。
public class Sample { public boolean judge(int x) { if (x >= 10 && x/2 == 0) { return true; } return false; } }
これは、以下の条件を全て満たすときにtrueを返すメソッドを書いたつもりです(間違っていますが)。
- 10以上である
- 偶数である
このメソッドが正しいかを確かめるソースコードがテストコードです。
例えば、以下のコードはテストコードに当たります。
public class Main { public static void main(String[] args) { Sample s = new Sample(); if ( !s.judge(5) ) { System.out.prinln("OK1"); } if ( !s.judge(15) ) { System.out.prinln("OK2"); } if ( s.judge(50) ) { System.out.prinln("OK3"); } } }
5や15はfalseが帰ってくるので、"!"で打ち消してあげればOK1とOK2が出力されるはずですし、50は10以上かつ偶数なので、OK3が出力されるはずです。
つまり、このテストコードを実行してOKが1~3まで出力されたら、書いたコードは正しそうですよね(本来は境界値の10あたりを細かく見るべきですが、割愛します)。
しかし、実行してみるとOK3が出力されないことに気づきます。
そこでもとのコードを見直してみると、偶数判定に「%」ではなく「/」を使っていることに気づけました。
このように、テストコードを書くことで自分が書いたソースコードが正しいのかをチェックすることができるのです。
ココがポイント
テストコードを書くことでテストを自動実行できる。
自分が書いたコードの正しさを保証できる。
なお、もしこれをJUnitで書くと以下のようなコードになります。
(JUnitの書き方は後ほどご紹介します)
public class SampleTest { Sample s; @BeforeEach public void setUp() { s = new Sample(); } @Test public void 5はfalseを返す() throws Exception { AssertFalse(s.judge(5)); } @Test public void 15はfalseを返す() throws Exception { AssertFalse(s.judge(15)); } @Test public void 50はtrueを返す() throws Exception { AssertTrue(s.judge(50)); } }
補足2: テストコードを書くメリット
テストコードを書く主なメリットは以下のとおりです。
- コードの動作を保証できる
- テストが自動化され、修正時の確認が大変楽になる
テストコードのテスト突破を確認することで、そのソースコードが正しい動作をしていることを保証できます。
また、1度テストコードを作ってしまえば、それを実行するだけでいつでも自動的にテストを行うことができます。
この2番目のメリットが大変大きいです。
ぜひ業務で使用するレベルのソースコードを想像してみてください。
複雑で、1つのメソッドを読む解くのも大変なメソッドを見た経験はありませんか。
もしそんなメソッドを修正することになったとしたら、あなたが修正したメソッドは本当に問題ないのでしょうか。
複雑過ぎて修正が漏れていた、修正が原因で他のところに影響が出た、なんてことがあるかもしれませんよね。
しかし、もしも最初からテストコードを書いていたら、修正を加えたときにそのテストを実行するだけで既存の仕様に影響が出ていないことをすぐに保証できます。
また、今回の修正を保証するテストコードを追加してあげるだけで、未来に後輩が保守をすることになったとしても困ることは少ないことでしょう。
このように、JUnitでテストコードを書くことで保守が楽になるのです。
ココがポイント
テストコードを書くことで動作を保証するだけでなく、将来の保守が楽になる。
EclipseでJUnit5の環境構築
続いて、Eclipse上でJUnit5を環境構築していきます。
といっても、Spring Bootを使用していれば既にJUnit5が含まれていますので、操作は必要ありません。
SpringBootは2.5.0を使用しています。
2.5.0よりもバージョンが小さい場合はJUnit4が使われている可能性があります。
※STSのバージョンは4.10.0
pom.xmlを載せておきます。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.0</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>15</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
JUnit5の基本的な使い方
JUnit5の基本的な使い方をご紹介します。
step
1クラスと、対応するテストクラスを作成
まずは、SampleクラスとSampleTestクラスを作りましょう。
Sampleクラスのjudgeメソッドは引数が偶数ならtrueを返すメソッドです。
public class Sample { /** * 引数が偶数ならtrueを返す */ public boolean judge(int x) { if (x % 2 == 0) { return true; } return false; } }
このSampleクラスに対して、SampleTestクラスを作ります。
注意点として、以下の画像のようにsrc/test/javaディレクトリの配下に作りましょう。
SampleTest.javaのコードです。文法は後ほどご紹介します!
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class SampleTest { Sample s; @BeforeEach public void setUp() { s = new Sample(); } @Test public void judgeに5を渡すとfalse() throws Exception { assertFalse( s.judge(5) ); } @Test public void judgeに8を渡すとtrue() throws Exception { assertTrue( s.judge(8) ); } }
step
2実行する
テストコードを書いたら、あとは実行するだけです。
プロジェクトを右クリック > Run As > JUnit Test を押してください。
すると、「JUnit」というビューが現れ、このような結果が出てくると思います。
緑色のゲージが出ていたら、すべてテストが成功した証拠です。
JUnit5の文法
先ほどのSampleTestクラスには見慣れないアノテーションがたくさんありましたよね。
それらをすべてご紹介していきたいと思います。
ここにあるのはJUnit5を使用するうえで最も基本的なアノテーションですので、しっかり覚えていきましょう。
@Testアノテーション
@Testアノテーションはメソッドにつけることができます。
JUnit Testはこのアノテーションがついたメソッドを実行していくので、必ずつけましょう。
@BeforeEachアノテーション
@BeforeEachアノテーションは、それぞれの@Testが実行される前に実行されます。
つまり、すべてのテストで初期化処理をしたいときに使います。
先ほどのコードでは、Sample型の変数sにSampleインスタンスを入れていましたよね。
Sample s; @BeforeEach public void setUp() { s = new Sample(); }
テストの考え方として、「テストの結果がほかのテストに影響を及ぼしてはいけない」というものがあります。
そのため、Sample s = new Sample();をあらかじめ外に書いておいて@Testメソッドでsを使いまわす、というのは(今回の例では別に影響はありませんが)テストの考え方としてアウトなのです。
そんなとき、@BeforeEachを使ってそれぞれのテストメソッドに対して初期化処理を入れていきます。
assertTrue
assertTrue()は、引数がtrueならテストを成功させる(falseなら失敗させる)というメソッドです。
このメソッドによりテストの成否を判定することができます。
JUnitにはassertシリーズが他にも多くあり、ほかによく使われるのはassertEquals()ですね。
ぜひそのほかのassertシリーズを調べてみてください。
その他
- テストメソッドには日本語を書く
- 本来タブーなthrows Exceptionを使っている
あたりもテストコードの特徴ですね。
まとめ
JUnit入門として、JUnitとは、環境構築、文法の3つをご紹介しました。
ココがポイント
- JUnitでソースコードの品質を保証できる
- 将来の保守を楽にできる
- SpringBootですぐに使える
- assertなど独自文法を学ぶ必要がある
これらを押さえることができたら、JUnit入門は完了です。
今回ご紹介した内容は入門的なものですが、実はこの知識だけでも十分業務で通用するテストコードを書くことができます。
なお、もしJUnitをもっと学びたいと思った方は以下の本がおすすめです!
JUnit実践入門 ── 体系的に学ぶユニットテストの技法 WEB+DB PRESS plus
個人的には緑色のJUnit実践入門が分かりやすく実践的だったので、初心者の方はそちらがおすすめですね。(オライリーでは、テストコードの思想を学ぶことができました。)
ぜひJUnitを使って品質の高いプロダクトを開発しましょう!
最後までお読みいただきありがとうございました。