6 - 測試結果6.1 - 成功、失敗和斷言
如果一個測試沒有拋出任何異常就完成運行或者說拋出了期望的異常(參見@Test註解的expectedExceptions屬性文檔),就說,這個測試時成功的。
測試方法的組成常常包括拋出多個異常,或者包含各種各樣的斷言(使用Java "assert" 關鍵字)。一個 "assert" 失敗會觸發一個 AssertionErrorException,結果就是測試方法被標記為失敗(記住,如果你看不到斷言錯誤,要在加上 -ea 這個JVM參數)。
下面是個例子:
@Test
public void verifyLastName() {
assert "Beust".equals(m_lastName) : "Expected name Beust, for" + m_lastName;
}
TestNG 也包括 JUnit 的 Assert 類,允許你對複雜的對象執行斷言:
import static org.testng.AssertJUnit.*;
//...
@Test
public void verify() {
assertEquals("Beust", m_lastName);
}
注意,上述代碼使用了靜態匯入,以便能夠使用 assertEquals 方法,而無需加上它的類首碼。
6.2 - 日誌與結果
當運行SuiteRunner的時候會指定一個目錄,之後測試的結果都會儲存在一個在那個目錄中叫做 index.html 的檔案中。這個index檔案指向其他多個HTML和文字檔,被指向的檔案包含了整個測試的結果。你可以再 這裡 看到一個例子。
通過使用監聽器和報表器,可以很輕鬆的產生自己的TestNG報表:
- 監聽器 實現介面 org.testng.ITestListener ,並且會在測試開始、通過、失敗等時刻即時通知
- 報告器 實現介面 org.testng.IReporter ,並且當整個測試回合完畢之後才會通知。IReporter 接受一個對象列表,這些對象描述整個測試回合的情況
例如,如果你想要產生一個PDF報告,那麼就不需要即時通知,所以用 IReporter。如果需要寫一個即時報告,例如用在GUI上,還要在每次測試時(下面會有例子和解釋)有進度條或者文本報告顯示點 ("."),那麼 ITestListener 是你最好的選擇。
6.2.1 - 日誌監聽器
這裡是對每個傳遞進來的測試顯示"."的監聽器,如果測試失敗則顯示 "F" ,跳過則是"S":
public class DotTestListener extends TestListenerAdapter {
private int m_count = 0;
@Override
public void onTestFailure(ITestResult tr) {
log("F");
}
@Override
public void onTestSkipped(ITestResult tr) {
log("S");
}
@Override
public void onTestSuccess(ITestResult tr) {
log(".");
}
private void log(String string) {
System.out.print(string);
if (m_count++ % 40 == 0) {
System.out.println("");
}
}
}
上例中,我們選擇擴充 TestListenerAdapter ,它使用空方法實現了 ITestListener 。所以我不需要去重寫那些我不需要的方法。如果喜歡可以直接實現介面。
這裡是我使用這個新監聽器調用TestNG的例子:
java -classpath testng.jar;%CLASSPATH% org.testng.TestNG -listener org.testng.reporters.DotTestListener test/testng.xml
輸出是:
........................................
........................................
........................................
........................................
........................................
.........................
===============================================
TestNG JDK 1.5
Total tests run: 226, Failures: 0, Skips: 0
===============================================
注意,當你使用 -listener 的時候,TestNG 會自動的檢測你所使用的監聽器類型。
6.2.2 - 日誌報表
org.testng.IReporter 介面只有一個方法:
public void generateReport(List<ISuite> suites, String outputDirectory)
這個方法在 TestNG 中的所有測試都運行完畢之後被調用,這樣你可以方法這個方法的參數,並且通過它們獲得剛剛完成的測試的所有資訊。
6.2.3 - JUnit 報表
TestNG 包含了一個可以讓TestNG的結果和輸出的XML能夠被JUnitReport所使用的監聽器。這裡 有個例子,並且ant任務建立了這個報告:
<target name="reports">
<junitreport todir="test-report">
<fileset dir="test-output">
<include name="*/*.xml"/>
</fileset>
<report format="noframes" todir="test-report"/>
</junitreport>
</target>
注意: 由於JDK 1.5 和 JUnitReports 不相容性,導致了frame版本不能夠正常工作,所以你需要指定 "noframes" 使其能夠正常工作。
6.2.4 - 報表 API
如果你要在HTML報告中顯示日誌資訊,那麼就要用到類 org.testng.Reporter:
Reporter.log("M3 WAS CALLED");
6.2.5 - XML 報表
TestNG 提供一種XML報表器,使得能夠捕捉到只適用於TestNG而不適用與JUnit報表的那些特定的資訊。這在使用者的測試環境必須要是用TestNG特定資訊的XML,而JUnit又不能夠提供這些資訊的時候非常有用。下面就是這種報表器產生XML的一個例子:
<testng-results>
<suite name="Suite1">
<groups>
<group name="group1">
<method signature="com.test.TestOne.test2()" name="test2" class="com.test.TestOne"/>
<method signature="com.test.TestOne.test1()" name="test1" class="com.test.TestOne"/>
</group>
<group name="group2">
<method signature="com.test.TestOne.test2()" name="test2" class="com.test.TestOne"/>
</group>
</groups>
<test name="test1">
<class name="com.test.TestOne">
<test-method status="FAIL" signature="test1()" name="test1" duration-ms="0"
started-at="2007-05-28T12:14:37Z" description="someDescription2"
finished-at="2007-05-28T12:14:37Z">
<exception class="java.lang.AssertionError">
<short-stacktrace>java.lang.AssertionError
... Removed 22 stack frames
</short-stacktrace>
</exception>
</test-method>
<test-method status="PASS" signature="test2()" name="test2" duration-ms="0"
started-at="2007-05-28T12:14:37Z" description="someDescription1"
finished-at="2007-05-28T12:14:37Z">
</test-method>
<test-method status="PASS" signature="setUp()" name="setUp" is-config="true" duration-ms="15"
started-at="2007-05-28T12:14:37Z" finished-at="2007-05-28T12:14:37Z">
</test-method>
</class>
</test>
</suite>
</testng-results>
這個報表器是隨著預設監聽器一起諸如的,所以你預設的情況下就可以得到這種類型的輸出。這個監聽器提供了一些屬性,可以修改報告來滿足你的需要。下表包含了這些屬性,並做簡要說明:
| 屬性 |
說明 |
Default value |
| outputDirectory |
一個 String 指明了XML檔案要存放的目錄 |
TestNG 輸出目錄 |
| timestampFormat |
指定報表器產生日期欄位的格式 |
yyyy-MM-dd'T'HH:mm:ss'Z' |
| fileFragmentationLevel |
值為1,2或3的整數,指定了XML檔案的產生方式:1 - 在一個檔案裡面產生所有的結果 2 - 每套測試都單獨產生一個XML檔案,這些檔案被連結到一個主檔案 3 - 同2,不過添加了引用那些套測試的測試案例的XML檔案 |
1 |
| splitClassAndPackageNames |
boolean值,指明了對 <class> 元素的產生方式。例如,你在false的時候得到 <class class="com.test.MyTest"> ,在true的時候 <class class="MyTest" package="com.test"> 。 |
false |
| generateGroupsAttribute |
boolean值指定了對<test-method> 元素是否產生 groups 屬性。這個功能的目的是,對那些無需遍曆整個<group> 元素,且只含有一個測試方法的組來說,可以提供一種更直接的解析組的方式。 |
false |
| stackTraceOutputMethod |
指定在發生異常的時候產生異常,追蹤彈棧資訊的類型,有如下可選值:0 - 無彈棧資訊 (只有異常類和訊息). 1 - 尖端的彈棧資訊,從上到下只有幾行 2 - 帶有所有內部異常的完整的彈棧方式 3 - 短長兩種彈棧方式 |
2 |
| generateDependsOnMethods |
對於<test-method>元素,使用這個屬性來開啟/關閉 depends-on-methods 屬性。 |
true |
| generateDependsOnGroups |
對於<test-method>屬性開啟depends-on-groups 屬性。 |
true |
為了配置報表器,你可以在命令列下使用 -reporter 選項,或者在 Ant 任務中嵌入<reporter> 元素。對於每個情況,你都必須指明類org.testng.reporters.XMLReporter。但是要注意你不能夠配置內建的報表器,因為這個只使用預設配置。如果你的確需要XML報表,並且使用自訂配置,那麼你就不得不手工完成。可以通過自己添加一兩個方法,並且禁用預設監聽器達到目的。
返回到 我的個人首頁。
或者看看我的其他項目:
- EJBGen: EJB 標籤產生器
- TestNG: 使用註解的測試架構,測試組和方法參數
- Doclipse: JavaDoc 標籤的 Eclipse 外掛程式
- J15: Eclipse 外掛程式,協助你遷移代碼到新的 JDK 1.5
- SGen: 使用外掛程式體系的 XDoclet 替換器
- Canvas: 基於 Groovy 語言的模板產生器