Bermigrasi dari JUnit 4 ke JUnit 5

1. Ikhtisar

Dalam artikel ini, kita akan melihat bagaimana kita dapat bermigrasi dari JUnit 4 ke rilis JUnit 5 terbaru - dengan gambaran umum tentang perbedaan antara dua versi perpustakaan.

Untuk panduan umum tentang penggunaan JUnit 5, lihat artikel kami di sini.

2. Keuntungan JUnit 5

Mari kita mulai dengan versi sebelumnya - JUnit 4 memiliki beberapa batasan yang jelas:

  • Seluruh kerangka disimpan dalam satu pustaka jar. Seluruh pustaka perlu diimpor meskipun hanya fitur tertentu yang diperlukan. Di JUnit 5, kami mendapatkan lebih banyak perincian dan hanya dapat mengimpor yang diperlukan
  • Satu runner pengujian hanya dapat menjalankan pengujian di JUnit 4 dalam satu waktu (misalnya SpringJUnit4ClassRunner atau Parameterized ). JUnit 5 memungkinkan banyak pelari untuk bekerja secara bersamaan
  • JUnit 4 tidak pernah maju di luar Java 7, kehilangan banyak fitur dari Java 8. JUnit 5 memanfaatkan fitur Java 8 dengan baik

Ide di balik JUnit 5 adalah menulis ulang JUnit 4 sepenuhnya untuk menyelesaikan sebagian besar kekurangan ini.

3. Perbedaan

JUnit 4 dibagi menjadi beberapa modul yang terdiri dari JUnit 5:

  • Platform JUnit - modul ini mencakup semua framework ekstensi yang mungkin kami minati dalam eksekusi, penemuan, dan pelaporan pengujian
  • JUnit Vintage - modul ini memungkinkan kompatibilitas mundur dengan JUnit 4 atau bahkan JUnit 3

3.1. Anotasi

JUnit 5 hadir dengan perubahan penting dalam anotasinya. Yang paling penting adalah kita tidak bisa lagi menggunakan anotasi @Test untuk menentukan ekspektasi.

The diharapkan parameter dalam JUnit 4:

