Sự khác biệt giữa thất bại và lỗi trong JUnit là gì?


93

Tôi đang chạy các bài kiểm tra JUnit trên một cơ sở mã lớn và tôi đã nhận ra rằng đôi khi tôi gặp "Lỗi" trong khi những lần khác tôi nhận được "Lỗi". Có gì khác biệt?

Câu trả lời:


116

Ok, tôi vừa nhận thấy một mẫu và nghĩ rằng tôi đã tìm ra nó (hãy sửa cho tôi nếu tôi sai). Đối với tôi, dường như thất bại là khi các trường hợp thử nghiệm của bạn không thành công - tức là các khẳng định của bạn không chính xác. Lỗi là lỗi không mong muốn xảy ra trong khi cố gắng thực sự chạy thử nghiệm - ngoại lệ, v.v.


5
Mặc dù nếu bất kỳ thứ gì mở rộng java.lang.AssertionErrorđược ném ra, nó sẽ được hiển thị là lỗi kiểm tra thay vì lỗi kiểm tra. Bạn nên cân nhắc việc chấp nhận câu trả lời của chính mình vì nó đúng.
ponzao

Vâng, đó chính xác là sự khác biệt. Và từ góc độ thực dụng thì không có "sự khác biệt" - ở chỗ nếu bạn gặp lỗi hoặc thất bại, thì bạn cần phải sửa chữa nó. Vì vậy, có thể là một sai lầm khi đếm "lỗi" và "lỗi" riêng biệt trong JUnit. JUnit 4 kết hợp cả hai (như được giải thích trong câu trả lời bên dưới).
Jeff Grigg

Và nếu ngoại lệ được mong đợi, bạn nên chú thích @Testvới expected = SomeException.class.
Downhillski

@JeffGrigg có một sự khác biệt thực dụng. Nếu một hành vi đang được dựa vào trong nhiều trường hợp thử nghiệm, tôi vẫn có thể chỉ viết một trường hợp thử nghiệm xác nhận hành vi đó, trong khi ném các ngoại lệ thời gian chạy không suy nghĩ, có khả năng xảy ra trong tất cả các trường hợp còn lại. Điều này nói lên rằng phần còn lại của các trường hợp thử nghiệm đang thử nghiệm thứ gì đó khác mặc dù chúng vẫn phụ thuộc vào hành vi cụ thể đó để chạy. Khi hành vi đó bị hỏng, chỉ có một trường hợp thử nghiệm sẽ báo lỗi trong khi phần còn lại báo lỗi và từ đó tôi có thể thấy rằng tôi có chính xác một lỗi cần sửa mặc dù nhiều trường hợp thử nghiệm không vượt qua.
RonJRH 19/03/18

org.junit.Assert.assertEquals () nếu không thành công được coi là LỖI bởi báo cáo HTML JUnit4. Điều này mâu thuẫn với tuyên bố của bạn (mà tôi đã biết đến bây giờ). Bạn có thể vui lòng đặt thêm ánh sáng vào điều này?
Krishnom

15

Nếu thử nghiệm của bạn đưa ra một ngoại lệ không được giải thích thông qua khung công tác Assertion trong Junit, nó sẽ được báo cáo là lỗi. Ví dụ, một NullPointer hoặc một ngoại lệ ClassNotFound sẽ báo lỗi:

String s = null;
s.trim();

hoặc là,

try {

    // your code
} catch(Exception e) {
    // log the exception
    throw new MyException(e);
}

Có nói rằng, sau đây sẽ báo cáo lỗi:

Assert.fail("Failure here");

hoặc là,

Assert.assertEquals(1, 2);

hoặc thậm chí:

throw new AssertionException(e);

Nó phụ thuộc vào phiên bản Junit bạn đang sử dụng. Junit 4- sẽ phân biệt giữa một lỗi và một lỗi, nhưng Junit 4 đơn giản hóa nó chỉ là những thất bại.

Liên kết sau cung cấp nhiều đầu vào thú vị hơn:

http://www.devx.com/Java/Article/31983/1763/page/2


Điều này không chính xác. Sự phân biệt giữa lỗi thử nghiệm và lỗi thử nghiệm không có trong JUnit 4. Tôi vừa thử nghiệm nó. Bài báo được liên kết đã gây hiểu lầm. Nó nói rằng "JUnit 4 làm cho nó đơn giản hơn bằng cách chỉ sử dụng các lỗi" nhưng cần nhấn mạnh rằng JUnit 4 biến java.lang.AssertionError thành các lỗi thử nghiệm để bạn không phải sử dụng junit.framework.AssertionFailedError. Lợi ích là bạn có thể bắt đầu viết các xác nhận thử nghiệm trong mã sản xuất mà không cần dự án liên kết với JUnit. Sự phân biệt giữa lỗi thử nghiệm và lỗi thử nghiệm cũng vô cùng hữu ích và sẽ là một bước lùi nếu bị loại bỏ.
RonJRH

RonJRH, bạn có thể thấy lỗi trong báo cáo tháng 6 mặc định của mình không?
Neel

