Bạn có thể làm điều này với TestRule . Điều này sẽ cung cấp cho bạn sự linh hoạt cần thiết. TestRule cho phép bạn chèn logic xung quanh bài kiểm tra, vì vậy bạn sẽ triển khai vòng lặp thử lại:
public class RetryTest {
public class Retry implements TestRule {
private int retryCount;
public Retry(int retryCount) {
this.retryCount = retryCount;
}
public Statement apply(Statement base, Description description) {
return statement(base, description);
}
private Statement statement(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
Throwable caughtThrowable = null;
for (int i = 0; i < retryCount; i++) {
try {
base.evaluate();
return;
} catch (Throwable t) {
caughtThrowable = t;
System.err.println(description.getDisplayName() + ": run " + (i+1) + " failed");
}
}
System.err.println(description.getDisplayName() + ": giving up after " + retryCount + " failures");
throw caughtThrowable;
}
};
}
}
@Rule
public Retry retry = new Retry(3);
@Test
public void test1() {
}
@Test
public void test2() {
Object o = null;
o.equals("foo");
}
}
Trọng tâm của a TestRule
là base.evaluate()
, gọi phương pháp thử nghiệm của bạn. Vì vậy, xung quanh cuộc gọi này, bạn đặt một vòng lặp thử lại. Nếu một ngoại lệ được đưa ra trong phương pháp thử nghiệm của bạn (lỗi khẳng định thực sự là một AssertionError
), thì thử nghiệm đã không thành công và bạn sẽ thử lại.
Có một thứ khác có thể được sử dụng. Bạn có thể chỉ muốn áp dụng logic thử lại này cho một tập hợp các bài kiểm tra, trong trường hợp đó, bạn có thể thêm vào lớp Thử lại bên trên một bài kiểm tra cho một chú thích cụ thể trên phương thức. Description
chứa một danh sách các chú thích cho phương pháp. Để biết thêm thông tin về điều này, hãy xem câu trả lời của tôi cho Cách chạy một số mã trước mỗi phương thức JUnit @Test riêng lẻ, mà không sử dụng @RunWith hay AOP? .
Sử dụng TestRunner tùy chỉnh
Đây là gợi ý của CKuck, bạn có thể định nghĩa Runner của riêng mình. Bạn cần mở rộng BlockJUnit4ClassRunner và ghi đè runChild (). Để biết thêm thông tin, hãy xem câu trả lời của tôi về Cách xác định quy tắc phương thức JUnit trong một bộ? . Câu trả lời này trình bày chi tiết cách xác định cách chạy mã cho mọi phương thức trong Suite mà bạn phải xác định Trình chạy của riêng mình.