Berhijrah dari JUnit 4 ke JUnit 5

1. Gambaran keseluruhan

Dalam artikel ini, kita akan melihat bagaimana kita dapat berpindah dari JUnit 4 ke peluncuran JUnit 5 terbaru - dengan gambaran keseluruhan perbezaan antara kedua versi perpustakaan.

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

2. Kelebihan JUnit 5

Mari kita mulakan dengan versi sebelumnya - JUnit 4 mempunyai beberapa had yang jelas:

  • Keseluruhan kerangka itu terdapat dalam perpustakaan balang tunggal. Seluruh perpustakaan perlu diimport walaupun hanya diperlukan ciri tertentu. Di JUnit 5, kami mendapat lebih terperinci dan hanya dapat mengimport apa yang diperlukan
  • Satu pelari ujian hanya dapat menjalankan ujian di JUnit 4 pada satu masa (contohnya SpringJUnit4ClassRunner atau Parameterized ). JUnit 5 membolehkan beberapa pelari bekerja serentak
  • JUnit 4 tidak pernah maju selain Java 7, kehilangan banyak fitur dari Java 8. JUnit 5 memanfaatkan ciri-ciri Java 8 dengan baik

Idea di sebalik JUnit 5 adalah menulis semula JUnit 4 sepenuhnya untuk menyelesaikan sebahagian besar kelemahan ini.

3. Perbezaan

JUnit 4 dibahagikan kepada modul yang merangkumi JUnit 5:

  • Platform JUnit - modul ini merangkumi semua kerangka peluasan yang mungkin kami minati dalam pelaksanaan ujian, penemuan, dan pelaporan
  • JUnit Vintage - modul ini membenarkan keserasian ke belakang dengan JUnit 4 atau bahkan JUnit 3

3.1. Anotasi

JUnit 5 hadir dengan perubahan penting dalam penjelasannya. Yang paling penting ialah kita tidak lagi dapat menggunakan anotasi @Test untuk menentukan jangkaan.

Yang dijangka parameter dalam JUnit 4:

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

Sekarang, kita boleh menggunakan kaedah assertThrows :

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

Yang tamat masa atribut dalam JUnit 4:

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

Kini, assertTimeout kaedah dalam JUnit 5:

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

Anotasi lain yang diubah dalam JUnit 5:

  • @Sebelum anotasi dinamakan semula menjadi @BeforeEach
  • Selepas anotasi dinamakan semula menjadi @AfterEach
  • Anotasi @BeforeClass dinamakan semula menjadi @BeforeAll
  • Anotasi @AfterClass dinamakan semula menjadi @AfterAll
  • @ Abaikan anotasi dinamakan semula menjadi @Disabled

3.2. Ketegasan

Kita sekarang boleh menulis mesej penegasan dalam lambda di JUnit 5, yang membolehkan penilaian malas melangkau pembinaan mesej yang rumit sehingga diperlukan:

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

Kami juga dapat mengumpulkan penegasan dalam 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. Andaian

Kelas Assumptions baru kini ada di org.junit.jupiter.api.Asumptions . JUnit 5 menyokong sepenuhnya kaedah andaian yang ada di JUnit 4 dan juga menambahkan satu set kaedah baru untuk membenarkan menjalankan beberapa penegasan hanya dalam senario tertentu sahaja:

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

3.4. Penandaan dan Penapisan

Di JUnit 4 kita dapat mengumpulkan ujian dengan menggunakan anotasi @Category . Dengan JUnit 5, anotasi @Kategori digantikan dengan anotasi @Tag :

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

Kami boleh memasukkan / mengecualikan tag tertentu menggunakan plugin maven-surefire-plugin :

   maven-surefire-plugin   junit5     

3.5. Anotasi Baru untuk Menjalankan Ujian

The @RunWith digunakan untuk mengintegrasikan konteks ujian dengan rangka kerja lain atau untuk menukar aliran pelaksanaan keseluruhan dalam kes-kes ujian dalam JUnit 4.

Dengan JUnit 5, kita sekarang boleh menggunakan anotasi @ExtendWith untuk menyediakan fungsi yang serupa.

Sebagai contoh, untuk menggunakan ciri Spring di JUnit 4:

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

Sekarang, dalam JUnit 5 ia adalah pelanjutan ringkas:

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

3.6. Anotasi Peraturan Ujian Baru

Dalam JUnit 4, anotasi @Rule dan @ ClassRule digunakan untuk menambahkan fungsi khas untuk ujian.

Di JUnit 5. kita boleh menghasilkan semula logik 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 dalam artikel ini, JUnit 5 adalah rangka kerja modular dan moden mengenai JUnit 4. Kami telah memperkenalkan perbezaan utama antara kedua versi ini dan mengisyaratkan cara berpindah dari satu ke yang lain.

Pelaksanaan penuh tutorial ini boleh didapati di GitHub.