Pendahuluan

JUnit secara de facto merupakan platform yang paling banyak dipakai untuk testing di Java.

Mengenai Pendahuluan JUnit , bisa dilihat di sini

Yang kita tahu bahwa JUnit 4 dibuat dengan desain yang kurang memperhatikan separation of concern.

Akhirnya muncul JUnit Lambda, yang didasari semangat untuk merefactor JUnit 4 yang telah 10 tahun release tanpa perubahan yang mendasar.

Nama Lambda dipakai untuk mengadopsi fitur Java Lambda semenjak Java 8 yang lebih intuitif dalam melakukan assertion, dan banyak perubahan yang bisa juga digunakan di JUnit.

Lambat laun JUnit Lambda ini direlease menjadi JUnit 5.

Di dalamnya banyak memanfaatkan fitur Lambda dari Java 8, termasuk misalnya untuk Assertion, expect Exception, dll.

Oleh karenanya JUnit 5 memiliki persyaratan awal bahwa akan berjalan di versi Java 8 keatas.

Sementara JUnit 4 , akan jalan di versi Java 5 keatas.


Ok, sekarang bagaimana arsitekturnya ?

JUnit 5 dibuat ulang dengan semangat penyederhanaan library, dan separation of concern.

Library JUnit 5 tidak hanya terdiri dari satu library .jar saja, akan tetapi dibagi 3 modul .jar yang bisa diimport terpisah.

3 sub project/modul dari JUnit 5 tersebut adalah :

  • JUnit Platform –> Ini sebagai basic untuk menjalankan testing framework. Terdiri dari API/antarmuka untuk berinteraksi dengan implementasi JUnit yang dinamakan Jupiter, atau implementasi framework testing lainnya. Didalamnya terdapat mekanisme untuk orkestrasi test.

  • JUnit Jupiter –> TestEngine nya JUnit atau implementasi dari platform JUnit. Dengan modul ini maka Software Engineer bisa bikin unit test, berguna untuk menemukan dan menjalankan test tertentu. Disini terdapat anotasi, programming model, dan juga extension yang kita temui di waktu membuat sebuah unit test.

  • JUnit Vintage –> Support untuk JUnit3 dan JUnit4, sama seperti JUnit Jupiter, tetapi khusus untuk JUnit 3 dan JUnit 4.

Sehingga dalam halaman user guide nya, disebutkan bahwa :

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

Selain itu ada juga library/framework testing yang mungkin dibuat oleh Software Engineer lain, seperti TestNg, Spock, ScalaTest, dll, yang cocok/compatible dengan spesifikasi JUnit Platform yang dibuat oleh JUnit 5.

Oleh karenanya kita bisa import modulnya tergantung kebutuhan saja.

Bisa saja kita butuh JUnit Jupiter saja, karena misalnya kita membuat Unit Test memakai pendekatan JUnit 5/ Jupiter.

Atau misalnya kita mau tetap memakai JUnit 3 atau JUnit 4 sebagai implementasi Unit test kita, maka kita bisa import JUnit Vintage.

Atau juga misalnya kita ingin menggunakan TestNg sebagai implementasi dari unit test kita. Maka kita import JUnit Platform dengan import library TestNg yang merupakan implementasinya.

Dengan pemisahan seperti diatas, maka JUnit 5 lebih banyak berkutat di spesifikasi, antarmuka, dan platform umum.

Sementara implementasi dan detailnya bisa di delegasikan ke library implementasi testing framework yang digunakan.


Bagaimana struktur library di dalamnya ?

Ok, coba kita bedah :

Arsitektur dari JUnit 5 ini akhirnya membagi 3 modul diatas menjadi beberapa dependency .jar file dan modul nya lagi menjadi terpisah-pisah, sbb :

  • junit-jupiter-api –> merupakan API untuk menulis Test dengan JUnit 5/Jupiter.

  • junit-platform-engine –> antarmuka API yang harus diimplementasi oleh test engine, baik oleh test engine nya JUnit 5/JupiterTestNg, Spock, Cucumber, ScalaTest, dll. Tujuannya untuk menemukan dan menjalankan test sesuai dengan implementasinya.

  • junit-jupiter-engine, merupakan implementasi dari junit-platform-engine dan khusus untuk JUnit 5/Jupiter

  • junit-vintage-engine, merupakan implementasi dari junit-platform-engine dan khusus JUnit3 dan JUnit4

  • junit-platform-launcher –> modul untuk menemukan implementasi test engine yang cocok lalu orkestrasi eksekusinya. Cocok buat IDE atau build tools yang lain, misalnya kalau kita lihat menu run as test di Eclipse.

Diluar hal diatas, maka bisa saja Software Engineer lain membuat library yang implementasi junit-platform-engine.

Misalnya testing framework TestNg.

Mereka misalnya membuat implementasinya :

  • testNg-engine, merupakan implementasi dari junit-platform-engine dan khusus untuk TestNg.

Kemudian secara selektif, kita bisa saja mengimpor implementasi library diatas di project kita di .pom (misalnya karena kita lebih suka menggunakan TestNg, daripada JUnit Jupiter).

Cukup menarik bukaan..

Intinya di JUnit 5, dilakukan pemisahan antara platform engine, laucher, dan juga implementasinya.

Dengan pemisahan seperti itu, maka JUnit akan lebih leluasa dalam mendefinsikan fitur-fitur baru yang dirasa perlu ditambahkan, tanpa harus khawatir dengan detail implementasi yang bisa jadi bentrok dengan yang ada.


Bagaimana contohnya kita implementasi JUnit 5 ?

Misalnya kita memakai maven dan mau menggunakan Jupiter, maka kita bisa import di .pom sbb :

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.9.0</version>
    <scope>test</scope>
</dependency>

dan kita bisa membuat Unit test sbb :

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

import example.util.Calculator;

import org.junit.jupiter.api.Test;

class MyFirstJUnitJupiterTests {

    private final Calculator calculator = new Calculator();

    @Test
    void addition() {
        assertEquals(2, calculator.add(1, 1));
    }
}

code diatas diambil dari JUnit example

Ok.. kita lanjut ke JUnit 5 - Part 2