Điều kiện bỏ qua các bài kiểm tra trong JUnit 4


365

OK, vì vậy @Ignorechú thích là tốt để đánh dấu rằng một trường hợp thử nghiệm không nên chạy.

Tuy nhiên, đôi khi tôi muốn bỏ qua một bài kiểm tra dựa trên thông tin thời gian chạy. Một ví dụ có thể là nếu tôi có một bài kiểm tra đồng thời cần được chạy trên một máy có số lượng lõi nhất định. Nếu thử nghiệm này được chạy trên máy không xử lý, tôi không nghĩ sẽ đúng khi vượt qua thử nghiệm (vì nó chưa được chạy) và chắc chắn sẽ không đúng khi thử nghiệm và phá vỡ bản dựng .

Vì vậy, tôi muốn có thể bỏ qua các thử nghiệm trong thời gian chạy, vì đây có vẻ là kết quả đúng (vì khung thử nghiệm sẽ cho phép bản dựng vượt qua nhưng ghi lại rằng các thử nghiệm không chạy). Tôi khá chắc chắn rằng chú thích sẽ không mang lại cho tôi sự linh hoạt này và nghi ngờ rằng tôi sẽ cần phải tự tạo bộ kiểm tra cho lớp đang đề cập. Tuy nhiên, tài liệu không đề cập bất cứ điều gì về điều này và xem qua API, nó cũng không rõ làm thế nào điều này sẽ được thực hiện theo chương trình (tức là làm thế nào để tôi lập trình một ví dụ Testhoặc tương tự như được tạo bởi @Ignorechú thích?).

Nếu bất cứ ai đã làm một cái gì đó tương tự trong quá khứ, hoặc có một ý tưởng sáng sủa về cách khác tôi có thể đi về điều này, tôi rất vui khi nghe về nó.

Câu trả lời:


476

Cách JUnit là làm điều này vào thời gian chạy là org.junit.Assume.

 @Before
 public void beforeMethod() {
     org.junit.Assume.assumeTrue(someCondition());
     // rest of setup.
 }

Bạn có thể làm điều đó trong một @Beforephương thức hoặc trong chính bài kiểm tra, nhưng không phải trong một @Afterphương thức. Nếu bạn làm điều đó trong chính bài kiểm tra, @Beforephương pháp của bạn sẽ được chạy. Bạn cũng có thể làm điều đó trong @BeforeClassđể ngăn chặn việc khởi tạo lớp.

Một giả định thất bại làm cho bài kiểm tra bị bỏ qua.

Chỉnh sửa: Để so sánh với @RunIfchú thích từ Junit-ext , mã mẫu của chúng sẽ trông như thế này:

@Test
public void calculateTotalSalary() {
    assumeThat(Database.connect(), is(notNull()));
    //test code below.
}

Chưa kể rằng việc nắm bắt và sử dụng kết nối từ Database.connect()phương thức này dễ dàng hơn nhiều .


1
@notnoop, đó không phải là quan sát của tôi cả. Họ bị bỏ qua. Người chạy thử nghiệm IDEA báo cáo họ theo cách đó và xem mã nguồn JUnit cho thấy rằng nó báo cáo thử nghiệm là bỏ qua.
Yishai

1
Để trích dẫn: "Trong tương lai, điều này có thể thay đổi và một giả định thất bại có thể dẫn đến thử nghiệm bị bỏ qua." Thực tế nó đã thay đổi, tính đến 4,5 tôi tin. Javadoc hiện tại cho biết: "Người chạy JUnit mặc định xử lý các bài kiểm tra với các giả định không thành công như bị bỏ qua. Người chạy tùy chỉnh có thể cư xử khác nhau." github.com/KentBeck/junit/blob/ Mạnh
Yishai

4
Eclipse 3.6 với Junit 4.8.1 báo cáo các Giả định sai khi thử nghiệm vượt qua. Tương tự với kiến ​​1.8.1.
fijiaaron

8
Việc Eclipse báo cáo các giả định thất bại vì việc vượt qua là một lỗi: bug.eclipse.org/bugs/show_orms.cgi?id=359944
Martin

1
@JeffStorey, sau đó bạn đang tìm kiếm một vài điều. Một là @BeforeClasschú thích, nơi bạn có thể có giả định của mình thất bại ở đó, sẽ bỏ qua cả lớp. Khác là @ClassRule(đối với kiểm soát hạt mịn, nhưng trên toàn bộ lớp, một lần).
Yishai

51

Bạn nên kiểm tra Junit-extdự án. Họ có RunIfchú thích thực hiện các bài kiểm tra có điều kiện, như:

@Test
@RunIf(DatabaseIsConnected.class)
public void calculateTotalSalary() {
    //your code there
}