Có Neel. Tôi vừa thử nó. Không chắc chắn chính xác nguyên tắc liên kết hình ảnh ở đây nhưng điều này cho thấy kết quả kiểm tra của tôi: imagebucket.net/abpxucddkvn1/Capture.PNG
RonJRH

6

Từ "Kiểm tra đơn vị thực dụng trong Java 8 với JUnit":

Các xác nhận (hoặc xác nhận) trong JUnit là các lệnh gọi phương thức tĩnh mà bạn đưa vào các bài kiểm tra của mình. Mỗi khẳng định là một cơ hội để xác minh rằng một số điều kiện là đúng. Nếu một điều kiện đã xác nhận không đúng, quá trình kiểm tra sẽ dừng lại ngay tại đó và JUnit báo cáo lỗi kiểm tra.

(Cũng có thể khi JUnit chạy thử nghiệm của bạn, một ngoại lệ được đưa ra và không được bắt. Trong trường hợp này, JUnit báo cáo lỗi thử nghiệm.)


5

Kiểm tra dưới đây giải thích sự khác biệt giữa Lỗi kiểm tra và Lỗi kiểm tra .

Tôi đã nhận xét dòng ném lỗi kiểm tra và lỗi kiểm tra.

    @Test
    public void testErrorVsTestFailure() {

        final String sampleString = null;

        assertEquals('j', sampleString.charAt(0) );
        //above line throws test error as you are trying to access charAt() method on null reference

        assertEquals(sampleString, "jacob");
        //above line throws Test failure as the actual value-a null , is not equal to expected value-string "jacob"
        }

Vì vậy, Junit hiển thị lỗi kiểm tra bất cứ khi nào bạn gặp một ngoại lệ và kiểm tra thất bại khi giá trị kết quả mong đợi của bạn không khớp với giá trị thực của bạn


2

Lớp nguồn: JUnitReportReporter.java

public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String defaultOutputDirectory) {
//......

            for (ITestResult tr : (Set) entry.getValue()) {
                TestTag testTag = new TestTag();

                boolean isSuccess = tr.getStatus() == 1;
                if (!(isSuccess)) {
                    if (tr.getThrowable() instanceof AssertionError)
                        ++errors;
                    else {
                        ++failures;
                    }
                }
}

Như bạn có thể thấy dòng dưới đây trong phương pháp trên

tr.getThrowable () instanceof AssertionError

số lỗi được tăng lên khi nó là trường hợp của AssertionError nếu không (bất kỳ Throwable nào) được tính là lỗi.


1

Bạn nói đúng rằng các lỗi đến từ các AssertionErrors do các phương thức xác nhận JUnit ném ra, hoặc bằng cách ném AssertionError, hoặc do ném một ngoại lệ mà bạn đã khai báo trong @Testchú thích của mình và các lỗi đến từ các Ngoại lệ không mong muốn khác. Nhưng có một điểm khác biệt quan trọng giữa chúng:

Lỗi có nghĩa là thử nghiệm của bạn đã chạy chính xác và đã xác định được lỗi trong mã của bạn.

Một lỗi có thể có nghĩa là một lỗi trong mã của bạn, nhưng một lỗi mà bạn thậm chí không thử nghiệm. Nó cũng có thể có nghĩa là lỗi nằm trong chính thử nghiệm.

Tóm lại, một thất bại có nghĩa là bạn cần phải viết lại đoạn mã đang được kiểm tra. Một lỗi có nghĩa là nó có thể là bài kiểm tra đơn vị mà bạn cần phải viết lại. Nó có thể có nghĩa là điều này ngay cả khi lỗi xảy ra trong mã của bạn, chẳng hạn như a NullPointerException, bởi vì bạn đã phát hiện ra một lỗ hổng mà bạn thậm chí không kiểm tra, vì vậy có thể là khôn ngoan khi kiểm tra điều đó.


0

Trớ trêu thay, junit và các khuôn khổ liên quan đến thử nghiệm khác (testng, hamcrest) cung cấp các hoạt động xác nhận để xác minh điều kiện và nếu nó không thành công thì "chui" một java.lang.AssertionError đang được ném ra, btw mở rộng java.lang.Error.

Nhưng nó không có cách nào mâu thuẫn với các câu trả lời ở trên, tất nhiên là hoàn toàn hợp lệ. Vì vậy, để đánh dấu luồng thử nghiệm cụ thể là thất bại, người ta có thể ném AssertionError, tuy nhiên tôi không chắc nó thực sự được ghi lại trong các sách hướng dẫn tương ứng, vì sử dụng API fail () chuyên dụng sẽ thích hợp hơn. Các loại Throwable khác sẽ được coi là lỗi, không phải lỗi.


0

Về cơ bản, thất bại đề cập đến các xác nhận chưa được thực hiện trong khi lỗi là do thực hiện kiểm tra bất thường . và tôi nghĩ rằng mỗi IDE có các biểu tượng tượng trưng với các màu khác nhau cho các bài kiểm tra đạt , không đạtcó lỗi .

Để biết thêm thông tin, hãy kiểm tra điều này .

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.