2017-07-19 25 views
6

Tôi có một lớp BaseTest bao gồm một số bài kiểm tra. Mỗi bài kiểm tra sẽ được thực hiện cho danh sách MỌI hồ sơ tôi.Spring Boot/JUnit, chạy tất cả các bài kiểm tra đơn vị cho nhiều cấu hình

Tôi nghĩ về việc sử dụng các giá trị tham số như:

@RunWith(Parameterized.class) 
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 
// @ActiveProfiles("h2-test") // <-- how to iterate over this? 
public abstract class BaseTest { 

@Autowired 
private TestRepository test; 

// to be used with Parameterized/Spring 
private TestContextManager testContextManager; 

public BaseTest(String profile) { 
    System.setProperty("spring.profiles.active", profile); 
    // TODO what now? 
} 

@Parameterized.Parameters 
public static Collection<Object[]> data() { 
    Collection<Object[]> params = new ArrayList<>(); 
    params.add(new Object[] {"h2-test" }); 
    params.add(new Object[] {"mysql-test" }); 
    return params; 
} 

@Before 
public void setUp() throws Exception { 
    this.testContextManager = new TestContextManager(getClass()); 
    this.testContextManager.prepareTestInstance(this); 
    // maybe I can spinup Spring here with my profile? 
} 

@Test 
public void testRepository() { 
    Assert.assertTrue(test.exists("foo")) 
} 

Làm thế nào tôi sẽ nói với mùa xuân để chạy từng thử nghiệm với các cấu hình khác nhau? Trong thực tế, mỗi hồ sơ sẽ nói chuyện với các nguồn dữ liệu khác nhau (trong bộ nhớ h2, mysql bên ngoài, oracle bên ngoài, ..) vì vậy kho lưu trữ/nguồn dữ liệu của tôi phải được reinitialized.


tôi biết rằng tôi có thể chỉ định @ActiveProfiles (...) và tôi thậm chí có thể kéo dài từ BaseTest và ghi đè lên các chú thích ActiveProfile. Mặc dù điều này sẽ làm việc, tôi chỉ hiển thị một phần của bộ thử nghiệm của tôi. Rất nhiều lớp thử nghiệm của tôi mở rộng từ BaseTest và tôi không muốn tạo một số sơ yếu lý lịch khác nhau cho mỗi lớp. Hiện đang làm việc, nhưng giải pháp xấu xí:

  • BaseTest (@ActiveProfiles ("mysql"))
    • FooClassMySQL (chú thích từ BaseTest)
      • FooClassH2 (@ActiveProfiles ("h2"))
    • BarClassMySQL (chú thích từ BaseTest)
      • BarClassH2 (@ActiveProfiles ("h2"))

Cảm ơn

+0

Tại sao không chạy tất cả các thử nghiệm có thông số, ví dụ: nếu bạn sử dụng Maven, nó có thể là 'mvn test -Dspring.profiles.active = test'. Tôi không chắc liệu bạn có thể đạt được nó bằng lớp tham số này hay không, chủ yếu là vì Spring hầu như sẽ khởi động ngữ cảnh của nó trước khi nó bắt đầu thực hiện kiểm thử của bạn và bạn phải thiết lập cấu hình hoạt động trước đó. –

+0

Cảm ơn. Giải pháp rất đẹp mà tôi chưa từng nghĩ đến. Điều này chắc chắn sẽ làm gì nếu không có một cách thanh lịch để đối phó với nó trong mã! Tôi nghĩ rằng vấn đề duy nhất với điều này có thể chỉ là một vài thử nghiệm (trên thực tế, tất cả các kiểm tra kho lưu trữ/jpa của tôi), cần phải có các cấu hình khác nhau, trong khi những người khác không/cần truy cập các cấu hình khác nhau. – Frame91

+0

Tuyệt! Tôi sẽ thêm nó như một câu trả lời nếu nó phù hợp với bạn. –

Trả lời

3

Nếu bạn sử dụng Maven bạn thực sự có thể xác định cấu hình hoạt động từ dòng lệnh (hoặc env biến nếu cần thiết):

mvn clean test -Dspring.profiles.active=h2-test 

Cách tiếp cận với thử nghiệm được tham số hóa có thể không hoạt động trong trường hợp này, vì profile phải được xác định trước khi Spring khởi động ngữ cảnh của nó. Trong trường hợp này khi bạn chạy thử nghiệm tích hợp tham số, ngữ cảnh sẽ được khởi động trước khi chạy thử nghiệm bắt đầu chạy thử nghiệm của bạn. Ngoài ra các bài kiểm tra tham số của JUnit được phát minh vì các lý do khác (chạy thử nghiệm đơn vị với chuỗi dữ liệu khác nhau).

EDIT: Ngoài ra một điều nữa - khi bạn quyết định sử dụng @RunWith(Parameterized.class) bạn sẽ không thể sử dụng nhân tố khác. Trong nhiều trường hợp (nếu không phải tất cả nếu nói đến thử nghiệm tích hợp) bạn muốn chỉ định người chạy khác nhau, như SpringRunner.class - với thử nghiệm được tham số hóa, bạn sẽ không thể thực hiện được.

+0

Tôi đã chỉnh sửa mã của mình, cho thấy cách tôi có thể giải quyết SpringRunner.class (TestContextManager) – Frame91

4

Cấu hình mùa xuân không được thiết kế để hoạt động theo cách này.
Trong trường hợp của bạn, mỗi cấu hình sử dụng nguồn dữ liệu cụ thể.
Vì vậy, mỗi yêu cầu tải khởi động Spring để chạy thử nghiệm với nguồn dữ liệu dự kiến.

Thực tế, những gì bạn muốn làm cũng giống như tạo bao nhiêu Maven làm hồ sơ Spring mà bạn muốn kiểm tra.

Ngoài ra, xây dựng trong môi trường địa phương phải càng nhanh càng tốt.
Nhân thực hiện kiểm tra tự động bằng cách triển khai DBMS yêu cầu tải lại Khởi động lại cho mỗi lần sẽ không giúp ích gì.

Bạn không cần phải chỉ định @ActiveProfiles.

Nó trông giống như một nhiệm vụ cho một công cụ tích hợp liên tục, nơi bạn có thể định nghĩa một công việc thực thi (tuần tự hoặc song song) mỗi Maven xây dựng bằng cách xác định một hồ sơ Xuân Boot cụ thể:

mvn clean test -Dspring.profiles.active=h2 

mvn clean test -Dspring.profiles.active=mysql 

vv ...

Bạn cũng có thể thử thực hiện bằng địa phương bằng cách viết một tập lệnh thực hiện việc xây dựng maven.
Nhưng như đã nói, nó sẽ làm chậm quá trình xây dựng cục bộ của bạn và cũng phức tạp.

Các vấn đề liên quan