JUnitは、Javaプログラムの単体テスト(ユニットテスト)を効率的に行うためのツールやライブラリの集合体です。Junitを用いることでテストコードの作成/実行/管理が簡単になり、またテストの自動化もサポートしているため、繰り返し実行するテストを手動で行う手間を省くことも可能になります。
ポイント JUnitとは?
- ツールやライブラリの集合体
- JUnitはテストのための様々な機能を提供するツールやライブラリのセット。
- 効率的なテスト
- JUnitをプロジェクトにインストールして利用する。→テストメソッドの自動認識、テスト結果のレポート、セットアップとクリーンアップの自動化など、多くの便利な機能を利用可能になる。
- テスト自動化
- JUnitはテストの自動化をサポート。繰り返し実行するテストを手動で行う手間を省き、バグの早期発見やコードの品質向上に寄与する。
このページではJunitとは何か?を説明しつつ、Junitの使い方を1からわかりやすく解説します。
関連 Javaの1stステップ:基本的な構文ルールを1分で復習!
Junitとは?
JUnit(読み方:じぇーゆにっと)は、Javaプログラムの単体テストを行うためのオープンソースのフレームワークです。単体テスト(ユニットテスト)とは、プログラムの個々の部分(ユニット)が意図した通りに動作するかどうかを検証するテストのことで、JUnitはこれを支援するための多くの機能を提供します。
イメージをつかむために、簡単なプログラムと、それに対応するJunitを用いたテストプログラムを先にお見せします。
サンプルコード Calculatorクラス(参考:Javaのクラスの使い方)
public class Calculator { public int add(int a, int b) { return a + b; } }
サンプルコード Junit「CalculatorTestクラス」
import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; public class CalculatorTest { @Test void testAddition() { Calculator calc = new Calculator(); int result = calc.add(2, 3); assertEquals(5, result, "2 + 3 should equal 5"); } }
ご覧の通り、Calculatorクラスをインスタンス化し実際に値をインプット→想定される結果が返ってくるかどうか?を確認するコードです。Junitと言えど基本的にはJavaの基本文法に沿って書かれている、というのが1つのポイント。
そのうえで、Junitの特徴は以下の通りで、これを押さえておけばJunitに対する基本知識はOK。
Junitの基本知識1:アノテーションの利用
JUnitでは、テストメソッドに@Test
アノテーションを付けます。これにより、JUnitがそのメソッドをテストとして認識します。先ほどの例では、testAddition
メソッドに@Test
アノテーションが付いています。
import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; public class CalculatorTest { @Test void testAddition() { Calculator calc = new Calculator(); int result = calc.add(2, 3); assertEquals(5, result, "2 + 3 should equal 5"); } }
参考 Javaのメソッドとは?
Junitの基本知識2:アサーションの提供
JUnitは、テスト結果を検証するためのアサーションメソッドを提供します。この例では、assertEquals
メソッドを使って、期待される結果(5)と実際の結果(calc.add(2, 3)
)を比較しています。もし結果が一致しなければ、テストは失敗します
import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; public class CalculatorTest { @Test void testAddition() { Calculator calc = new Calculator(); int result = calc.add(2, 3); assertEquals(5, result, "2 + 3 should equal 5"); } }
Junitの基本知識3:テストの自動化
JUnitは、テストケースを自動的に実行しその結果をレポートしてくれます。手動で1つ1つのテストを行う必要がなく、一貫したテストが可能になります。例えば↓のようなテストクラスがあるとします。(testAddition
とtestSubtraction
の2つのテストメソッドが定義されています。)
import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; public class CalculatorTest { @Test void testAddition() { Calculator calc = new Calculator(); assertEquals(5, calc.add(2, 3)); } @Test void testSubtraction() { Calculator calc = new Calculator(); assertEquals(1, calc.subtract(3, 2)); } }
この2つのテストは、IDE(統合開発環境)やコマンドラインから一括で実行することができます。つまり、テストの自動化は、コマンドを1つ実行するだけで、すべてのテストメソッドを一気に実行できるという意味です。
Junitの基本知識4:テストの構造化
JUnitでは、テストケースを論理的にグループ化できます。複数のテストメソッドを1つのテストクラス(この場合、CalculatorTest
クラス)にまとめることで、テストコードを整理しやすくなります。
import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; public class CalculatorTest { @Test void testAddition() { Calculator calc = new Calculator(); assertEquals(5, calc.add(2, 3)); } @Test void testSubtraction() { Calculator calc = new Calculator(); assertEquals(1, calc.subtract(3, 2)); } }
Junitの基本知識5:例外のテスト
JUnitは、特定の例外(参考:例外とは?)がスローされることをテストする機能も提供しています。例えば、assertThrows
メソッドを使って、例外が正しくスローされるかどうかを確認できます。以下がその例。
@Test void testAdditionThrowsException() { Calculator calc = new Calculator(); assertThrows(IllegalArgumentException.class, () -> { calc.add(Integer.MAX_VALUE, 1); }); }
この例では、add
メソッドがInteger.MAX_VALUE
と1を加算するとIllegalArgumentException
がスローされることを期待しています。実際に例外がスローされればテストは成功し、スローされなければ失敗します。
このように、JUnitを利用することでJavaプログラムの単体テストを効率的に行うことができます。アノテーションを使ってテストメソッドを定義→アサーションメソッドを使ってテスト結果を確認という流れで、テストを自動化することで、コードの品質を高めることができます。
JUnitを利用してテストを実施する方法
ここからは、JUnitを使ってJavaプログラムのテストを実施する方法を1から順を追って解説します。今回は、ユーザー認証システムを例にして、Mavenを利用する前提で説明します。
ステップ1:プロジェクトのセットアップ
まず、JUnitを利用するためにMavenプロジェクトをセットアップします。pom.xml
ファイルに依存関係を追加します。
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>user-authentication</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.7.0</version> <scope>test</scope> </dependency> </dependencies> </project>
<dependencies>
: プロジェクトが依存しているライブラリを定義するセクション。<dependency>
: 個々の依存ライブラリを定義するブロック。<groupId>
: ライブラリのグループID。JUnitの場合はorg.junit.jupiter
。<artifactId>
: ライブラリのアーティファクトID=ライブラリの名前。JUnitの場合はjunit-jupiter-engine
。<scope>
: 依存関係のスコープ。test
を指定することで、この依存関係はテストの実行時のみ有効になる。
これで、プロジェクトにJUnitの依存関係が追加されました。
ステップ2:テスト対象のクラスを作成する
次に、テスト対象となるクラスを作成します。ここでは簡単なユーザー認証クラスを例にします。
public class UserAuthenticator { public boolean authenticate(String username, String password) { // 簡単な例として、ユーザー名が "user" でパスワードが "password" の場合のみ認証成功 return "user".equals(username) && "password".equals(password); } }
ステップ3:テストクラスを作成する
テスト対象クラスができたので、次にJUnitを使ってテストクラスを作成します。
import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; public class UserAuthenticatorTest { @Test void testAuthenticateSuccess() { UserAuthenticator authenticator = new UserAuthenticator(); assertTrue(authenticator.authenticate("user", "password"), "User should be authenticated successfully with correct username and password"); } @Test void testAuthenticateFailure() { UserAuthenticator authenticator = new UserAuthenticator(); assertFalse(authenticator.authenticate("user", "wrongpassword"), "User should not be authenticated with incorrect password"); } }
ステップ4:テストの実行
テストクラスを作成したら実際にテストを実行します。Mavenを使ってテストを実行する方法は、プロジェクトのルートディレクトリで以下のコマンドを実行するだけ。
mvn test このコマンドを実行すると、MavenがJUnitテストを自動的に実行し、その結果を表示する。↓ [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running UserAuthenticatorTest [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.002 s - in UserAuthenticatorTest [INFO] [INFO] Results: [INFO] [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.124 s [INFO] Finished at: 2024-06-11T14:42:13+00:00 [INFO] ------------------------------------------------------------------------
もしテストが失敗した場合は、どのテストが失敗したのか、その理由(アサーションが失敗した箇所)が表示されます。