TestNG測試結果報告

TestNG默認情況下,會生產兩種類型的測試報告HTML的和XML的。 測試報告位于 "test-output" 目錄下。

TestNG的還允許用戶自己寫的報告凭戴,并用它使用TestNG。還有一個選項來寫你自己的記錄器炕矮,在運行時通過TestNG的通知

  • 監(jiān)聽器: 為了實現(xiàn)一個監(jiān)聽類么夫,實現(xiàn)一個 ITestListener接口或者其它接口者冤。這些類在運行時通知了TestNG測試開始時,結束后档痪,失敗涉枫,跳過或傳遞。

  • 記錄器: 為了實現(xiàn)一個報表類腐螟,實現(xiàn)一個org.testng.IReporter接口愿汰。這些類一整套運行結束時調用。調用時乐纸,該對象包含整個測試運行的信息傳遞到這個類衬廷。

IAnnotationTransformer

IAnnotationTransformer 監(jiān)聽器只能用來修改 @Test 注釋

IAnnotationTransformer 要求實現(xiàn) transform 方法,其方法簽名如下:

void transform(ITest annotation, Class testClass, Constructor testConstructor, Method testMethod);

annotation 代表就是為 testMethod 定義的 @Test 注釋
調用其方法可以更改 @Test 注釋屬性
例如汽绢,下面的代碼在運行時將屬性 enabled 改為 false 從而禁用了當前的測試方法

annotation.setEnabled(false);

IAnnotationTransformer2

IAnnotationTransformer2 監(jiān)聽器修改其他 TestNG 的注釋(比如吗跋,@DataProvider, @Factory )

該監(jiān)聽器要求實現(xiàn)的方法:

void transform(IConfigurationAnnotation annotation, java.lang.Class testClass, 
 java.lang.reflect.Constructor testConstructor,
 java.lang.reflect.Method testMethod)
void transform(IDataProviderAnnotation annotation, java.lang.reflect.Method method)
void transform(IFactoryAnnotation annotation, java.lang.reflect.Method method)

IHookable

IHookable 監(jiān)聽器提供了類似與面向q切面編程(AOP)中的 Around Advice 的功能
它在測試方法執(zhí)行前后提供了切入點,從而使用戶在測試方法運行前后注入特定的功能

例如: 用戶可以在當前測試方法運行前加入特定的驗證邏輯以決定測試方法是否運行或者跳過宁昭,甚至覆蓋測試方法的邏輯

IHookable 監(jiān)聽器要求實現(xiàn)的方法簽名

void run(IHookCallBack callBack, ITestResult testResult)

運行原始測試方法邏輯跌宛,需要調用 runTestMethod 方法

callBack.runTestMethod(testResult);

用JAAS(Java驗證和授權API)一個例子:

public class MyHook implements IHookable {
  public void run(final IHookCallBack icb, ITestResult testResult) {
    // Preferably initialized in a @Configuration method
    mySubject = authenticateWithJAAs();

    Subject.doAs(mySubject, new PrivilegedExceptionAction() {
      public Object run() {
        icb.callback(testResult);
      }
    };
  }
}

IInvokedMethodListener

與 IHookable 類似,IInvokedMethodListener 提供了類似與面向方面編程(AOP)中的 Before Advice 和 After Advice 的功能

IInvokedMethodListener監(jiān)聽器允許用戶在當前測試方法被執(zhí)行前和執(zhí)行后注入特定的邏輯

比如: 可以加入日志方法积仗,無論何時TestNG即將調用一個測試(被@Test注解的)或者配置(任何使用@Beforeor@After注解標注的方法)秩冈,監(jiān)聽器 IInvokedMethodListener都可以讓你得到通知

public interface IInvokedMethodListener extends ITestNGListener {
  void beforeInvocation(IInvokedMethod method, ITestResult testResult);
  void afterInvocation(IInvokedMethod method, ITestResult testResult);
}

IMethodInterceptor

TestNG 啟動之后,第一件要做的事情是將所有的測試方法分成兩類:
一類是順序運行的測試方法斥扛;
一類是沒有特定運行順序的測試方法

第一類
TestNG 通過 @Test注釋中的 dependsOnGroupsdependsOnMethods使用戶能夠定義測試方法之間的依賴關系。這種依賴關系也就決定這些測試方法必須按著怎樣的順序運行

第二類
除了第一類有依賴關系的剩下的全部歸于第二類丹锹,盡管默認 TestNG 會嘗試用類名將它們分組稀颁,但是理論上,它們的運行順序是隨機的楣黍,甚至每次運行的順序都可能不同

IMethodInterceptor 監(jiān)聽器使用戶擁有對第二類測試方法更大的控制權

實現(xiàn)的方法:

public interface IMethodInterceptor {

  List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context);

}

