簡體   English   中英

JUnit 中的失敗和錯誤有什么區別?

[英]What's the difference between failure and error in JUnit?

我正在大型代碼庫上運行 JUnit 測試,並且我一直意識到有時會出現“錯誤”,而有時會出現“失敗”。 有什么不同?

似乎失敗是當您的測試用例失敗時 - 即您的斷言不正確。 錯誤是在嘗試實際運行測試時發生的意外錯誤 - 異常等。

如果您的測試拋出一個異常,而該異常並未通過 Junit 中的斷言框架冒泡,則會被報告為錯誤。 例如,一個 NullPointer,或者一個 ClassNotFound 異常會報錯:

String s = null;
s.trim();

或者,

try {

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

話雖如此,以下將報告失敗:

Assert.fail("Failure here");

或者,

Assert.assertEquals(1, 2);

甚至:

throw new AssertionException(e);

這取決於您使用的 Junit 版本。 Junit 4- 將區分失敗和錯誤,但 Junit 4 僅將其簡化為失敗。

以下鏈接提供了更多有趣的輸入:

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

來自“使用 JUnit 在 Java 8 中進行實用單元測試”:

JUnit 中的斷言(或斷言)是您放入測試中的靜態方法調用。 每個斷言都是驗證某些條件成立的機會。 如果斷言的條件不成立,則測試會立即停止,並且 JUnit 會報告測試失敗。

(也有可能在 JUnit 運行您的測試時拋出異常而未捕獲。在這種情況下,JUnit 報告測試錯誤。)

下面的測試解釋了Test Error 與 Test failure之間的區別。

我已經評論了引發測試錯誤和測試失敗的行。

    @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"
        }

因此,每當您遇到異常時,Junit 都會顯示測試錯誤,並在您的預期結果值與您的實際值不匹配時顯示測試失敗

源類: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;
                    }
                }
}

正如你在上面的方法中看到的下面一行

tr.getThrowable() 實例斷言錯誤

當它是 AssertionError 的實例時,錯誤計數增加,否則(任何 Throwable)被計為失敗。

你是對的,失敗來自 JUnit 斷言方法拋出的 AssertionErrors,或者拋出 AssertionError,或者拋出你在@Test注釋中聲明的異常,而錯誤來自其他意外異常。 但它們之間有一個重要的區別:

失敗意味着您的測試運行正確,並確定了代碼中的缺陷。

錯誤可能意味着您的代碼中存在錯誤,但您甚至沒有對其進行測試。 這也可能意味着錯誤在測試本身中。

簡而言之,失敗意味着您需要重寫正在測試的代碼。 錯誤意味着它可能是您需要重寫的單元測試。 這可能意味着即使失敗在您的代碼中,例如NullPointerException ,因為您檢測到了一個您甚至沒有測試過的缺陷,因此測試它可能是明智的。

具有諷刺意味的是,junit 和其他與測試相關的框架(testng、hamcrest)提供了斷言操作來驗證條件,如果它失敗,則會在“幕后”拋出一個 java.lang.AssertionError,順便說一下,它擴展了 java.lang.Error。

但這與上面的答案並不矛盾,當然這些答案是完全有效的。 因此,為了將特定的測試流程標記為失敗,可以拋出 AssertionError,但是我不確定它是否真的記錄在相應的手冊中,因為使用專用的 fail() API 更合適。 其他類型的 Throwable 將被視為錯誤,而不是失敗。

基本上,失敗是指未實現的斷言,錯誤是由於異常的測試執行 而且我認為每個 IDE 都有不同顏色的符號圖標,用於通過失敗錯誤測試。

有關更多信息,請查看

測試方法投擲 測試結果
java.lang.AssertionError 失敗
org.junit.AssumptionViolatedException 跳過
預期的例外 好的
任何其他例外 錯誤
沒有例外 好的
測試方法之外的異常 錯誤
  • assert 方法只是拋出 AssertionExceptions。
  • @Test 注釋中聲明了預期的異常。
  • 測試方法之外的代碼可以用@Before、@BeforeClass 等注釋。
  • IDE 中的計數報告計數測試(測試方法),而不是斷言,因為第一個失敗的斷言會終止測試。
  • 根據經驗,如果測試方法異常終止(不是使用 return 語句),則不成功,反之亦然。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM