Kiểm tra tích hợp với Maven

1. Khái quát chung

Maven là công cụ xây dựng phổ biến nhất trong không gian Java, trong khi kiểm tra tích hợp là một phần thiết yếu của quá trình phát triển. Do đó, việc cấu hình và thực hiện các bài kiểm tra tích hợp với Maven là một lựa chọn tự nhiên.

Trong hướng dẫn này, chúng ta sẽ xem xét một số cách khác nhau để sử dụng Maven để kiểm tra tích hợp và để tách các bài kiểm tra tích hợp khỏi các bài kiểm tra đơn vị.

2. Chuẩn bị

Để làm cho mã trình diễn gần với một dự án trong thế giới thực, chúng tôi sẽ thiết lập một ứng dụng JAX-RS. Ứng dụng này được triển khai tới máy chủ trước khi thực hiện các bài kiểm tra tích hợp và được gỡ bỏ sau đó.

2.1. Cấu hình Maven

Chúng tôi sẽ xây dựng ứng dụng REST của mình xung quanh Jersey - việc triển khai tham chiếu của JAX-RS. Việc triển khai này yêu cầu một số phụ thuộc:

 org.glassfish.jersey.containers jersey-container-servlet-core 2.27   org.glassfish.jersey.inject jersey-hk2 2.27 

Chúng tôi có thể tìm thấy các phiên bản mới nhất của các phụ thuộc này tại đây và tại đây.

Chúng tôi sẽ sử dụng plugin Jetty Maven để thiết lập môi trường thử nghiệm. Plugin này khởi động máy chủ Jetty trong giai đoạn kiểm tra trước tích hợp của vòng đời xây dựng Maven, sau đó dừng nó trong giai đoạn kiểm tra sau tích hợp .

Đây là cách chúng tôi định cấu hình plugin Jetty Maven trong pom.xml :

 org.eclipse.jetty jetty-maven-plugin 9.4.11.v20180605   8999  quit 9000    start-jetty pre-integration-test  start    stop-jetty post-integration-test  stop    

Khi máy chủ Jetty khởi động, nó sẽ lắng nghe trên cổng 8999 . Các stopKeystopPort yếu tố cấu hình được sử dụng hoàn toàn bằng của plugin dừng mục tiêu và giá trị của họ là không quan trọng từ quan điểm của chúng tôi.

Đây là nơi để tìm phiên bản mới nhất của plugin Jetty Maven.

Một điều cần lưu ý nữa là chúng ta phải đặt phần tử đóng gói trong tệp pom.xml thành war , nếu không plugin Jetty không thể khởi động máy chủ:

war

2.2. Tạo ứng dụng REST

Điểm cuối của ứng dụng rất đơn giản - trả lại thông báo chào mừng khi yêu cầu GET truy cập vào gốc ngữ cảnh:

@Path("/") public class RestEndpoint { @GET public String hello() { return "Welcome to Baeldung!"; } }

Đây là cách chúng tôi đăng ký lớp điểm cuối với Jersey:

package com.baeldung.maven.it; import org.glassfish.jersey.server.ResourceConfig; public class EndpointConfig extends ResourceConfig { public EndpointConfig() { register(RestEndpoint.class); } }

Để máy chủ Jetty biết ứng dụng REST của chúng tôi, chúng tôi có thể sử dụng bộ mô tả triển khai web.xml cổ điển :

  rest-servlet org.glassfish.jersey.servlet.ServletContainer  javax.ws.rs.Application com.baeldung.maven.it.EndpointConfig    rest-servlet /*  

Bộ mô tả này phải được đặt trong thư mục / src / main / webapp / WEB-INF để máy chủ nhận dạng.

2.3. Mã kiểm tra phía máy khách

Tất cả các lớp kiểm tra trong các phần sau đều chứa một phương thức duy nhất:

@Test public void whenSendingGet_thenMessageIsReturned() throws IOException { String url = "//localhost:8999"; URLConnection connection = new URL(url).openConnection(); try (InputStream response = connection.getInputStream(); Scanner scanner = new Scanner(response)) { String responseBody = scanner.nextLine(); assertEquals("Welcome to Baeldung!", responseBody); } }

Như chúng ta thấy, phương pháp này không làm gì khác ngoài việc gửi yêu cầu GET đến ứng dụng web mà chúng tôi đã thiết lập trước đó và xác minh phản hồi.

3. Thử nghiệm tích hợp trong hành động

Một điều quan trọng cần lưu ý về kiểm thử tích hợp là các phương pháp kiểm thử thường mất khá nhiều thời gian để chạy.

Do đó, chúng ta nên loại trừ các bài kiểm tra tích hợp khỏi vòng đời xây dựng mặc định, giúp chúng không làm chậm toàn bộ quá trình mỗi khi chúng tôi xây dựng một dự án.

Một cách thuận tiện để tách các bài kiểm tra tích hợp là sử dụng cấu hình xây dựng. Loại cấu hình này cho phép chúng tôi thực hiện các bài kiểm tra tích hợp chỉ khi cần thiết - bằng cách chỉ định một cấu hình phù hợp.

Trong các phần tiếp theo, chúng tôi sẽ định cấu hình tất cả các thử nghiệm tích hợp với cấu hình bản dựng.

4. Kiểm tra với Plugin Failsafe

Cách đơn giản nhất để chạy thử nghiệm hội nhập là sử dụng Maven failsafe plugin.

Theo mặc định, Maven chắc chắn hơn Plugin thực thi đơn vị kiểm tra trong thời gian thử nghiệm giai đoạn, trong khi các failsafe Plugin chạy thử nghiệm hội nhập trong hội nhập thử nghiệm giai đoạn .

Chúng tôi có thể đặt tên các lớp kiểm tra với các mẫu khác nhau cho các plugin đó để nhận các kiểm tra kèm theo một cách riêng biệt.

Các quy ước đặt tên mặc định được thực thi bởi surefirefailsafe là khác nhau, do đó chúng ta chỉ cần tuân theo các quy ước này để tách biệt các bài kiểm tra đơn vị và tích hợp.

Việc thực thi plugin chắc chắn bao gồm tất cả các lớp có tên bắt đầu bằng Test hoặc kết thúc bằng Test , Tests hoặc TestCase . Ngược lại, plugin an toàn dự phòng thực thi các phương pháp kiểm tra trong các lớp có tên bắt đầu bằng IT hoặc kết thúc bằng IT hoặc ITCase .

Đây là nơi chúng tôi có thể tìm thấy tài liệu liên quan đến bao gồm thử nghiệm để chắc chắn và đây là tài liệu về an toàn dự phòng .

Hãy thêm plugin an toàn dự phòng vào POM với cấu hình mặc định:

 failsafe    maven-failsafe-plugin 2.22.0    integration-test verify       

Liên kết này là nơi để tìm phiên bản mới nhất của plugin an toàn dự phòng .

With the above configuration, the following test method will be executed in the integration-test phase:

public class RestIT { // test method shown in subsection 2.3 }

Since the Jetty server starts up in the pre-integration-test phase and shuts down in post-integration-test, the test we have just seen passes with this command:

mvn verify -Pfailsafe

We can also customize the naming patterns to include classes with different names:

 maven-failsafe-plugin 2.22.0   **/*RestIT **/RestITCase   ... 