class DatabaseIsConnected implements Checker {
   public boolean satisify() {
        return Database.connect() != null;
   }
}

[Mẫu mã được lấy từ hướng dẫn của họ]


3
Cảm ơn câu trả lời này - một cú pháp thay thế thú vị cho chức năng, mặc dù tôi sẽ Assumetrực tiếp thực hiện để không giới thiệu một phụ thuộc khác.
Andrzej Doyle

3
Cá nhân tôi thích giải pháp này. Nếu bạn có nhiều bài kiểm tra nên được chạy dựa trên cùng điều kiện, điều này sẽ lý tưởng hơn nhiều so với việc phải sử dụng Giả sử trong mọi bài kiểm tra. Ngoài ra, nếu điều này có thể được sử dụng ở cấp độ lớp hơn là cấp độ phương thức, nó sẽ còn lý tưởng hơn nữa.
Richard

Tôi thích nó hơn, vì điều này giúp chạy thử nghiệm có điều kiện trong thời gian chạy. Nó phù hợp với nơi một số bài kiểm tra đơn vị sẽ chạy và yêu cầu là chạy các bài kiểm tra đơn vị trên trình kiểm tra cụ thể. Tôi thực sự ngạc nhiên khi thấy rằng Junit-ext không có sẵn trên kho lưu trữ của maven. Làm thế nào chúng ta sẽ có được điều này trong dự án maven.
shambhu

4
Một chú thích như @RunIftách biệt điều kiện khi một bài kiểm tra nên chạy từ mã kiểm tra thực tế, mà tôi nghĩ là tốt. Những gì tôi không thích là nó đòi hỏi một người chạy thử cụ thể. Do đó, tôi đã viết một quy tắc JUnit để bỏ qua các bài kiểm tra.
Rüdiger Herrmann

2
Sau khi cài đặt jar Junit-ext (tìm thấy ở đây code.google.com/p/junit-ext/doads/ nam ) trong kho lưu trữ cục bộ của chúng tôi và thực hiện chú thích @Run If này ... không có gì! Nó hoàn toàn bị bỏ qua, và tôi nghĩ lý do có thể là Junit-ext dường như phụ thuộc vào Junit 4.5. Chúng tôi cần 4,9+ do kiểm tra mùa xuân. Vì vậy, ... đừng bận tâm điều đó.
Marc

7

Trong JUnit 4, một tùy chọn khác cho bạn có thể là tạo một chú thích để biểu thị rằng thử nghiệm cần phải đáp ứng các tiêu chí tùy chỉnh của bạn, sau đó mở rộng trình chạy mặc định bằng chính bạn và sử dụng phản xạ, dựa trên quyết định của bạn dựa trên tiêu chí tùy chỉnh. Nó có thể trông giống như thế này:

public class CustomRunner extends BlockJUnit4ClassRunner {
    public CTRunner(Class<?> klass) throws initializationError {
        super(klass);
    }

    @Override
    protected boolean isIgnored(FrameworkMethod child) {
        if(shouldIgnore()) {
            return true;
        }
        return super.isIgnored(child);
    }

    private boolean shouldIgnore(class) {
        /* some custom criteria */
    }
}

Mặc dù điều này trông đẹp và sạch sẽ, nhưng nó không hoạt động với các phiên bản hiện tại nếu JUnit4, vì BlockJUnit4ClassRunnernó không cung cấp isIgnoredphương thức nữa.
Dave

-2

Lưu ý nhanh: Assume.assumeTrue(condition)bỏ qua các bước còn lại nhưng vượt qua bài kiểm tra. Để trượt bài kiểm tra, sử dụng org.junit.Assert.fail()bên trong câu lệnh có điều kiện. Hoạt động giống như Assume.assumeTrue()nhưng thất bại trong bài kiểm tra.


5
Như đã lưu ý trong các câu trả lời ở trên, một giả định thất bại không khiến bài kiểm tra vượt qua, nó trả về một trạng thái riêng biệt. Một số người chạy có thể báo cáo sai điều này như thể đó là một lần vượt qua, nhưng đó là điểm yếu / lỗi trong trình chạy thử nghiệm (và trình chạy JUnit mặc định hiển thị bài kiểm tra như bị bỏ qua). Và đối với câu cuối cùng của bạn, việc trượt bài kiểm tra đặc biệt không phải là điều tôi muốn (ed) làm.
Andrzej Doyle

Ồ được thôi. Các thử nghiệm đã vượt qua giả định thất bại trong trường hợp của tôi nhưng tôi muốn chúng được báo cáo là thất bại (tôi đang kiểm tra ngoại lệ từ Test Watcher). Buộc một thất bại đã giúp tôi.
TIn TIn
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.