📝

IntelliJ IDEA ではじめる TDD

2025/01/02に公開

はじめに

あけましておめでとうございます。
寝正月のおともに、Javaでテスト駆動開発をはじめてみました。

IntelliJ IDEA とは

JetBrains社から提供される、Java / Kotlin をいいかんじに扱えるIDE(統合開発環境)です。
https://www.jetbrains.com/ja-jp/idea/

IntelliJ IDEA には Community版(無料)とUltimate版(有料)がありますが、筆者は学割でUltimate版を使用しています。機能的な差異はあまりないとおもいますが、ご参考までに。

TDD とは

「テスト駆動開発(Test Driven Development)」のことです。
テストを書き、テスト要件を満たす実装を書くことで、常に要件を整理しながら保守性の高いコードが書けます。

https://t-wada.hatenablog.jp/entry/canon-tdd-by-kent-beck

これをJava、もといIntelliJ IDEA でやるときの流れをさっくりとまとめたのがこの記事です。

やってみる

実際にやっていきます。
さて、テストにはいくつか種類があります。ひとまず、ひとつのクラス・関数をテストする ユニットテスト の作成・実行を目標にしてみます。

プロジェクトの作成

テスト用のプロジェクトを作成します。

  • ビルドシステム:Gradle
  • Gradle DSL: Groovy
  • JDK: v23.0.1

DSL(build.gradle で使う言語)は Kotlin でも問題ないですが、以降の手順は Groovy で書きます。
Kotlin で書く必要がある場合は、適宜読み替えてください。

プロジェクトが問題なく作成されれば OK。

テストを書く

作成されたプロジェクトを見てみます。
src フォルダの中に maintest フォルダがありますね。

お察しの通り、実装は main に置き、テストを test に置いていきます。
今回はターン制ゲームを管理する Game クラスの作成を例に挙げてみます。要件は以下のような感じ。

  • ゲームは、現在のターンを示す turn パラメータを持つ
  • インスタンスを作成したとき、ターンは 0 として定義される
  • getTUrn 関数を呼ぶと、現在のターン数が取得できる
  • nextTurn 関数を呼ぶと、次のターンに進む

この仕様をもとに、テストが書けそうです。
Game クラスのテストを書く GameTest ファイルを作成しましょう。test フォルダ内の java フォルダを右クリックし、「新規」から「Javaクラス」を選択して作成します。[1]

問題なく作成できたら、中身を以下のように実装します。

import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;

public class GameTest {

    @Test
    public void testInitialTurn() {
        Game game = new Game();
        assertEquals(0, game.getTurn(), "初期化後のターンは0であるか");
    }

    @Test
    public void testNextTurn() {
        Game game = new Game();
        game.nextTurn();
        assertEquals(1, game.getTurn(), "nextTurn()を呼び出すとターンが1増えるか");
    }
}

テスト内では、

  • 初期化後のターンは0であるか
  • nextTurn関数を呼び出すとターンは1増えるか
    のふたつを確かめています。

さて、実行...といきたいですが、まだ Game クラスすら作っていないので参照エラーまみれのはずです。

先に、必要なクラスと関数を作っていきましょう。
まずは Game クラスから。テスト内の Game クラスの記述にカーソルを置き、「クラス 'Game' の作成」をクリックすることで、かんたんにクラスを作成できます。
このとき、クラスの作成場所は main フォルダ(青色のほう)にするのをお忘れなく。

同様にして、nextTurngetTurn 関数も作成します。

public class Game {
    public void nextTurn() {
    }

    public int getTurn() {
    }
}

帰り値の必要な getTurn 関数では、実装していないことを示すためにとりあえず -1 を返しておきます。

public class Game {
    public void nextTurn() {
    }

    public int getTurn() {
+        return -1;
    }
}

さて、これで GameTest を実行できるようになりました。

テストを実行する

実際に動かしてみます。
GameTest クラスの左側に、緑の再生マークがいくつかあることに気づいたかもしれません。これをクリックすることによって、個別に実行することができたり、クラス全体を一気に実行することができたりします。

実際に GameTest クラスの実行ボタンをクリックしてみます。

実際にテストが実行され、問題なく失敗したことが確認できます。

まとめてテストを実行する

現在はひとつのみのテストですが、開発においては複数のテストファイルを書くことが想定されます。これらを一気に実行する際は、サイドメニューのフォルダ一覧から緑になっているフォルダ(今回は test\java を右クリックし、「テストの実行」を選択することで実行できます。

過去に実行したテストを再実行する

上のタブの右側に、実行したテストの名前が表示されていることに気が付いたかもしれません。ここから任意のテストを選ぶことによって、過去に実行したテストをもういちど実行することができます。

参照

https://pleiades.io/help/idea/tdd-with-intellij-idea.html

脚注
  1. 本来は src\test\com\example のように、プロジェクトごとに決まったグループ名(もしくはプロジェクト名など)のフォルダを作成するのがJavaプロジェクトでの慣習です。こうすることで、パッケージ名がほかのライブラリと被ることによる命名の衝突事故を防いでいます。今回は説明の手間を省くために省略しましたが、気になる場合は このへん を参考にしてみて下さい。 ↩︎

Progate Path コミュニティ

Discussion