@Test(expected = Exception.class) public void shouldRaiseAnException() throws Exception { // ... }

Sekarang, kita dapat menggunakan metode assertThrows :

public void shouldRaiseAnException() throws Exception { Assertions.assertThrows(Exception.class, () -> { //... }); }

The batas waktu atribut dalam JUnit 4:

@Test(timeout = 1) public void shouldFailBecauseTimeout() throws InterruptedException { Thread.sleep(10); }

Sekarang, metode assertTimeout di JUnit 5:

@Test public void shouldFailBecauseTimeout() throws InterruptedException { Assertions.assertTimeout(Duration.ofMillis(1), () -> Thread.sleep(10)); }

Anotasi lain yang diubah dalam JUnit 5:

  • Anotasi @Before diubah namanya menjadi @BeforeEach
  • @Setelah anotasi diubah namanya menjadi @AfterEach
  • Anotasi @BeforeClass diganti namanya menjadi @BeforeAll
  • Anotasi @AfterClass diganti namanya menjadi @AfterAll
  • Anotasi @ Abaikan diubah namanya menjadi @Disabled

3.2. Pernyataan

Sekarang kita bisa menulis pesan assertion dalam lambda di JUnit 5, yang memungkinkan evaluasi malas melewati konstruksi pesan yang kompleks hingga diperlukan:

@Test public void shouldFailBecauseTheNumbersAreNotEqual_lazyEvaluation() { Assertions.assertTrue( 2 == 3, () -> "Numbers " + 2 + " and " + 3 + " are not equal!"); }

Kami juga dapat mengelompokkan pernyataan di JUnit 5:

@Test public void shouldAssertAllTheGroup() { List list = Arrays.asList(1, 2, 4); Assertions.assertAll("List is not incremental", () -> Assertions.assertEquals(list.get(0).intValue(), 1), () -> Assertions.assertEquals(list.get(1).intValue(), 2), () -> Assertions.assertEquals(list.get(2).intValue(), 3)); }

3.3. Asumsi

Kelas Assumptions baru sekarang ada di org.junit.jupiter.api.Assumptions . JUnit 5 sepenuhnya mendukung metode asumsi yang ada di JUnit 4 dan juga menambahkan sekumpulan metode baru untuk memungkinkan menjalankan beberapa pernyataan hanya dalam skenario tertentu saja:

@Test public void whenEnvironmentIsWeb_thenUrlsShouldStartWithHttp() { assumingThat("WEB".equals(System.getenv("ENV")), () -> { assertTrue("http".startsWith(address)); }); }

3.4. Pemberian Tag dan Filter

Di JUnit 4 kita bisa mengelompokkan pengujian dengan menggunakan anotasi @Category . Dengan JUnit 5, anotasi @Category diganti dengan anotasi @Tag :

@Tag("annotations") @Tag("junit5") @RunWith(JUnitPlatform.class) public class AnnotationTestExampleTest { /*...*/ }

Kita bisa memasukkan / mengecualikan tag tertentu menggunakan maven-surefire-plugin :

   maven-surefire-plugin   junit5     

3.5. Anotasi Baru untuk Menjalankan Tes

The @RunWith digunakan untuk mengintegrasikan konteks pengujian dengan kerangka kerja lain atau mengubah aliran eksekusi secara keseluruhan dalam uji kasus di JUnit 4.

Dengan JUnit 5, sekarang kita dapat menggunakan anotasi @ExtendWith untuk menyediakan fungsionalitas serupa.

Sebagai contoh, untuk menggunakan fitur Spring di JUnit 4:

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration( {"/app-config.xml", "/test-data-access-config.xml"}) public class SpringExtensionTest { /*...*/ }

Sekarang, di JUnit 5 ini adalah ekstensi sederhana:

@ExtendWith(SpringExtension.class) @ContextConfiguration( { "/app-config.xml", "/test-data-access-config.xml" }) public class SpringExtensionTest { /*...*/ } 

3.6. Anotasi Aturan Tes Baru

Di JUnit 4, anotasi @Rule dan @ ClassRule digunakan untuk menambahkan fungsionalitas khusus ke pengujian.

Di JUnit 5. kita bisa mereproduksi logika yang sama menggunakan anotasi @ExtendWith .

For example, say we have a custom rule in JUnit 4 to write log traces before and after a test:

public class TraceUnitTestRule implements TestRule { @Override public Statement apply(Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { // Before and after an evaluation tracing here ... } }; } }

And we implement it in a test suite:

@Rule public TraceUnitTestRule traceRuleTests = new TraceUnitTestRule(); 

In JUnit 5, we can write the same in a much more intuitive manner:

public class TraceUnitExtension implements AfterEachCallback, BeforeEachCallback { @Override public void beforeEach(TestExtensionContext context) throws Exception { // ... } @Override public void afterEach(TestExtensionContext context) throws Exception { // ... } }

Using JUnit 5's AfterEachCallback and BeforeEachCallback interfaces available in the package org.junit.jupiter.api.extension, we easily implement this rule in the test suite:

@RunWith(JUnitPlatform.class) @ExtendWith(TraceUnitExtension.class) public class RuleExampleTest { @Test public void whenTracingTests() { /*...*/ } }

3.7. JUnit 5 Vintage

JUnit Vintage aids in the migration of JUnit tests by running JUnit 3 or JUnit 4 tests within the JUnit 5 context.

We can use it by importing the JUnit Vintage Engine:

 org.junit.vintage junit-vintage-engine ${junit5.vintage.version} test 

4. Conclusion

Seperti yang telah kita lihat di artikel ini, JUnit 5 adalah kerangka kerja JUnit 4 yang modular dan modern. Kami telah memperkenalkan perbedaan utama antara kedua versi ini dan memberi petunjuk tentang cara bermigrasi dari satu ke yang lain.

Implementasi lengkap dari tutorial ini dapat ditemukan di lebih dari GitHub.