TestNG中的監聽
1.使用監聽的目的:
Testng雖然提供了不少強大的功能和靈活的選項,但不能解決所有的問題,使用監聽器就是用來定製額外的功能以滿足我們的需求的;
2.監聽器具體實現:
監聽器實際上是一些預定義的java接口,用戶創建這些接口的實現類(即implements某監聽接口,並實現裏面的方法),並加入到testng中,testng便會在運行的不同時刻調用這些類中你自定義實現的接口方法,從而實現定製額外的功能;
3.監聽器的種類:
3.1 IAnnotationTransformer(修改@Test註釋屬性)
大多數情況下,在運行時我們不需要改動源代碼中定義的註釋,但有時需要這樣做。這時,我們就需要使用 IAnnotationTransformer 監聽器。IAnnotationTransformer 只能用來修改 @Test 註釋,如果需要修改其他 TestNG 的註釋(比如,@DataProvider, @Factory 以及 @Configuration),需要使用 IAnnotationTransformer2 監聽器。IAnnotationTransformer 要求實現 transform 方法,其方法簽名如下:
void transform(ITest annotation, Class testClass, Constructor testConstructor, Method testMethod);
annotation 代表就是爲 testMethod 定義的 @Test 註釋。調用其方法可以更改 @Test 註釋屬性。例如,下面的代碼在運行時將屬性 enabled 改爲 false 從而禁用了當前的測試方法。
annotation.setEnabled(false);
3.2 IAnnotationTransformer2(修改其他註解的註釋屬性)
用來修改除 @Test 以外的 TestNG 的註釋,例如:@DataProvider 以及 @Factory 等註解的註釋屬性能夠通過該監聽器修改;
void transform(IDataProviderAnnotation annotation, java.lang.reflect.Method method)
void transform(IFactoryAnnotation annotation, java.lang.reflect.Method method)
3.3 IHookable(類似與面向切面編程(AOP)中的 Around Advice 的功能),可忽略
3.4 IInvokedMethodListener(類似與面向切面編程(AOP)中的 Before Advice 和 After Advice 的功能),可忽略
3.5 IMethodInterceptor控制列表執行循序)
TestNG 啓動之後,所有的測試方法分成兩類:
一類是順序運行的測試方法;(dependsOnGroups 和 dependsOnMethods)
一類是沒有特定運行順序的測試方法。(運行順序是隨機,每次運行的順序都可能不同)
IMethodInterceptor 監聽器用來對第二類測試有更大的控制權,對列表重新排序,甚至增加或者減少測試方法;
java.util.List<IMethodInstance> intercept(java.util.List<IMethodInstance> methods, ITestContext context)
實現的intercept 方法會在所有測試方法被分類後以及所有測試方法被執行前被調用。所有的測試方法將按照 intercept 返回值列表中的順序被執行。
3.6 IReporter(自定義測試報表)
IReporter 監聽器用來自定義測試報表;
void generateReport(java.util.List<XmlSuite> xmlSuites, java.util.List<ISuite> suites, java.lang.String outputDirectory)
generateReport方法會在所有測試方法執行結束後被調用,通過遍歷 xmlSuites 和 suites 能夠獲取所有測試方法的信息以及測試結果。outputDirectory 是默認的測試報表生成路徑,當然你可以指定其他路徑生成報表
3.7 ISuiteListener(suite的AOP),可忽略;
3.8 ITestListener(簡便自定義測試方法執行後的後續行爲)
用來在測試方法執行成功、失敗或者跳過時指定不同後續行爲;
IInvokedMethodListener 也可以實現,但ITestListener更簡便;
void onTestFailure(ITestResult result)
void onTestSkipped(ITestResult result)
void onTestSuccess(ITestResult result)
另外:TestListenerAdapter 已經實現 ITestListener,並且提供了一些有用的方法,比如分別獲取所有成功失敗跳過三種測試結果的測試方法的方法,並且 ITestListner 中有很多方法而 TestListenerAdapter 已給出了默認實現。因此,繼承 TestListenerAdapter 後,便只需關注需要修改的方法。
4.監聽器使用:
4.1 在 testng.xml 中使用 TestNG 監聽器
<listeners>
<listener class-name="api.listeners.AutoTestListener"></listener>
<listener class-name="api.listeners.RetryListener"></listener>
<listener class-name="api.listeners.ExtentTestNGIReporterListener"/>
</listeners>
4.2在源代碼中使用 TestNG 監聽器
通過 @Listeners 註釋,可以直接在 Java 源代碼中添加 TestNG 監聽器
@Listeners(RetryListener.class)
public class SampleTest {
@Test()
public void test1() {
sleep(6000);
System.out.println("test1");
}
*注意:
1)在 @Listeners 中添加監聽器跟在 testng.xml 添加監聽器一樣,將被應用到整個測試套件中的測試方法。如果需要控制監聽器的應用範圍(比如添加的監聽器僅使用於某些測試測試類或者某些測試方法),則必須在監聽器類中編寫適當的判斷邏輯。
2)在 @Listeners 中添加監聽器跟在 testng.xml 添加監聽器的不同之處在於,它不能添加 IAnnotationTransformer 和 IAnnotationTransformer2 監聽器。原因是因爲這兩種監聽器必須在更早的階段添加到 TestNG 中才能實施修改註釋的操作,所以它們只能在 testng.xml 添加。
3)TestNG 對添加的監聽器不做去重判斷。因此,如果 testng.xml 和源代碼中添加了相同的監聽器,該監聽器的方法會被調用兩次。有關這一點,大家可以通過運行本文附帶的示例代碼包中 testng.xml 驗證。因此,切記,不要通過多種方式重複添加監聽器。
5.監聽舉例:
5.1 TestCaseListener實現ITestListener接口,並重寫onTestStart、onTestSuccess和onTestFailure方法;
package com.testngdemo;
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.annotations.*;
public class TestCaseListener implements ITestListener {
@Override
public void onFinish(ITestContext arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStart(ITestContext arg0) {
// TODO Auto-generated method stub
}
@Override
public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) {
// TODO Auto-generated method stub
}
@Override
public void onTestFailure(ITestResult iTestResult) { //重寫onTestFailure方法
System.out.println("用例執行失敗,啓動截圖:");
System.out.println(iTestResult.toString());
}
@Override
public void onTestSkipped(ITestResult arg0) {
// TODO Auto-generated method stub
}
@Override
public void onTestStart(ITestResult iTestResult) { //重寫onTestStart方法
System.out.println("用例啓動:");
}
@Override
public void onTestSuccess(ITestResult iTestResult) { //重寫onTestSuccess方法
System.out.println("用例執行成功:");
}
}
5.2 使用TestRetry類進行測試(使用@Listeners在代碼中添加監聽)
package com.testngdemo;
import org.testng.Assert;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners(TestCaseListener.class)
public class TestRetry {
@Test(priority = 1)
public void printMessage() {
Assert.assertEquals(11, 11);
}
@Test(priority = 2)
public void pintErrorMessage() {
Assert.assertEquals(11, 12,"斷言錯誤");
}
}
5.3也可使用xml的形式添加監聽,如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1">
<listeners>
<listener class-name="com.testngdemo.TestCaseListener"/>
</listeners>
<test name="test1">
<classes>
<class name="com.testngdemo.TestRetry"/>
</classes>
</test>
</suite>
5.4運行結果如下: