Junit: tách thử nghiệm tích hợp và thử nghiệm đơn vị


126

Tôi đã thừa hưởng một tải thử nghiệm Junit, nhưng các thử nghiệm này (ngoài hầu hết không hoạt động) là một hỗn hợp của thử nghiệm đơn vị thực tế và thử nghiệm tích hợp (yêu cầu các hệ thống bên ngoài, db, v.v.).

Vì vậy, tôi đang cố gắng nghĩ ra một cách để thực sự tách chúng ra, để tôi có thể chạy thử nghiệm đơn vị tốt và nhanh chóng và các thử nghiệm tích hợp sau đó.

Các tùy chọn là ..

  1. Chia chúng thành các thư mục riêng biệt.

  2. Di chuyển đến Junit4 (từ v3) và chú thích các lớp để phân tách chúng.

  3. Sử dụng quy ước đặt tên tệp để cho biết một lớp là gì, tức là AdapterATest và AdapterAIntergrationTest.

3 có một vấn đề là Eclipse có tùy chọn "Chạy tất cả các thử nghiệm trong dự án / gói hoặc thư mục đã chọn". Vì vậy, sẽ rất khó để chạy các bài kiểm tra tích hợp.

2: có nguy cơ các nhà phát triển có thể bắt đầu viết các bài kiểm tra tích hợp trong các lớp kiểm tra đơn vị và nó trở nên lộn xộn.

1: Có vẻ như là giải pháp gọn gàng nhất, nhưng ruột của tôi nói rằng phải có một giải pháp tốt hơn ngoài kia.

Vì vậy, đó là câu hỏi của tôi, làm thế nào để bạn phá vỡ các bài kiểm tra tích hợp và bài kiểm tra đơn vị thích hợp?


Tôi chỉ muốn cảm ơn tất cả các bạn cho đầu vào của bạn, tôi biết đây là một câu hỏi chủ quan, và không một câu trả lời đúng. Nhưng bạn đã giúp tôi nhận ra rằng không có lựa chọn nào khác ngoài những lựa chọn tôi đã liệt kê. Tôi nghĩ rằng tôi sẽ đi với cấu trúc thư mục vào lúc này và chuyển sang JUnit4, mặc dù chưa sử dụng các chú thích để tách chúng ra.
porter jeff

Câu trả lời:


10

Tôi hiện đang sử dụng các thư mục riêng biệt do chính sách của tổ chức (và di sản Junit 3) nhưng hiện tại tôi đang muốn chuyển sang chú thích. Tôi đang ở trên Junit 4.

Tôi sẽ không quá lo lắng về việc các nhà phát triển đưa các bài kiểm tra tích hợp vào các lớp kiểm tra đơn vị của bạn - thêm một quy tắc trong các tiêu chuẩn mã hóa của bạn nếu cần thiết.

Tôi muốn biết loại giải pháp nào khác ngoài các chú thích hoặc tách biệt các lớp ..


145

Bạn có thể phân chia chúng rất dễ dàng bằng cách sử dụng các danh mục JUnit và Maven.

Điều này được thể hiện rất, rất ngắn gọn dưới đây bằng cách tách các bài kiểm tra đơn vị và tích hợp.

Xác định giao diện đánh dấu

Bước đầu tiên trong việc nhóm thử nghiệm bằng các danh mục là tạo giao diện đánh dấu.

Giao diện này sẽ được sử dụng để đánh dấu tất cả các bài kiểm tra mà bạn muốn được chạy dưới dạng kiểm tra tích hợp.

public interface IntegrationTest {}

Đánh dấu các lớp kiểm tra của bạn

Thêm chú thích danh mục vào đầu lớp kiểm tra của bạn. Nó có tên của giao diện mới của bạn.

import org.junit.experimental.categories.Category;
@Category(IntegrationTest.class)
public class ExampleIntegrationTest{
  @Test
  public void longRunningServiceTest() throws Exception {
  }
}

Cấu hình kiểm tra đơn vị Maven

Cái hay của giải pháp này là không có gì thực sự thay đổi đối với mặt thử nghiệm đơn vị của mọi thứ.

Chúng tôi chỉ cần thêm một số cấu hình vào plugin maven Surefire để làm cho nó bỏ qua mọi thử nghiệm tích hợp.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <includes>
      <include>**/*.class</include>
    </includes>
    <excludedGroups>com.test.annotation.type.IntegrationTest</excludedGroups>
  </configuration>
</plugin>

Khi bạn thực hiện kiểm tra sạch mvn, chỉ các kiểm tra đơn vị chưa được đánh dấu của bạn sẽ chạy.

Cấu hình kiểm tra tích hợp Maven

Một lần nữa cấu hình cho việc này rất đơn giản.

Để chỉ chạy các bài kiểm tra tích hợp, hãy sử dụng:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <groups>com.test.annotation.type.IntegrationTest</groups>
  </configuration>
</plugin>

Nếu bạn bọc cái này trong một hồ sơ bằng id IT, bạn chỉ có thể chạy các bài kiểm tra nhanh bằng cách sử dụng mvn clean install. Để chạy chỉ tích hợp / kiểm tra chậm, sử dụng mvn clean install -P IT.

Nhưng thông thường nhất, bạn sẽ muốn chạy các bài kiểm tra nhanh theo mặc định và tất cả các bài kiểm tra với -P IT. Nếu đó là trường hợp, thì bạn phải sử dụng một mẹo:

<profiles>
    <profile>
        <id>IT</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <excludedGroups>java.io.Serializable</excludedGroups> <!-- An empty element doesn't overwrite, so I'm using an interface here which no one will ever use -->
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

Như bạn có thể thấy, tôi loại trừ các bài kiểm tra được chú thích java.io.Serializable. Điều này là cần thiết bởi vì cấu hình sẽ kế thừa cấu hình mặc định của plugin Surefire, vì vậy ngay cả khi bạn nói <excludedGroups/>hoặc <excludedGroups></excludedGroups>, giá trị com.test.annotation.type.IntegrationTestsẽ được sử dụng.

Bạn cũng không thể sử dụng nonevì nó phải là một giao diện trên đường dẫn lớp (Maven sẽ kiểm tra điều này).

Ghi chú:

  • Việc phụ thuộc surefire-junit47chỉ cần thiết khi Maven không tự động chuyển sang trình chạy JUnit 4. Sử dụng groupshoặc excludedGroupsphần tử sẽ kích hoạt chuyển đổi. Xem ở đây .
  • Hầu hết các mã ở trên được lấy từ tài liệu cho plugin Maven Failsafe. Xem phần "Sử dụng Danh mục JUnit" trên trang này .
  • Trong các thử nghiệm của mình, tôi thấy rằng điều này thậm chí hoạt động khi bạn sử dụng @RunWith()các chú thích để chạy các bộ hoặc các thử nghiệm dựa trên Spring.

18
Tôi nghĩ rằng có một lỗi trong đoạn pom.xml cuối cùng của bạn. bạn đã dán đoạn trích tương tự như cho giai đoạn "thử nghiệm". nó vẫn loại trừ các thử nghiệm tích hợp và cũng không bị ràng buộc với bất kỳ pha maven nào.
Alex

1
Thật vậy, đoạn pom cuối cùng là một lỗi sao chép và dán. Nó sẽ hiển thị maven-failafe-plugin.
Paulo Merson

2
Vậy xml thứ hai nên là gì? : O
Liv

Bạn không phải sử dụng mánh khóe (phép thuật cuối cùng với Nối tiếp) nếu bạn sử dụng hồ sơ Maven mặc định
user831217

Đây thực sự nên là câu trả lời được chấp nhận bởi vì đây thực sự là một giải pháp cho câu hỏi thay vì một cuộc tranh luận triết học về nơi đặt các bài kiểm tra khác nhau.
Bwvcarball

40

Chúng tôi sử dụng Plugin Maven Surefire để chạy thử nghiệm đơn vị và Plugin Maven Failsafe để chạy thử nghiệm tích hợp. Kiểm tra đơn vị tuân theo các **/Test*.java **/*Test.java **/*TestCase.javaquy ước đặt tên, kiểm tra tích hợp - **/IT*.java **/*IT.java **/*ITCase.java. Vì vậy, nó thực sự là lựa chọn số ba của bạn.

Trong một vài dự án, chúng tôi sử dụng TestNG và xác định các nhóm thử nghiệm khác nhau để kiểm tra tích hợp / đơn vị, nhưng điều này có lẽ không phù hợp với bạn.


1
+1 cho combo maven + Surefire + failafe + Junit. Tôi đã không nhận ra failafe sẽ chạy "IT *" một cách tự động. Ngọt.
PapaFreud

13

Tôi sẽ chuyển lên Junit4 chỉ vì có nó :)

Bạn có thể tách chúng thành các bộ thử nghiệm khác nhau. Tôi không biết làm thế nào chúng được tổ chức trong Junit3 nhưng thật dễ dàng trong Junit4 chỉ để xây dựng các bộ thử nghiệm và đặt tất cả các thử nghiệm đơn vị thực sự vào một trong số chúng và sau đó sử dụng bộ thứ hai cho các thử nghiệm tích hợp.

Bây giờ hãy xác định cấu hình chạy cho cả hai bộ trong nhật thực và bạn có thể dễ dàng chạy một bộ duy nhất. Các bộ này cũng có thể được khởi chạy từ một quy trình tự động cho phép bạn chạy thử nghiệm đơn vị mỗi khi nguồn thay đổi và có thể các thử nghiệm tích hợp (nếu chúng thực sự lớn) chỉ một lần một ngày hoặc một lần một giờ.


9

Sử dụng chú thích mùa xuân IfProfileValue giúp bạn có thể đạt được điều này mà không cần plugin maven hoặc cấu hình.

Chú thích các lớp hoặc phương thức kiểm thử tích hợp bằng IfProfileValue

import org.springframework.test.annotation.IfProfileValue;

@IfProfileValue(name="test-groups", value="integration")
public class ExampleIntegrationTest{
    @Test
    public void longRunningServiceTest() throws Exception {
    }
} 

Để chạy chỉ sử dụng kiểm tra đơn vị:

mvn clean test

Để chạy bằng kiểm tra tích hợp và kiểm tra đơn vị:

mvn clean test -Dtest-groups=integration

Ngoài ra, "Chạy tất cả thử nghiệm" trong IDE sẽ chỉ chạy thử nghiệm đơn vị. Thêm -Dtest-groups=integrationvào đối số VM để chạy cả kiểm tra tích hợp và đơn vị.


Cách tiếp cận này rất hay và đơn giản, nhưng vấn đề tôi thấy là theo mặc định tôi muốn chạy tất cả các bài kiểm tra (bao gồm cả kiểm tra tích hợp). Điều đó là không thể với phương pháp này, phải không?
csalazar

6

Không có một câu trả lời đúng. Như bạn đã giải thích, có một số cách để làm điều đó sẽ làm việc. Tôi đã thực hiện cả sơ đồ đặt tên tệp và chia mọi thứ vào các thư mục khác nhau.

Nghe có vẻ như việc chia nhỏ mọi thứ vào các thư mục khác nhau có thể phù hợp với bạn hơn và điều đó có vẻ rõ ràng hơn đối với tôi, vì vậy tôi nghiêng về phía đó.

Tôi không nghĩ rằng tôi sẽ thử chú thích bởi vì điều đó dường như tốt hơn đối với tôi. Bạn có thực sự muốn hai loại thử nghiệm này trộn lẫn trong cùng một tệp không? Tôi sẽ không.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.