intercept 方法在所有測試方法被分類后以及所有測試方法被執(zhí)行前被調用匾灶。所有的測試方法將按照 intercept 返回值列表中的順序被執(zhí)行。因此租漂,用戶在 intercept 方法中可以對列表進行修改阶女,比如重新排序,甚至增加或者減少測試方法哩治。

intercept方法也要返回一個IMethodInstance列表秃踩,它可能是下面情況之一:

  • 內容與參數(shù)中接收的一致,但是順序不同
  • 一組IMethodInstance對象
  • 更大的一組IMethodInstance對象

定義了攔截器业筏,就把它傳遞個TestNG憔杨,用下面的方式:

java -classpath "testng-jdk15.jar:test/build" org.testng.TestNG -listener test.methodinterceptors.NullMethodInterceptor
   -testclass test.methodinterceptors.FooTest

例如,下面是個方法攔截器會重新給方法排序蒜胖,一遍“fast”組中的方法總是先執(zhí)行:

public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
  List<IMethodInstance> result = new ArrayList<IMethodInstance>();
  for (IMethodInstance m : methods) {
    Test test = m.getMethod().getConstructorOrMethod().getAnnotation(Test.class);
    Set<String> groups = new HashSet<String>();
    for (String group : test.groups()) {
      groups.add(group);
    }
    if (groups.contains("fast")) {
      result.add(0, m);
    }
    else {
      result.add(m);
    }
  }
  return result;
}

ISuiteListener

ISuiteListener 類似于 IInvokedMethodListener消别,區(qū)別是 IInvokedMethodListener 針對的是測試方法抛蚤,而 ISuiteListener 針對的是測試套件
ISuiteListener 監(jiān)聽器使用戶有機會在測試套件開始執(zhí)行以及執(zhí)行結束之后嵌入自己的邏輯。
實現(xiàn)的方法 :

void onFinish(ISuite suite) 
void onStart(ISuite suite)

ITestListener

ITestListener 監(jiān)聽器要求實現(xiàn)的方法中包含如下三個

void onTestFailure(ITestResult result) 
void onTestSkipped(ITestResult result) 
void onTestSuccess(ITestResult result)

TestListenerAdapter 已經實現(xiàn) ITestListener寻狂,并且提供了一些有用的方法岁经,比如分別獲取所有成功失敗跳過三種測試結果的測試方法的方法,并且 ITestListner 中有很多方法而 TestListenerAdapter 已給出了默認實現(xiàn)

擴展TestListenerAdapter蛇券,它使用空方法實現(xiàn)了ITestListener

對每個傳遞進來的測試顯示"."的監(jiān)聽器缀壤,如果測試失敗則顯示 "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("");
    }
  }
}

IReporter

TestNG 提供了默認的測試報表

IReporter 監(jiān)聽器接口只有一個方法:

public void generateReport(List<ISuite> suites, String outputDirectory)

該方法在所有測試方法執(zhí)行結束后被調用,outputDirectory 是默認的測試報表生成路徑怀读,當然可以指定其他路徑生成報表

JUnitReport

TestNG 包含了一個可以讓TestNG的結果和輸出的XML能夠被JUnitReport所使用的監(jiān)聽器诉位。
例子: 并且ant任務創(chuàng)建了這個報告:

<target name="reports">
  <junitreport todir="test-report">
    <fileset dir="test-output">
      <include name="*/*.xml"/>
    </fileset>

    <report format="noframes"  todir="test-report"/>
  </junitreport>
</target>
image.png

監(jiān)聽器的使用方法

在 testng.xml 中使用 TestNG 監(jiān)聽器

TestNG 通過 testng.xml 配置所有的測試方法。
Testng.xml 提供了 listeners 和 listener 標簽用來添加自定義的監(jiān)聽器菜枷。

<suite name="TestNGSample">
    <listeners>
        <listener class-name="listeners.OSFilter" />
        <listener class-name="listeners.ProgressTracker" />
    </listeners>
    <test name="ProgressTracker Demo">
        <classes>
            <class name="tests.SampleTest" />
        </classes>
    </test>
</suite>

在源代碼中使用 TestNG 監(jiān)聽器

通過 @Listeners 注釋苍糠,可以直接在 Java 源代碼中添加 TestNG 監(jiān)聽器。

@Listeners({ OSFilter.class, ProgressTracker.class })
public class SampleTest {
 
    @Test(groups = { OSNames.OS_LINUX })
    public void test1() {
        sleep(5000);
        System.out.println(">>>test1");
    }

注意:

  • 在 @Listeners 中添加監(jiān)聽器跟在 testng.xml 添加監(jiān)聽器一樣啤誊,將被應用到整個測試套件中的測試方法岳瞭。如果需要控制監(jiān)聽器的應用范圍(比如添加的監(jiān)聽器僅使用于某些測試測試類或者某些測試方法),則必須在監(jiān)聽器類中編寫適當?shù)呐袛噙壿嫛?/p>

  • 在 @Listeners 中添加監(jiān)聽器跟在 testng.xml 添加監(jiān)聽器的不同之處在于蚊锹,它不能添加 IAnnotationTransformer 和 IAnnotationTransformer2 監(jiān)聽器瞳筏。原因是因為這兩種監(jiān)聽器必須在更早的階段添加到 TestNG 中才能實施修改注釋的操作,所以它們只能在 testng.xml 添加牡昆。

  • TestNG 對添加的監(jiān)聽器不做去重判斷姚炕。因此,如果 testng.xml 和源代碼中添加了相同的監(jiān)聽器丢烘,該監(jiān)聽器的方法會被調用兩次柱宦。不要通過多種方式重復添加監(jiān)聽器。

通過 ServiceLoader 使用 TestNG 監(jiān)聽器

JDK中提供了一個非常優(yōu)雅的機制播瞳,通過ServiceLoader類的借口路徑來實現(xiàn)監(jiān)聽掸刊。

通過 ServiceLoader 的方式使用 TestNG 監(jiān)聽器,簡單來說赢乓,就是創(chuàng)建一個 jar 文件忧侧,里面包含 TestNG 監(jiān)聽器的實現(xiàn)類已經 ServiceLoader 需要的配置信息,并在運行 TestNG 時把該 jar 文件加載到類路徑中

這樣做的好處是:

  • 可以輕松地與其他人分享 TestNG 監(jiān)聽器牌芋。
  • 當有很多 testng.xml 文件時蚓炬,不需要重復把監(jiān)聽器添加到每個文件中。

具體例子
先創(chuàng)建一個偵聽器(所有的TetstNG監(jiān)聽都應該響應):

package test.tmp;

public class TmpSuiteListener implements ISuiteListener {
  @Override
  public void onFinish(ISuite suite) {
    System.out.println("Finishing");
  }

  @Override
  public void onStart(ISuite suite) {
    System.out.println("Starting");
  }
}

編譯這個文件躺屁,然后在當前文件位置創(chuàng)建一個文件META-INF/services/org.testng.ITestNGListener
這個名字就是要實現(xiàn)的接口

目錄結構试吁,只有僅僅兩個文件:

$ tree
|____META-INF
| |____services
| | |____org.testng.ITestNGListener
|____test
| |____tmp
| | |____TmpSuiteListener.class

在這個目錄創(chuàng)建一個jar文件:

jar cvf ../sl.jar .

將jar文件放入調用TestNG的類路徑下:

java -classpath sl.jar:testng.jar org.testng.TestNG testng-single.yaml  

報表 API

要在HTML報告中顯示日志信息,那么就要用到類 org.testng.Reporter:Reporter.log("M3 WAS CALLED");

XML 報表

TestNG 提供一種XML報表器,使得能夠捕捉到只適用于TestNG而不適用與JUnit報表的那些特定的信息熄捍。
這在用戶的測試環(huán)境必須要是用TestNG特定信息的XML烛恤,而JUnit又不能夠提供這些信息的時候非常有用。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末余耽,一起剝皮案震驚了整個濱河市缚柏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碟贾,老刑警劉巖币喧,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異袱耽,居然都是意外死亡杀餐,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門朱巨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來史翘,“玉大人,你說我怎么就攤上這事冀续∏矸恚” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵洪唐,是天一觀的道長钻蹬。 經常有香客問我,道長凭需,這世上最難降的妖魔是什么问欠? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮粒蜈,結果婚禮上顺献,老公的妹妹穿的比我還像新娘。我一直安慰自己薪伏,他們只是感情好其馏,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布锋叨。 她就那樣靜靜地躺著焊切,像睡著了一般掘宪。 火紅的嫁衣襯著肌膚如雪筋现。 梳的紋絲不亂的頭發(fā)上咐低,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天盐须,我揣著相機與錄音反症,去河邊找鬼蚂斤。 笑死存捺,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播捌治,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼岗钩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了肖油?” 一聲冷哼從身側響起兼吓,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎森枪,沒想到半個月后视搏,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡县袱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年浑娜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片式散。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡筋遭,死狀恐怖,靈堂內的尸體忽然破棺而出杂数,到底是詐尸還是另有隱情宛畦,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布揍移,位于F島的核電站次和,受9級特大地震影響,放射性物質發(fā)生泄漏那伐。R本人自食惡果不足惜踏施,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望罕邀。 院中可真熱鬧畅形,春花似錦、人聲如沸诉探。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肾胯。三九已至竖席,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間敬肚,已是汗流浹背毕荐。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留艳馒,地道東北人憎亚。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親第美。 傳聞我的和親對象是個殘疾皇子蝶锋,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容