Câu hỏi Làm thế nào tôi có thể làm cho mã chạy JUnit 4.8 sau một thử nghiệm không thành công, nhưng trước bất kỳ phương thức @After nào?


Tôi đang lái một bộ kiểm tra Selenium (thực sự là Selenium được WebDriver hỗ trợ) sử dụng JUnit 4.8.2. Tôi muốn các bài kiểm tra tự động chụp ảnh màn hình của trình duyệt ngay sau khi thử nghiệm không thành công. Tất cả các thử nghiệm được kế thừa từ SeleniumBaseTestCasevà phần lớn sau đó tiếp tục kế thừa từ SeleniumBastTestCaseWithCompany (sử dụng @Before và @After các phương thức để tạo và sau đó làm sạch dữ liệu thử nghiệm thông thường thông qua Selenium).

Tôi đã thử thêm một lớp con của TestWatchman như một @Rule trong SeleniumBaseTestCase, ghi đè TestWatchman'S failed để chụp ảnh màn hình. Vấn đề là ở chỗ @After phương pháp làm sạch dữ liệu thử nghiệm đang được chạy trước TestWatchman'S failed phương pháp được gọi, vì vậy các ảnh chụp màn hình là tất cả các bước cuối cùng của việc dọn dẹp, không phải là thử nghiệm thất bại.

Nhìn vào nó một chút, có vẻ như TestWatchman'S apply phương pháp chỉ cần gọi Statementphương pháp đánh giá (phương pháp tiếp xúc duy nhất), gọi phương thức @After phương pháp, để lại TestWatchman (Hay bất cứ thứ gì khác Rule) không có cơ hội để chèn bất kỳ mã nào giữa việc thực hiện kiểm tra và của @After phương pháp, như xa như tôi có thể nói.

Tôi cũng đã thấy các phương pháp tạo tùy chỉnh Runner để thay đổi Statements được tạo để các phương thức được chú thích với tùy chỉnh @AfterFailure được chạy trước @After phương pháp (vì vậy ảnh chụp màn hình có thể được chụp trong một @AfterFailure phương pháp), nhưng điều này phụ thuộc vào trọng số BlockJUnit4ClassRunner'S withAfters phương pháp, không được chấp nhận và do trở thành riêng tư, theo tài liệuthay vào đó, đề xuất sử dụng Quy tắc.

Tôi đã tìm thấy một câu trả lời khác về SO về Vòng đời @Rule mà làm cho nó âm thanh như thế này chỉ đơn giản là có thể không được có thể trong JUnit 4.8, nhưng có thể có thể trong JUnit 4,10. Nếu đó là chính xác thì đủ công bằng, tôi chỉ muốn xác nhận rằng đầu tiên.

Bất kỳ suy nghĩ về một cách thanh lịch và tương lai bằng chứng trong đó tôi có thể đạt được những gì tôi muốn sẽ được nhiều đánh giá cao!


10
2017-12-19 16:17


gốc




Các câu trả lời:


Bạn đang ở trong phân tích của mình, @Befores và @Afters được thêm vào danh sách các câu lệnh trước bất kỳ Quy tắc nào. Các @Before được thực thi sau @Rule và @After được thực thi trước @Rule. Cách bạn khắc phục điều này phụ thuộc vào mức độ linh hoạt của bạn SeleniumBaseTestCaseWithCompany.

Cách dễ nhất là xóa @Before/@After phương pháp và thay thế chúng bằng một ExternalResource. Điều này có thể trông giống như sau:

public class BeforeAfterTest {
    @Rule public TestRule rule = new ExternalResource() {
        protected void before() throws Throwable { System.out.println("externalResource before"); }
        protected void after() { System.out.println("externalResource after"); }
    };

    @Test public void testHere() { System.out.println("testHere"); }
}

điều này cho:

externalResource before
testHere
externalResource after

Trường này có thể được đưa vào lớp cơ sở của bạn, vì vậy nó được thừa hưởng / ghi đè. Vấn đề của bạn khi đặt hàng giữa @Sau và các quy tắc của bạn sẽ biến mất, bởi vì bạn có thể đặt hàng các quy tắc của mình theo cách bạn thích, bằng cách sử dụng @RuleChain (trong 4.10, không phải 4.8).

Nếu bạn không thể thay đổi SeleniumBaseTestCaseWithCompany, sau đó bạn có thể mở rộng BlockJUnit4ClassRunnernhưng không ghi đè với bộ đệm, nhưng ghi đè BlockJUnit4ClassRunner # methodBlock (). Sau đó bạn có thể gọi super.methodBlock và sắp xếp lại các câu lệnh khi cần thiết [*].

[*] Bạn chỉ có thể sao chép mã và sắp xếp lại các dòng, nhưng withRules là riêng tư và do đó không thể gọi từ lớp con.


7
2017-12-20 22:11



Đúng, tôi nghĩ việc nâng cấp JUnit là con đường để đi - tôi không thể thấy một giải pháp đặc biệt thỏa đáng trong 4.8.2. Tôi đã có một TestWatcher được bảo vệ trên SeleniumBaseTestCase chụp ảnh màn hình và RuleChain với điều đó là quy tắc duy nhất. Sau đó trong SeleniumBaseTestCaseWithCompany Tôi có một ExternalResource để tạo / xóa công ty, và tôi đổ bóng RuleChain của lớp cha đặt hàng cả ảnh chụp màn hình và quy tắc tạo / xóa. Dường như làm việc độc đáo, cảm ơn. - Rowan
Chỉ cần một lưu ý. Trong 4.11, bạn sẽ có thể chỉ định @Rule trên một phương thức, vì vậy bạn có thể ghi đè phương thức đó thay vì che khuất một trường. Nhưng 4.11 vẫn chưa được phát hành. - Matthew Farwell
Ah, tốt để biết - che giấu biến là bit duy nhất tôi cảm thấy khó chịu về ... - Rowan