Appium失败截图及重试机制封装(二)
一、失败截图封装
1、主要封装了失败之后的文件名、重写了失败之后消息、失败了以后做个截图,最后置为失败,并且存放到相对路径下、截图操作,未把失败用例至为Fail,主要代码如下:
1 package cn.hysh.appium.testng; 2 3 import org.testng.Assert; 4 import org.testng.Reporter; 5 6 import cn.hysh.appium.base.AndroidDriverBase; 7 import cn.hysh.appium.base.hyshPath; 8 9 10 public class Assertion { 11 private AndroidDriverBase driver; 12 public Assertion(AndroidDriverBase driver){ 13 this.driver=driver; 14 } 15 //注意断言的失败不是一个exception,而是一个error 16 public void assertEquals(Object actual, Object expected,String fileName){ 17 try{ 18 Assert.assertEquals(actual, expected); 19 }catch(AssertionError e){ 20 fail(fileName); 21 } 22 } 23 24 public void assertEquals(Object actual, Object expected, String fileName,String message){ 25 try{ 26 Assert.assertEquals(actual, expected, message); 27 }catch(AssertionError e){ 28 fail(fileName,message); 29 } 30 } 31 32 public void verifyEquals(Object actual, Object expected,String fileName){ 33 try{ 34 Assert.assertEquals(actual, expected); 35 }catch(AssertionError e){ 36 try { 37 driver.takeScreen(hyshPath.path, "\\images\\"+Thread.currentThread().getId()+fileName); 38 } catch (Exception e1) { 39 e1.printStackTrace(); 40 } 41 } 42 } 43 public void verifyEquals(Object actual, Object expected,String fileName,String message){ 44 try{ 45 Assert.assertEquals(actual, expected, message); 46 }catch(AssertionError e){ 47 try { 48 driver.takeScreen(hyshPath.path, "\\images\\"+Thread.currentThread().getId()+fileName); 49 } catch (Exception e1) { 50 e1.printStackTrace(); 51 } 52 } 53 } 54 /** 55 失败了以后做个截图,最后置为失败,并且存放到相对路径下 56 */ 57 public void fail(String fileName){ 58 try { 59 Long date=System.currentTimeMillis(); 60 System.out.println(date); 61 driver.takeScreen("D:/autotest/images",Thread.currentThread().getId()+"_"+date+fileName); 62 } catch (Exception e1) { 63 e1.printStackTrace(); 64 } 65 Assert.fail(); 66 } 67 public void fail(String fileName,String message){ 68 try { 69 Long date=System.currentTimeMillis(); 70 System.out.println(date); 71 driver.takeScreen("D:/autotest/images",Thread.currentThread().getId()+"_"+date+fileName); 72 } catch (Exception e1) { 73 e1.printStackTrace(); 74 } 75 Assert.fail(message); 76 } 77 }
2、如何应用?主要代码如下:
1 public class AppTest { 2 AndroidDriverBase driver; 3 Assertion myAssert; 4 @Parameters({"udid","port"}) 5 @BeforeClass 6 public void beforeClass(String udid,String port){ 7 ProUtil p=new ProUtil(hyshPath.globalPath); 8 String server=p.getPro("server"); 9 String capsPath=hyshPath.capsPath; 10 String input="com.example.android.softkeyboard/.SoftKeyboard"; 11 try { 12 driver=new AndroidDriverBase(server, port, capsPath, udid, input); 13 myAssert=new Assertion(driver); 14 driver.implicitlyWaitDefault(); 15 } catch (Exception e) { 16 SendMail sm=new SendMail(); 17 sm.send("driver失败", e.getMessage()); 18 } 19 } 20 @DataProvider 21 public Object[][] loginData() throws Exception{ 22 Object[][] ob=ExcelUtil.getTestData("C:\\Users\\Administrator\\Desktop/test.xlsx", "Sheet1"); 23 return ob; 24 } 25 @Test(dataProvider="loginData") 26 public void t001_login(String caseNumber,String caseName,String username,String password,String assertValue,String filename) throws Exception{ 27 ExcelUtil eu=new ExcelUtil("C:\\Users\\Administrator\\Desktop/test.xlsx", "Sheet1"); 28 Login l=new Login(driver); 29 Home home=l.loginTest(username,password); 30 try { 31 myAssert.assertEquals(driver.getPageSouce().contains(assertValue), true, filename); 32 eu.setCellData(Integer.valueOf(caseNumber), eu.getLastColumnNum(), "测试通过"); 33 } catch (Error e) { 34 eu.setCellData(Integer.valueOf(caseNumber), eu.getLastColumnNum(), "测试失败"); 35 Assert.fail(e.getMessage()); 36 } 37 38 } 39 @Test(enabled=false) 40 public void t002_search(){ 41 Home home=new Home(driver); 42 Boolean flag=home.searchTest("test"); 43 myAssert.assertEquals(flag==true, true, "searcherror"); 44 45 } 46 @Test(enabled=false) 47 public void t003_attention(){ 48 Article ar=new Article(driver); 49 boolean result=ar.attention(); 50 myAssert.assertEquals(result==true, true, "attentionerror"); 51 } 52 @Test(enabled=false) 53 public void t004_personInfo(){ 54 EditPersonInfo edinfo=new EditPersonInfo(driver); 55 boolean flag=edinfo.modifyPersonInfo(); 56 myAssert.assertEquals(flag, true, "personinfoerror"); 57 System.out.println(1); 58 59 } 60 61 @AfterMethod 62 public void restart(){ 63 String appPackge=(String)driver.getCapabilities().getCapability(AndroidMobileCapabilityType.APP_PACKAGE); 64 String appActivity=(String)driver.getCapabilities().getCapability(AndroidMobileCapabilityType.APP_ACTIVITY); 65 driver.startActivity(appPackge,appActivity); 66 } 67 68 @AfterClass 69 public void afterClass(){ 70 driver.resetApp(); 71 driver.quit(); 72 } 73 74 }
二、重试监听,主要应用了testng的监听机制
1、RetryListener实现了IAnnotationTransformer接口,做了判断,如果retry为null,就把retry设置为TestngRetry对象,主要代码如下:
1 import java.lang.reflect.Constructor; 2 import java.lang.reflect.Method; 3 4 import org.testng.IRetryAnalyzer; 5 import org.testng.annotations.ITestAnnotation; 6 import org.testng.internal.annotations.IAnnotationTransformer; 7 8 9 public class RetryListener implements IAnnotationTransformer { 10 11 @Override 12 public void transform(ITestAnnotation annotation, Class testClass, 13 Constructor testConstructor, Method testMethod) { 14 IRetryAnalyzer retry = annotation.getRetryAnalyzer(); 15 if (retry == null) { 16 annotation.setRetryAnalyzer(TestngRetry.class); 17 } 18 } 19 }
2、此外还要TestNGRetry实现IRetryAnalyzer接口,主要重写了重试次数(最大的重试次数),主要代码如下:
1 import org.testng.IRetryAnalyzer; 2 import org.testng.ITestResult; 3 import org.testng.Reporter; 4 5 public class TestngRetry implements IRetryAnalyzer { 6 //private static Logger logger = Logger.getLogger(TestngRetry.class); 7 private int retryCount = 1; 8 private int maxRetryCount=3; 9 @Override 10 public boolean retry(ITestResult result) { 11 if (retryCount <= maxRetryCount) { 12 String message = "running retry for '" + result.getName() + "' on class " + this.getClass().getName() + " Retrying " 13 + retryCount + " times"; 14 //logger.info(message); 15 Reporter.setCurrentTestResult(result); 16 Reporter.log("RunCount=" + (retryCount + 1)); 17 retryCount++; 18 return true; 19 } 20 return false; 21 } 22 23 }
3、如何应用?代码如下:
1 public class RetryTest { 2 3 @Test(retryAnalyzer=TestngRetry.class) 4 public void test(){ 5 System.out.println("xx"); 6 Assert.fail(); 7 } 8 }
4、重写了TestNG监听类,主要是测试类失败后,成功的、跳过的、开始、完成的(重试之后报告的整理)重写,主要代码如下:
1 import java.text.SimpleDateFormat; 2 import java.util.ArrayList; 3 import java.util.Arrays; 4 import java.util.Date; 5 import java.util.HashSet; 6 import java.util.Iterator; 7 import java.util.Set; 8 9 import org.testng.ITestContext; 10 import org.testng.ITestResult; 11 import org.testng.Reporter; 12 import org.testng.TestListenerAdapter; 13 import org.testng.log4testng.Logger; 14 15 public class TestngListener extends TestListenerAdapter { 16 private static Logger logger = Logger.getLogger(TestngListener.class); 17 public static final String CONFIG = "config.properties"; 18 19 @Override 20 public void onTestFailure(ITestResult tr) { 21 super.onTestFailure(tr); 22 logger.info(tr.getName() + " Failure"); 23 } 24 25 @Override 26 public void onTestSkipped(ITestResult tr) { 27 super.onTestSkipped(tr); 28 logger.info(tr.getName() + " Skipped"); 29 } 30 31 @Override 32 public void onTestSuccess(ITestResult tr) { 33 super.onTestSuccess(tr); 34 logger.info(tr.getName() + " Success"); 35 } 36 37 @Override 38 public void onTestStart(ITestResult tr) { 39 super.onTestStart(tr); 40 logger.info(tr.getName() + " Start"); 41 } 42 /** 43 成功之后测试报告整理 44 */ 45 @Override 46 public void onFinish(ITestContext testContext) { 47 super.onFinish(testContext); 48 ArrayList<ITestResult> testsToBeRemoved = new ArrayList<ITestResult>(); 49 Set<Integer> passedTestIds = new HashSet<Integer>(); 50 for (ITestResult passedTest : testContext.getPassedTests().getAllResults()) { 51 logger.info("PassedTests = " + passedTest.getName()); 52 passedTestIds.add(getId(passedTest)); 53 } 54 55 Set<Integer> failedTestIds = new HashSet<Integer>(); 56 for (ITestResult failedTest : testContext.getFailedTests().getAllResults()) { 57 logger.info("failedTest = " + failedTest.getName()); 58 int failedTestId = getId(failedTest); 59 60 if (failedTestIds.contains(failedTestId) || passedTestIds.contains(failedTestId)) { 61 testsToBeRemoved.add(failedTest); 62 } else { 63 failedTestIds.add(failedTestId); 64 } 65 } 66 67 for (Iterator<ITestResult> iterator = testContext.getFailedTests().getAllResults().iterator(); iterator.hasNext();) { 68 ITestResult testResult = iterator.next(); 69 if (testsToBeRemoved.contains(testResult)) { 70 logger.info("Remove repeat Fail Test: " + testResult.getName()); 71 iterator.remove(); 72 } 73 } 74 75 76 } 77 private int getId(ITestResult result) { 78 int id = result.getTestClass().getName().hashCode(); 79 id = id + result.getMethod().getMethodName().hashCode(); 80 id = id + (result.getParameters() != null ? Arrays.hashCode(result.getParameters()) : 0); 81 return id; 82 } 83 }
5、如何应用?主要代码如下:
1 @Listeners(TestngListener.class) 2 public class RetryTest { 3 4 @Test(retryAnalyzer=TestngRetry.class) 5 public void test(){ 6 System.out.println("xx"); 7 Assert.fail(); 8 } 9 }