Appium失败截图及重试机制封装

Posted chanper

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
View Code

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 }
View Code

二、重试监听,主要应用了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 }
View Code

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 }
View Code

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 }
View Code

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 }

 

以上是关于Appium失败截图及重试机制封装的主要内容,如果未能解决你的问题,请参考以下文章

Python之如何优雅的重试

Appium-测试失败后屏幕截图的

RxSwift,分享+重试机制

Python + Appium 获取当前屏幕的截图方法的封装

appium自动化,失败自动截图

RocketMQ重试机制和消息幂