Kontena Docker Test di Java Test

1. Pengenalan

Dalam tutorial ini, kita akan melihat perpustakaan Java TestContainers . Ini membolehkan kami menggunakan bekas Docker dalam ujian kami. Hasilnya, kita dapat menulis ujian integrasi mandiri yang bergantung pada sumber luaran.

Kami boleh menggunakan sebarang sumber dalam ujian kami yang mempunyai imej pelabuhan. Sebagai contoh, terdapat gambar untuk pangkalan data, penyemak imbas web, pelayan web, dan barisan mesej. Oleh itu, kami boleh menjalankannya sebagai bekas dalam ujian kami.

2. Keperluan

Perpustakaan TestContainers boleh digunakan dengan Java 8 dan lebih tinggi. Selain itu, ia serasi dengan JUnit Rules API.

Pertama, mari tentukan kebergantungan maven untuk fungsi teras:

 org.testcontainers testcontainers 1.11.4 

Terdapat juga modul untuk bekas khas. Dalam tutorial ini, kita akan menggunakan PostgreSQL dan Selenium.

Mari tambahkan kebergantungan yang berkaitan:

 org.testcontainers postgresql  1.11.4   org.testcontainers selenium  1.11.4 

Kami boleh mendapatkan versi terbaru di Maven Central.

Kita juga memerlukan Docker untuk menjalankan kontena . Rujuk dokumentasi Docker untuk arahan pemasangan.

Pastikan anda dapat menjalankan bekas Docker di persekitaran ujian anda.

3. Penggunaan

Mari konfigurasikan peraturan bekas generik:

@ClassRule public static GenericContainer simpleWebServer = new GenericContainer("alpine:3.2") .withExposedPorts(80) .withCommand("/bin/sh", "-c", "while true; do echo " + "\"HTTP/1.1 200 OK\n\nHello World!\" | nc -l -p 80; done");

Kami membina peraturan ujian GenericContainer dengan menentukan nama gambar docker. Kemudian, kami mengkonfigurasinya dengan kaedah pembina:

  • Kami menggunakan denganExposedPorts untuk memaparkan port dari bekas
  • withCommand mentakrifkan perintah kontena. Ia akan dilaksanakan semasa kontena bermula.

Peraturan tersebut dijelaskan dengan @ClassRule. Akibatnya, ia akan memulakan kontena Docker sebelum sebarang ujian di kelas tersebut dijalankan . Bekas akan musnah setelah semua kaedah dijalankan.

Sekiranya anda menggunakan anotasi @Rule , peraturan GenericContainer akan memulakan wadah baru untuk setiap kaedah ujian. Dan itu akan menghentikan bekas apabila kaedah ujian itu selesai.

Kita boleh menggunakan alamat IP dan port untuk berkomunikasi dengan proses yang berjalan di dalam wadah :

@Test public void givenSimpleWebServerContainer_whenGetReuqest_thenReturnsResponse() throws Exception { String address = "//" + simpleWebServer.getContainerIpAddress() + ":" + simpleWebServer.getMappedPort(80); String response = simpleGetRequest(address); assertEquals(response, "Hello World!"); }

4. Kaedah Penggunaan

Terdapat beberapa mod penggunaan bekas ujian. Kami melihat contoh menjalankan GenericContainer.

Perpustakaan TestContainers juga mempunyai definisi peraturan dengan fungsi khusus. Mereka adalah untuk kontena pangkalan data biasa seperti MySQL, PostgreSQL; dan lain-lain seperti pelanggan web.

Walaupun kami dapat menggunakannya sebagai wadah generik, pengkhususan itu menyediakan kaedah kemudahan yang diperluas.

4.1. Pangkalan Data

Anggaplah kita memerlukan pelayan pangkalan data untuk ujian integrasi lapisan akses data. Kita boleh menjalankan pangkalan data dalam bekas dengan bantuan perpustakaan TestContainers.

Sebagai contoh, kami menghidupkan bekas PostgreSQL dengan peraturan PostgreSQLC . Kemudian, kami dapat menggunakan kaedah penolong. Ini adalah getJdbcUrl, getUsername, getPassword untuk sambungan pangkalan data:

@Rule public PostgreSQLContainer postgresContainer = new PostgreSQLContainer(); @Test public void whenSelectQueryExecuted_thenResulstsReturned() throws Exception { String jdbcUrl = postgresContainer.getJdbcUrl(); String username = postgresContainer.getUsername(); String password = postgresContainer.getPassword(); Connection conn = DriverManager .getConnection(jdbcUrl, username, password); ResultSet resultSet = conn.createStatement().executeQuery("SELECT 1"); resultSet.next(); int result = resultSet.getInt(1); assertEquals(1, result); }

Anda juga boleh menjalankan PostgreSQL sebagai wadah generik. Tetapi akan lebih sukar untuk mengkonfigurasi sambungan.

4.2. Pemacu Web

Senario lain yang berguna ialah menjalankan kontena dengan penyemak imbas web. Peraturan BrowserWebDriverContainer membolehkan menjalankan Chrome dan Firefox dalam bekas docker-selenium . Kemudian, kami menguruskannya dengan RemoteWebDriver.

Ini sangat berguna untuk mengautomasikan UI / Uji penerimaan untuk aplikasi web:

@Rule public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer() .withCapabilities(new ChromeOptions()); @Test public void whenNavigatedToPage_thenHeadingIsInThePage() { RemoteWebDriver driver = chrome.getWebDriver(); driver.get("//example.com"); String heading = driver.findElement(By.xpath("/html/body/div/h1")) .getText(); assertEquals("Example Domain", heading); }

4.3. Karang Docker

Sekiranya ujian memerlukan perkhidmatan yang lebih kompleks, kami dapat menentukannya dalam fail compose docker :

simpleWebServer: image: alpine:3.2 command: ["/bin/sh", "-c", "while true; do echo 'HTTP/1.1 200 OK\n\nHello World!' | nc -l -p 80; done"]

Kemudian, kami menggunakan peraturan DockerComposeContainer . Peraturan ini akan memulakan dan menjalankan perkhidmatan seperti yang ditentukan dalam fail tulis.

Kami menggunakan getServiceHost dan getServicePost kaedah untuk alamat sambungan bina untuk perkhidmatan:

@ClassRule public static DockerComposeContainer compose = new DockerComposeContainer( new File("src/test/resources/test-compose.yml")) .withExposedService("simpleWebServer_1", 80); @Test public void givenSimpleWebServerContainer_whenGetReuqest_thenReturnsResponse() throws Exception { String address = "//" + compose.getServiceHost("simpleWebServer_1", 80) + ":" + compose.getServicePort("simpleWebServer_1", 80); String response = simpleGetRequest(address); assertEquals(response, "Hello World"); }

5. Kesimpulan

Kami melihat bagaimana kami boleh menggunakan perpustakaan TestContainers . Ini memudahkan pengembangan dan menjalankan ujian integrasi.

Kami menggunakan peraturan GenericContainer untuk bekas gambar docker yang diberikan. Kemudian, kami melihat peraturan PostgreSQLContainer, BrowserWebDriverContainer dan DockerComposeContainer . Mereka memberikan lebih banyak fungsi untuk kes penggunaan tertentu.

Akhirnya, contoh kod di sini boleh didapati di GitHub.