技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

入門向け?Java11 と gradle5.0 で JUnit5 を動かすセットアップ

と言ってもそんな難しい話ではない。

Java11 JDK インストール

OracleJDK は有償になってしまったので、ZuluJDK をインストールする。
とくに難しい話はなくて、インストーラーを起動するだけでいい。

注意が必要なのは、すでに OracleJDK 10 以下が入っている場合、Path 変数や JAVA_HOME あたりの設定に OracleJDK のパスが入ってて、コマンドを食われる場合があるという点。
なので、インストールしたら Windows10 ならコントロールパネルでも開いて確認する方がいい。

インストールに成功して、再起動後、Dos で以下が出ればOK

D:\sources\Testing>java -version
openjdk version "11.0.1" 2018-10-16 LTS
OpenJDK Runtime Environment Zulu11.2+3 (build 11.0.1+13-LTS)
OpenJDK 64-Bit Server VM Zulu11.2+3 (build 11.0.1+13-LTS, mixed mode)

Gradle5.0 インストール

これも基本的にはインストーラーで入る…が、私は Chocolatey - The package manager for Windows 経由で入れた。
Mac なら Homebrew でも入るので、その方がおすすめ。

gradle.org

> choco install gradle

これもコマンドプロンプトで、バージョンが確認できればOK

D:\sources\Testing>gradle --version

------------------------------------------------------------
Gradle 5.0
------------------------------------------------------------

Build time:   2018-11-26 11:48:43 UTC
Revision:     7fc6e5abf2fc5fe0824aec8a0f5462664dbcd987

Kotlin DSL:   1.0.4
Kotlin:       1.3.10
Groovy:       2.5.4
Ant:          Apache Ant(TM) version 1.9.13 compiled on July 10 2018
JVM:          11.0.1 (Azul Systems, Inc. 11.0.1+13-LTS)
OS:           Windows 10 10.0 amd64

因みに余談だが、choco のインストールパッケージにコーディング用フォント GitHub - tonsky/FiraCode: Monospaced font with programming ligatures も choco から入るので、入れてないならお勧めする。

Gradle プロジェクトを作成する

上記だけで PATH とかも大体通るので、サクッと立ち上げる。
ウィザードができたのはうれしい。

因みに前バージョンから gradle でゴリゴリ書いてた派なので、ビルドスクリプトは groovy でやることにする。
新規で入るなら Kotlin のが分かりやすいかもしれないけど、groovy のDSLの楽さ考えたら…って感じもする。

D:\sources\sample>gradle init

Select type of project to generate:
  1: basic
  2: groovy-application
  3: groovy-library
  4: java-application
  5: java-library
  6: kotlin-application
  7: kotlin-library
  8: scala-library
Enter selection (default: basic) [1..8] 4

Select build script DSL:
  1: groovy
  2: kotlin
Enter selection (default: groovy) [1..2] 1

Select test framework:
  1: junit
  2: testng
  3: spock
Enter selection (default: junit) [1..3] 1

Project name (default: Testing):

Source package (default: Testing): example


BUILD SUCCESSFUL in 21s
2 actionable tasks: 2 executed

これで、基本的なコマンドは使えるのだが、最初にビルドスクリプトをいじるのは嗜み。

plugins {
    id 'java'
    id 'application'
}

// これは必須。なんで Windows のソースがデフォルト windows-31j (MS932) 設定なのか…
def defaultEncoding = 'UTF-8'
tasks.withType(AbstractCompile)*.options*.encoding = defaultEncoding
tasks.withType(GroovyCompile)*.groovyOptions*.encoding = defaultEncoding

repositories {
    jcenter()
}

dependencies {
    // JUnit5 使いたいです
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
}

test {
    // ということで、テストの実行エンジンも指定
    useJUnitPlatform {
        includeEngines 'junit-jupiter'
    }
}

// 実行クラスパス(これは好みで)
mainClassName = 'example.App'

コード書いて実行だ

別に今回は複雑なことがしたいわけではなくて、ビルドしてテストが書ける事が前提なので、ざっくり作る。

package example;

import java.util.Arrays;
import java.util.List;

public class App {
    public static void main(String[] args) {
        List<Double> source = Arrays.asList(11.2, 13.5, 21.3, 10.9);
        double mean = App.mean(source);
        double variance = App.variance(source);
        double std = App.standardDivision(source);

        System.out.println(mean);
        System.out.println(variance);
        System.out.println(std);

    }

    public static double standardDivision(List<Double> source) {
        double variance = App.variance(source);
        return Math.sqrt(variance);
    }

    public static double variance(List<Double> source) {
        double mean = App.mean(source);
        return source.stream().mapToDouble(v -> mean - v).map(v -> v * v).average().getAsDouble();
    }

    public static double mean(final List<Double> args) {
        return args.stream().mapToDouble(v -> v).average().getAsDouble();
    }
}

わかりやすく平均、分散(偏差の二乗平均)、標準偏差(分散の√)を求めてみた。
これを動かしてみると

D:\sources\Testing>gradlew run

> Task :run
14.225
17.696875000000002
4.206765384472969

BUILD SUCCESSFUL in 0s
2 actionable tasks: 1 executed, 1 up-to-date

シンプルに行きましたな。

UT を動かす

と言っても計算処理しか入れてないので、テストもシンプル。

package example;


import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import java.util.Arrays;

import static org.junit.jupiter.api.Assertions.*;

public class AppTest {

    @Test
    @Tag("math")
    @DisplayName("平均計算テスト")
    public void meanTest() {
        var src = Arrays.asList(10.0, 8.0, 9.0);
        assertEquals(9.0, App.mean(src));
    }

    @Test
    @DisplayName("分散テスト")
    public void varianceTest() {
        var src = Arrays.asList(10.0, 8.0, 8.0, 6.0);
        assertEquals(2.0, App.variance(src));
    }

    @Test
    @DisplayName("標準偏差テスト")
    public void standardDivisionTest() {
        var src = Arrays.asList(10.0, 8.0, 8.0, 10.0);
        assertEquals(2.0, App.standardDivision(src));
    }
}

標準偏差はわざと落とす。

D:\sources\Testing>gradlew test

> Task :test FAILED

example.AppTest > standardDivisionTest() FAILED
    org.opentest4j.AssertionFailedError at AppTest.java:36

3 tests completed, 1 failed

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':test'.
> There were failing tests. See the report at: file:///D:/sources/Testing/build/reports/tests/test/index.html

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 1s
3 actionable tasks: 2 executed, 1 up-to-date

とテストもエラーを出して死ぬ。
build/reports の中には、きちんとレポートが出てくる。

f:id:white-azalea:20181217222731p:plain
テスト実行結果サンプル