5. Testing With the Surefire Plugin

Apart from the failsafe plugin, we can also use the surefire plugin to execute unit and integration tests in different phases.

Let's assume we want to name all integration tests with the suffix IntegrationTest. Since the surefire plugin runs tests with such a name in the test phase by default, we need to exclude them from the default execution:

 maven-surefire-plugin 2.22.0   **/*IntegrationTest   

The latest version of this plugin is here.

We've taken all test classes having a name ending with IntegrationTest out of the build lifecycle. It's time to put them back with a profile:

 surefire    maven-surefire-plugin 2.22.0   integration-test  test    none   **/*IntegrationTest        

Instead of binding the test goal of the surefire plugin to the test build phase, as usual, we bound it to the integration-test phase. The plugin will then kick in during the integration testing process.

Notice that we must set an exclude element to none to override the exclusion specified in the base configuration.

Now, let's define an integration test class with our naming pattern:

public class RestIntegrationTest { // test method shown in subsection 2.3 }

This test will be running with the command:

mvn verify -Psurefire

6. Testing With the Cargo Plugin

We can use the surefire plugin with the Maven cargo plugin. This plugin comes with built-in support for embedded servers, which are very useful for integration testing.

More details about this combination can be found here.

7. Testing With JUnit's @Category

A convenient way to selectively execute tests is to leverage the @Category annotation in the JUnit 4 framework. This annotation lets us exclude particular tests from unit testing, and include them in integration testing.

First off, we need an interface or class to work as a category identifier:

package com.baeldung.maven.it; public interface Integration { }

We can then decorate a test class with the @Category annotation and Integration identifier:

@Category(Integration.class) public class RestJUnitTest { // test method shown in subsection 2.3 }

Rather than declaring the @Category annotation on a test class, we can also use it at the method level to categorize individual test methods.

Excluding a category from the test build phase is simple:

 maven-surefire-plugin 2.22.0  com.baeldung.maven.it.Integration  

Including the Integration category in the integration-test phase is also straightforward:

 category    maven-failsafe-plugin 2.22.0   **/*  com.baeldung.maven.it.Integration     integration-test verify       

We can now run integration tests with a Maven command:

mvn verify -Pcategory

8. Adding a Separate Directory for Integration Tests

It's desirable at times to have a separate directory for integration tests. Organizing tests this way allows us to entirely isolate integration tests from unit tests.

We can use the Maven build helper plugin for this purpose:

 org.codehaus.mojo build-helper-maven-plugin 3.0.0   add-integration-test-source generate-test-sources  add-test-source    src/integration-test/java     

Here is where we can find the latest version of this plugin.

The configuration we've just seen adds a test source directory to the build. Let's add a class definition to that new directory:

public class RestITCase { // test method shown in subsection 2.3 }

It's time to run integration tests in this class:

mvn verify -Pfailsafe

Plugin an toàn dự phòng Maven sẽ thực thi các phương thức trong lớp thử nghiệm này do cấu hình chúng tôi đặt trong tiểu mục 3.1.

Thư mục nguồn thử nghiệm thường đi cùng với thư mục tài nguyên. Chúng tôi có thể thêm một thư mục như vậy trong một phần tử thực thi khác vào cấu hình plugin:

 ...  add-integration-test-resource generate-test-resources  add-test-resource     src/integration-test/resources     

9. Kết luận

Bài viết này đề cập đến việc sử dụng Maven để chạy các thử nghiệm tích hợp với máy chủ Jetty, tập trung vào cấu hình của các plugin Maven chắc chắnan toàn dự phòng .

Bạn có thể tìm thấy mã nguồn hoàn chỉnh cho hướng dẫn này trên GitHub.