在实际应用中,我们常遇到的两个情况:
1、一个case有N个断言,我想执行全部断言后,最后给出testcase的执行结果,而不是在执行一个断言错误后,就终止该条testcase,判定失败。
2、在半夜执行某个testcase失败后,害怕testcase失败是因为网络等原因,期望在失败后重新再重试下。
今天介绍一下解决第一种场景的2种办法。
①重新创建Assertion类,重写断言方法
/*** String对比* @param actual* @param expected*/public static void verifyEquals(Object actual, Object expected){try{Assert.assertEquals(actual, expected);}catch(Error e){errors.add(e);flag = false;}}/*** String对比+msg* @param actual* @param expected* @param message*/public static void verifyEquals(Object actual, Object expected, String message){try{Assert.assertEquals(actual, expected, message);}catch(Error e){errors.add(e);flag = false;}}
②创建新的监听类
public class AssertionListener extends TestListenerAdapter {@Overridepublic void onTestStart(ITestResult result) {Assertion.flag = true;Assertion.errors.clear();}@Overridepublic void onTestFailure(ITestResult tr) {this.handleAssertion(tr);}@Overridepublic void onTestSkipped(ITestResult tr) {this.handleAssertion(tr);}@Overridepublic void onTestSuccess(ITestResult tr) {this.handleAssertion(tr);}private int index = 0;/*** 得到测试类所需的测试异常信息** @param tr*/private void handleAssertion(ITestResult tr) {if (!Assertion.flag) {Throwable throwable = tr.getThrowable();if (throwable == null) {throwable = new Throwable();}StackTraceElement[] traces = throwable.getStackTrace();StackTraceElement[] alltrace = new StackTraceElement[0];for (Error e : Assertion.errors) {StackTraceElement[] errorTraces = e.getStackTrace();StackTraceElement[] et = this.getKeyStackTrace(tr, errorTraces);StackTraceElement[] message = new StackTraceElement[] { new StackTraceElement("message : " + e.getMessage() + " in method : ", tr.getMethod().getMethodName(), tr.getTestClass().getRealClass().getSimpleName(), index) };index = 0;alltrace = this.merge(alltrace, message);alltrace = this.merge(alltrace, et);}if (traces != null) {traces = this.getKeyStackTrace(tr, traces);alltrace = this.merge(alltrace, traces);}throwable.setStackTrace(alltrace);tr.setThrowable(throwable);Assertion.flag = true;Assertion.errors.clear();tr.setStatus(ITestResult.FAILURE);}}/*** 根据测试类名获得该测试类的StackTraceElement数组** @param tr* @param stackTraceElements* @return*/private StackTraceElement[] getKeyStackTrace(ITestResult tr, StackTraceElement[] stackTraceElements) {List<StackTraceElement> ets = new ArrayList<StackTraceElement>();for (StackTraceElement stackTraceElement : stackTraceElements) {if (stackTraceElement.getClassName().equals(tr.getTestClass().getName())) {ets.add(stackTraceElement);index = stackTraceElement.getLineNumber();}}StackTraceElement[] et = new StackTraceElement[ets.size()];for (int i = 0; i < et.length; i++) {et[i] = ets.get(i);}return et;}/*** 合并两个StackTraceElement数组** @param traces1* @param traces2* @return*/private StackTraceElement[] merge(StackTraceElement[] traces1, StackTraceElement[] traces2) {StackTraceElement[] ste = new StackTraceElement[traces1.length + traces2.length];for (int i = 0; i < traces1.length; i++) {ste[i] = traces1[i];}for (int i = 0; i < traces2.length; i++) {ste[traces1.length + i] = traces2[i];}return ste;}}
③加入监听注解
@Listeners(AssertionListener.class)public class MyTest {@Testpublic void testAssertion() {beforeClass();try {Assertion.verifyEquals("aaa", "bbb", "aaa is wrong");Assertion.verifyEquals("aaa", "aaa");Assertion.verifyEquals("aaa", "ccc");} catch (Exception e) {logger.error("testAssertion:", e);}}}
运行结果:
FAILED: testAssertionjava.lang.Throwableat message : aaa is wrong expected [bbb] but found [aaa] in method : .testAssertion(LogonTest:41)at com.testcase.LogonTest.testAssertion(LogonTest.java:41)at message : expected [ccc] but found [aaa] in method : .testAssertion(LogonTest:43)at com.testcase.LogonTest.testAssertion(LogonTest.java:43)
小技巧:
为了省事一些可以把@Listeners放到testng.xml中,例如:
<listeners><listener class-name="com.framework.util.assertion.AssertionListener"></listener></listeners>
-
软断言
软断言运用了SoftAssert这个类。
private SoftAssert assertion = new SoftAssert();@Testpublic void testSoftAssert() {assertion.assertEquals("aaa", "bbb", "1 is wrong");assertion.assertEquals("aaa", "aaa", "2 is wrong");assertion.assertEquals("aaa", "ccc", "3 is wrong");assertion.assertAll();}
执行结果如下:
FAILED: testSoftAssertjava.lang.AssertionError: The following asserts failed:1 is wrong, 3 is wrong
注意assertEquals断言的message一定要写,否则会出现信息是null的情况,如下:
@Testpublic void testSoftAssert() {assertion.assertEquals("aaa", "bbb");assertion.assertEquals("aaa", "aaa");assertion.assertEquals("aaa", "ccc");assertion.assertAll();}
执行结果如下,判断不错误信息:
FAILED: testSoftAssertjava.lang.AssertionError: The following asserts failed:null, null
小技巧:
对于每次实例化SoftAssert这个类,可以写到一个basecase里面,然后采用extends继承的方式。
下次再介绍一下testng的失败重试。
1790

被折叠的 条评论
为什么被折叠?



