Java Unit Test
Java Unit Test
maven-archetype-quickstart
Menambah JUnit 5 di Apache Maven
Membuat Test
Membuat Test
● Untuk membuat test di JUnit itu sederhana, kita cukup membuat class, lalu menambahkan
method-method test nya
● Method akan dianggap sebuah test jika ditambahkan annotation @Test
● Kode test disimpan dibagian test folder di maven, bukan di main folder
● Biasanya saat membuat class untuk test, rata-rata orang biasa membuat nama class nya sama
dengan nama class yang akan di test, tapi diakhiri dengan kata Test, misal jika nama class nya
adalah Calculator, maka nama class test nya adalah CalculatorTest
Kode : Class Calculator
Kode : Unit Test Class Calculator
Menggunakan Assertions
Assertions
● Saat membuat test, kita harus memastikan bahwa test tersebut sesuai dengan ekspektasi yang kita
inginkan
● Jika manual, kita bisa melakukan pengecekan if else, namun itu tidak direkomendasikan
● JUnit memiliki fitur untuk melakukan assertions, yaitu memastikan bahwa unit test sesuai dengan
kondisi yang kita inginkan
● Assertions di JUnit di representasikan dalam class Assertions, dan di dalamnya terdapat banyak
sekali function static
● https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/Assertions.html
Meng-import Assertions
Menggunakan Assertions
Menggagalkan Test
● Kadang dalam membuat unit test, kita tidak hanya ingin mengetest kasus sukses atau gagal
● Ada kalanya kita ingin mengetes sebuah exception misalnya
● Assertions juga bisa digunakan untuk mengecek apakah sebuah exception terjadi
Kode : Calculator Divide
Kode : Assertions Exception
Mengubah Nama Test
Mengubah Nama Test
● Kadang agak sulit membuat nama function yang merepresentasikan kasus test nya
● Jika kita ingin menambahkan deskripsi untuk tiap test, kita bisa menggunakan annotation
@DisplayName
● Dengan menggunakan annotation @DisplayName, kita bisa menambahkan deskripsi unit testnya
Kode : Menggunakan DisplayName
Menggunakan Display Name Generator
● JUnit mendukung pembuatan DisplayName secara otomatis menggunakan generator
● Yang perlu kita lakukan adalah membuat class turunan dari interface DisplayNameGenerator, lalu
menambahkan annotation @DisplayNameGeneration di test class nya
Kode : Display Name Generator
Kode : Display Name Generation
Menonaktifkan Test
Menonaktifkan Test
● Kadang ada kalanya kita ingin menonaktifkan unit test, misal karena terjadi error di unit test
tersebut, dan belum bisa kita perbaiki
● Sebenarnya cara paling mudah untuk menonaktifkan unit test adalah dengan menghapus
annotation @Test, namun jika kita lakukan itu, kita tidak bisa mendeteksi kalo ada unit test yang di
disabled
● Untuk menonaktifkan unit test secara benar, kita bisa menggunakan annotation @Disabled
Kode : Disabled Unit Test
Tampilan di IntelliJ IDEA
Sebelum & Setelah Test
Sebelum & Setelah Unit Test
● Kadang kita ingin menjalankan kode yang sama sebelum dan setelah eksekusi unit test
● Hal ini sebenarnya bisa dilakukan secara manual di function @Test nya, namun hal ini akan
membuat kode duplikat banyak sekali
● JUnit memiliki annotation @BeforeEach dan @AfterEach
● @BeforeEach digunakan untuk menandai function yang akan dieksekusi sebelum unit test
dijalankan
● @AfterEach digunakan untuk menandai function yang akan dieksekusi setelah unit test dijalankan
● Ingat, bahwa ini akan selalu dieksekusi setiap kali untuk function @Test, bukan sekali untuk class
test saja
Kode : BeforeEach dan AfterEach
Sebelum & Setelah Semua Unit Test
● @BeforeEach & @AfterEach akan dieksekusi setiap kali function @Test jalan
● Namun kadang kita ingin melakukan sesuatu sebelum semua unit test berjalan, atau setelah semua
unit test berjalan
● Ini bisa dilakukan menggunakan annotation @BeforeAll dan @AfterAll
● Namun hanya static function yang bisa menggunakan @BeforeAll dan @AfterAll
Kode : BeforeAll dan AfterAll
Membatalkan Test
Membatalkan Test
● Kadang kita ingin membatalkan unit test ketika kondisi tertentu terjadi
● Untuk membatalkan, kita bisa menggunakan exception TestAbortedException
● Jika JUnit mendapatkan exception TestAbortedException, secara otomatis test tersebut akan
dibatalkan
Kode : Membatalkan Test
Ketika Test Dibatalkan
Menggunakan Assumptions
Menggunakan Assumptions
● Sebelumnya kita sudah tahu jika ingin membatalkan test, kita bisa menggunakan exception
TestAbortException
● Namun sebenarnya ada cara yang lebih mudah, yaitu dengan menggunakan Assumptions
● Penggunaan Assumptions mirip seperti Assertions, jika nilainya tidak sama, maka function
Assumptions akan thrown TestAbortException, sehingga secara otomatis akan membatalkan unit
test yang sedang berjalan
● https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/Assumptions.html
Kode : Import Assumptions
Kode : Menggunakan Assumptions
Test Berdasarkan Kondisi
Test Berdasarkan Kondisi
● Sebenarnya kita bisa menggunakan Assumptions untuk menjalankan unit test berdasarkan kondisi
tertentu
● Namun JUnit menyediakan fitur yang lebih mudah untuk pengecekan beberapa kondisi, seperti
kondisi sistem operasi, versi java, system property atau environment variable
● Ini lebih mudah dibandingkan menggunakan Assumptions
Kondisi Sistem Operasi
● Untuk kondisi sistem operasi, kita bisa menggunakan beberapa annotation
● @EnabledOnOs digunakan untuk penanda bahwa unit test boleh berjalan di sistem operasi yang
ditentukan
● @DisabledOnOs digunakan untuk penanda bahwa unit test tidak boleh berjalan di sistem operasi
yang ditentukan
Kode : Kondisi Sistem Operasi
Kondisi Versi Java
● Untuk kondisi versi Java yang kita gunakan, kita bisa menggunakan beberapa annotation
● @EnabledOnJre digunakan untuk penanda bahwa unit test boleh berjalan di Java versi tertentu
● @DisabledOnJre digunakan untuk penanda bahwa unit test tidak boleh berjalan di Java versi
tertentu
● @EnabledForJreRange digunakan untuk penanda bahwa unit test boleh berjalan di range Java
versi tertentu
● @DisabledForJreRange digunakan untuk penanda bahwa unit test tidak boleh berjalan di range
Java versi tertentu
Kode : Kondisi Versi Java
Kode : Kondisi Range Versi Java
Kondisi System Property
● Untuk kondisi nilai dari system property, kita bisa menggunakan beberapa annotation
● @EnabledIfSystemProperty untuk penanda bahwa unit test boleh berjalan jika system property
sesuai dengan yang ditentukan
● @DisabledIfSystemProperty untuk penanda bahwa unit test tidak boleh berjalan jika system
property sesuai dengan yang ditentukan
● Jika kondisinya lebih dari satu, kita bisa menggunakan @EnabledIfSystemProperties dan
@DisabledIfSystemProperties
Kode : Kondisi System Property
Kondisi Environment Variable
● Untuk kondisi nilai dari environment variable, kita bisa menggunakan beberapa annotation
● @EnabledIfEnvironmentVariable untuk penanda bahwa unit test boleh berjalan jika environment
variable sesuai dengan yang ditentukan
● @DisabledIfEnvironmentVariable untuk penanda bahwa unit test tidak boleh berjalan jika
environment variable sesuai dengan yang ditentukan
● Jika kondisinya lebih dari satu, kita bisa menggunakan @EnabledIfEnvironmentVariables dan
@DisabledIfEnvironmentVariables
Kode : Kondisi Environment Variable
Menggunakan Tag
Menggunakan Tag
● Class atau function unit test bisa kita tambahkan tag (tanda) dengan menggunakan annotation
@Tag
● Dengan menambahkan tag ke dalam unit test, kita bisa fleksibel ketika menjalan unit test, bisa
memilih tag mana yang mau di include atau di exclude
● Jika kita menambahkan tag di class unit test, secara otomatis semua function unit test di dalam
class tersebut akan memiliki tag tersebut
● Jika kita ingin menambahkan beberapa tag di satu class atau function unit test, kita bisa
menggunakan annotation @Tags
Kode : Menambahkan Tag
Memilih Tag dengan Maven
mvn test -Dgroups=tag1,tag2
Memilih Tag dengan IntelliJ IDEA
Urutan Eksekusi Test
Urutan Eksekusi Test
● Secara default, urutan eksekusi unit test tidak ditentukan, jadi jangan berharap jika sebuah
method berada diatas method lainnya, maka akan dijalankan lebih dulu
● Hal ini karena memang sebaiknya method unit test itu harus independen, tidak saling
ketergantungan
● Secara default pun, object class unit test akan selalu dibuat ulang tiap method, jadi jangan berharap
kita bisa menyimpan data di variable untuk digunakan di unit test method selanjutnya
Mengubah Urutan Eksekusi Test
● JUnit mendukung perubahan urutan eksekusi test jika kita mau menggunakan annotation
@TestMethodOrder, ada beberapa cara yang bisa kita lakukan
● Alphanumeric, artinya urutan eksekusi unit test akan diurutkan berdasarkan alphanumeric
● Random, artinya urutan urutan eksekusi unit test akan dieksekusi secara random
● OrderAnnotation, artinya urutan eksekusi unit test akan mengikuti annotation @Order yang ada
di tiap method unit test
Kode : Menggunakan Order Annotation
Membuat Urutan Sendiri
● Jika kita ingin membuat cara mengurutkan urutan unit test function sendiri, kita bisa dengan
mudah tinggal membuat class baru turunan dari MethodOrderer interface
Siklus Hidup Test
Siklus Hidup Test
● Secara default, lifecycle (siklus hidup) object test adalah independent per method test, artinya
object unit test akan selalu dibuat baru per method unit test, oleh karena itu kita tidak bisa
bergantung dengan method test lain
● Cara pembuatan object test di JUnit ditentukan oleh annotation @TestInstance, dimana defaultnya
adalah Lifecycle.PER_METHOD, artinya tiap method akan dibuat sebuah instance / object baru
● Kita bisa merubahnya menjadi Lifecycle.PER_CLASS jika mau, dengan demikian instance / object
test haya dibuat sekali per class, dan method test akan menggunakan object test yang sama
● Hal ini bisa kita manfaatkan ketika membuat test yang tergantung dengan test lain
Kode : Menggunakan Instance Per Class
Keuntungan Instance Per Class
● Salah satu keuntungan saat menggunakan Lifecycle.PER_CLASS adalah, kita bisa menggunakan
@BeforeAll dan @AfterAll di method biasa, tidak harus menggunakan function object / static
Kode : BeforeAll dan AfterAll
Test di dalam Test
Test di dalam Test
● Saat membuat unit test, ada baiknya ukuran test class nya tidak terlalu besar, karena akan sulit di
baca dan dimengerti.
● Jika test class sudah semakin besar, ada baiknya kita pecah menjadi beberapa test class, lalu kita
grouping sesuai dengan jenis method test nya.
● JUnit mendukung pembuatan class test di dalam class test, jadi kita bisa memecah sebuah class
test, tanpa harus membuat class di file berbeda, kita bisa cukup menggunakan inner class
● Untuk memberi tahu bahwa inner class tersebut adalah test class, kita bisa menggunakan
annotation @Nested
Kode : Test di dalam Test
Informasi Test
Informasi Test
● Walaupun mungkin jarang kita gunakan, tapi kita juga bisa mendapatkan informasi test yang
sedang berjalan menggunakan interface TestInfo
● Kita bisa menambahkan TestInfo sebagai parameter di function unit test
Kode : Menggunakan Test Info
Dependency Injection di Test
Dependency Injection di Test
● Tidak ada magic di JUnit, sebenarnya fitur TestInfo yang sebelumnya kita bahas adalah bagian dari
dependency injection di JUnit
● Dependency Injection sederhananya adalah bagaimana kita bisa memasukkan dependency
(object/instance) ke dalam unit test secara otomatis tanpa proses manual
● Saat kita menambah parameter di function unit test, sebenarnya kita bisa secara otomatis
memasukkan parameter tersebut dengan bantuan ParameterResolver
● Contohnya TestInfo yang kita bahas sebelumya, sebenarnya objectnya dibuat oleh
TestInfoParameterResolver
Kode : Membuat Random Parameter Resolver
Menggunakan Parameter Resolver
● Untuk menggunakan parameter resolver yang sudah kita buat, kita bisa menggunakan annontation
@ExtendWith di test class
● Jika lebih dari 1 parameter resolver, kita bisa menggunakan @Extentions
Kode : Menggunakan Random Resolver
Pewarisan di Test
Pewarisan di Test
● JUnit mendukung pewarisan di test, artinya jika kita membuat class atau interface dan
menambahkan informasi test disitu, maka ketika kita membuat turunannya, secara otomatis semua
fitur test nya dimiliki oleh turunannya
● Ini sangat cocok ketika kita misal contohnya sering membuat code sebelum dan setelah test yang
berulang-ulang, sehingga dibanding dibuat di semua test class, lebih baik dibuat sekali di parent
test class, dan test class tinggal menjadi child class dari parent test class
Kode : Membuat Parent Test Class
Kode : Membuat Child Test Class
Test Berulang
Test Berulang
● JUnit mendukung eksekusi unit test berulang kali sesuai dengan jumlah yang kita tentukan
● Untuk mengulang eksekusi unit test, kita bisa menggunakan annotation @RepeatedTest di method
unit test nya
● @RepeatedTest juga bisa digunakan untuk mengubah detail nama test nya, dan kita bisa
menggunakan value {displayName} untuk mendapatkan display name, {currentRepetition} untuk
mendapatkan perulangan ke berapa saat ini, dan {totalRepetitions} untuk mendapatkan total
perulangan nya
Kode : Test Berulang
Informasi Perulangan
● @RepeatedTest juga memiliki object RepetitionInfo yang di inject oleh class
RepetitionInfoParameterResolver, sehingga kita bisa mendapatkan informasi RepetitionInfo
melalui parameter function unit test
Kode : Informasi Perulangan
Test dengan Parameter
Test dengan Parameter
● Sebelumnya kita sudah tau jika ingin menambahkan parameter di function unit test, maka kita
perlu membuat ParameterResolver
● Namun jika terlalu banyak membuat ParameterResolver juga agak menyulitkan kita
● JUnit memiliki fitur yang bernama @ParameterizedTest, dimana jenis unit test ini memang khusus
dibuat agar dapat menerima parameter
● Yang perlu kita lakukan adalah dengan mengganti @Test menjadi @ParameterizedTest
Sumber Parameter
@ParameterizedTest mendukung beberapa sumber parameter, yaitu