美文网首页软件测试
Appium自动化测试框架

Appium自动化测试框架

作者: A丶咔咔 | 来源:发表于2020-06-28 15:09 被阅读0次

1.在utils包中创建一个AppiumUtil类,这个类是对appium api进行封装的。

代码如下:

package utils;

import java.net.MalformedURLException;

import java.net.URL;

import java.util.List;

import java.util.Set;

import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import org.openqa.selenium.By;

import org.openqa.selenium.JavascriptExecutor;

import org.openqa.selenium.NoSuchElementException;

import org.openqa.selenium.TimeoutException;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.remote.DesiredCapabilities;

import org.openqa.selenium.support.ui.ExpectedCondition;

import org.openqa.selenium.support.ui.WebDriverWait;

import org.testng.Assert;

import org.testng.ITestResult;

import io.appium.java_client.AppiumDriver;

import io.appium.java_client.MultiTouchAction;

import io.appium.java_client.NoSuchContextException;

import io.appium.java_client.TouchAction;

import io.appium.java_client.android.AndroidDriver;

import io.appium.java_client.ios.IOSDriver;/**

* @author young

* @description appium api封装

* */publicclass AppiumUtil {

    publicAppiumDriver driver;

    public    ITestResult it;

    /**定义日志输出对象*/publicstaticLogger logger = Logger.getLogger(AppiumUtil.class);

    /**获取driver

    * @throws  */publicAppiumDriver getDriver(String url,DesiredCapabilities capabilities,String platform){

            if(platform.equalsIgnoreCase("android")){

            try {

                driver =newAndroidDriver(new URL(url), capabilities);

            } catch (MalformedURLException e) {

                e.printStackTrace();

            }

            }elseif(platform.equalsIgnoreCase("ios")){

                try {

                    driver =newIOSDriver (new URL(url),capabilities);

                } catch (MalformedURLException e) {

                    e.printStackTrace();

                }

            }else{

            }

            return driver;

    }

    /**退出app*/publicvoid closeApp(String appName){

        driver.closeApp();

        logger.info(appName+"已经关闭");

    }

    /**退出移动浏览器*/publicvoid quit(){

        driver.quit();

        logger.info("driver已被清理");

    }

    /**通过By对象 去查找某个元素*/public WebElement findElement(By by){

        return driver.findElement(by);

    }

    /**

    * 通过By对象 去查找一组元素

    * */publicList findElements(By by) {

        return driver.findElements(by);

    }

    /**清空元素内容*/publicvoid clear(By byElement){

        WebElement element = findElement(byElement);

        element.clear();

        logger.info("清空元素:"+getLocatorByElement(element,">")+"上的内容");

    }

    /**输入内容*/publicvoid typeContent(By byElement,String str){

        WebElement element = findElement(byElement);

        element.sendKeys(str);

        logger.info("在元素:"+getLocatorByElement(element,">")+"输入内容:"+str);

    }

    /**点击*/publicvoid click(By byElement){

        WebElement element = findElement(byElement);

        try{

        element.click();

        logger.info("点击元素:"+getLocatorByElement(element,">"));

        }catch(Exception e){

            logger.error("点击元素:"+getLocatorByElement(element,">")+"失败", e);

            Assert.fail("点击元素:"+getLocatorByElement(element,">")+"失败", e);

        }

    }

    /**查找一个元素 - appium新增的查找元素方法*/public WebElement findElement(String locateWay,String locateValue){

        WebElement element =null;

    switch(locateWay){

    case"AccessibilityId":

        element = driver.findElementByAccessibilityId(locateValue);

        break;//    case "AndroidUIAutomator"://        element = driver.findElementByAndroidUIAutomator(locateValue);//            break;case"ClassName":

        element = driver.findElementByClassName(locateValue);

        break;

    case"CSS":

        element = driver.findElementByCssSelector(locateValue);

        break;

    case"ID":

        element = driver.findElementById(locateValue);

        break;

    case"LinkText":

        element = driver.findElementByLinkText(locateValue);

        break;

    case"Name":

        element = driver.findElementByName(locateValue);

        break;

    case"PartialLinkText":

        element = driver.findElementByPartialLinkText(locateValue);

        break;

    case"TagName":

        element = driver.findElementByTagName(locateValue);

        break;

    case"Xpath":

        element = driver.findElementByXPath(locateValue);

        break;

    default:

        logger.error("定位方式:"+locateWay+"不被支持");

        Assert.fail("定位方式:"+locateWay+"不被支持");

        }

    return element;

    }

    /**查找一组元素 - appium新增的查找元素方法*/publicList findElements(String locateWay,String locateValue){

        List element=null;

    switch(locateWay){

    case"AccessibilityId":

        element = driver.findElementsByAccessibilityId(locateValue);

        break;//    case "AndroidUIAutomator"://        element = driver.findElementsByAndroidUIAutomator(locateValue);//            break;case"ClassName":

        element = driver.findElementsByClassName(locateValue);

        break;

    case"CSS":

        element = driver.findElementsByCssSelector(locateValue);

        break;

    case"ID":

        element = driver.findElementsById(locateValue);

        break;

    case"LinkText":

        element = driver.findElementsByLinkText(locateValue);

        break;

    case"Name":

        element = driver.findElementsByName(locateValue);

        break;

    case"PartialLinkText":

        element = driver.findElementsByPartialLinkText(locateValue);

        break;

    case"TagName":

        element = driver.findElementsByTagName(locateValue);

        break;

    case"Xpath":

        element = driver.findElementsByXPath(locateValue);

        break;

    default:

        logger.error("定位方式:"+locateWay+"不被支持");

        Assert.fail("定位方式:"+locateWay+"不被支持");

        }

    return element;

    }

    /**获取文本1*/public String getText(By by){

        return findElement(by).getText().trim();

    }

    /**获取文本2*/public String getText(String locateWay,String locateValue){

        String str="";

    switch(locateWay){

    case"AccessibilityId":

        str = driver.findElementByAccessibilityId(locateValue).getText().trim();

        break;//    case "AndroidUIAutomator"://        str = driver.findElementByAndroidUIAutomator(locateValue).getText().trim();//            break;case"ClassName":

        str = driver.findElementByClassName(locateValue).getText().trim();

        break;

    case"CSS":

        str = driver.findElementByCssSelector(locateValue).getText().trim();

        break;

    case"ID":

        str = driver.findElementById(locateValue).getText().trim();

        break;

    case"LinkText":

        str = driver.findElementByLinkText(locateValue).getText().trim();

        break;

    case"Name":

        str = driver.findElementByName(locateValue).getText().trim();

        break;

    case"PartialLinkText":

        str = driver.findElementByPartialLinkText(locateValue).getText().trim();

        break;

    case"TagName":

        str = driver.findElementByTagName(locateValue).getText().trim();

        break;

    case"Xpath":

        str = driver.findElementByXPath(locateValue).getText().trim();

        break;

    default:

        logger.error("定位方式:"+locateWay+"不被支持");

        Assert.fail("定位方式:"+locateWay+"不被支持");

        }

    return str;

    }

    /**提交*/publicvoid submit(By by){

        WebElement element=findElement(by);

        try{

            element.submit();

        }catch(Exception e){

            logger.error("在元素:"+getLocatorByElement(element,">")+"做的提交操作失败",e);

            Assert.fail("在元素:"+getLocatorByElement(element,">")+"做的提交操作失败",e);

        }

        logger.info("在元素:"+getLocatorByElement(element,">")+"做了提交操作");

    }

    /**

    * 获得webview页面的标题

    * */public String getTitle() {

        return driver.getTitle();

    }

    /**

    * 获得元素 属性的文本

    * */public String getAttributeText(By elementLocator, String attribute) {

        return findElement(elementLocator).getAttribute(attribute).trim();

    }

    /**

    * 在给定的时间内去查找元素,如果没找到则超时,抛出异常

    * */publicvoidwaitForElementToLoad(int elementTimeOut, final By By) {

        logger.info("开始查找元素["+ By +"]");

        try {

            (newWebDriverWait(driver, elementTimeOut)).until(newExpectedCondition() {

                public Boolean apply(WebDriver driver) {

                    WebElement element = driver.findElement(By);

                    return element.isDisplayed();

                }

            });

        } catch (TimeoutException e) {

            logger.error("超时!! "+ elementTimeOut +" 秒之后还没找到元素 ["+ By +"]");

            Assert.fail("超时!! "+ elementTimeOut +" 秒之后还没找到元素 ["+ By +"]");

        }

        logger.info("找到了元素 ["+ By +"]");

    }

    /**

    * 判断文本是不是和需求要求的文本一致

    * **/publicvoid isTextCorrect(String actual, String expected) {

        try {

            Assert.assertEquals(actual, expected);

        } catch (AssertionError e) {

            logger.error("期望的文字是 ["+ expected +"] 但是找到了 ["+ actual +"]");

            Assert.fail("期望的文字是 ["+ expected +"] 但是找到了 ["+ actual +"]");

        }

        logger.info("找到了期望的文字: ["+ expected +"]");

    }

    /**

    * 暂停当前用例的执行,暂停的时间为:sleepTime

    * */publicvoidpause(int sleepTime) {

        if(sleepTime <=0) {

            return;

        }

        try {

            TimeUnit.SECONDS.sleep(sleepTime);

            logger.info("暂停:"+sleepTime+"秒");

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }

    /** 根据元素来获取此元素的定位值 */public String getLocatorByElement(WebElement element, String expectText) {

        String text = element.toString();

        String expect =null;

        try {

            expect = text.substring(text.indexOf(expectText) +1, text.length() -1);

        } catch (Exception e) {

            e.printStackTrace();

            logger.error("failed to find the string ["+ expectText +"]");

        }

        return expect;

    }

    /**

    * 判断实际文本时候包含期望文本

    *

    * @param actual

    *            实际文本

    * @param expect

    *            期望文本

    */publicvoid isContains(String actual, String expect) {

        try {

            Assert.assertTrue(actual.contains(expect));

        } catch (AssertionError e) {

            logger.error("The ["+ actual +"] is not contains ["+ expect +"]");

            Assert.fail("The ["+ actual +"] is not contains ["+ expect +"]");

        }

        logger.info("The ["+ actual +"] is contains ["+ expect +"]");

    }

    /**跳转到webview页面*/publicvoidswitchWebview(int index){

        Set contexts = driver.getContextHandles();

        for (String context : contexts) {

        System.out.println(context);

        //打印出来看看有哪些context        }

        driver.context((String) contexts.toArray()[index]);

    }

    /**跳转到webview页面*/publicvoid switchWebview(String contextName){

        try{

        Set contexts = driver.getContextHandles();

        for (String context : contexts) {

        System.out.println(context);

        //打印出来看看有哪些context        }

        driver.context(contextName);

        }catch(NoSuchContextException nce){

            logger.error("没有这个context:"+contextName, nce);

            Assert.fail("没有这个context:"+contextName, nce);

        }

    }

    /**

    * 执行JavaScript 方法

    * */publicvoid executeJS(String js) {

        ((JavascriptExecutor) driver).executeScript(js);

        logger.info("执行JavaScript语句:["+ js +"]");

    }

    /**

    * 执行JavaScript 方法和对象

    * 用法:seleniumUtil.executeJS("arguments[0].click();", seleniumUtil.findElementBy(MyOrdersPage.MOP_TAB_ORDERCLOSE));

    * */publicvoid executeJS(String js, Object... args) {

        ((JavascriptExecutor) driver).executeScript(js, args);

        logger.info("执行JavaScript语句:["+ js +"]");

    }

    /**检查元素是不是存在*/public  boolean doesElementsExist(By byElement){

        try{

        findElement(byElement);

        returntrue;

        }catch(NoSuchElementException nee){

            returnfalse;

        }

    }

    /**长按操作*/publicvoid longPress(By by){

        TouchAction tAction=new TouchAction(driver);

        tAction.longPress(findElement(by)).perform();

    }

    /**滑动*/publicvoidswipe(intbeginX,intbeginY,intendX,int endY){

        TouchAction tAction=new TouchAction(driver);

        try{

        tAction.press(beginX,beginY).moveTo(endX,endY).release().perform();

        }catch(Exception e){

            e.printStackTrace();

        }

    }

    /**滚动 - 根据文本模糊匹配*/publicvoid scroll(String text){

        driver.scrollTo(text);

    }

    /**滚动 - 根据文本精准匹配*/public WebElement scrollExact(String text){

        return driver.scrollToExact(text);

    }

    /**拖拽操作*/publicvoid DragAndDrop(By dragElement,By dropElement){

        TouchAction act=new TouchAction(driver);

        act.press(findElement(dragElement)).perform();

        act.moveTo(findElement(dropElement)).release().perform();

    }

    /**放大和缩小*/publicvoidzoomAndPinch(intbeginX,intbeginY,intendX,int endY){

      intscrHeight = driver.manage().window().getSize().getHeight();

      intscrWidth = driver.manage().window().getSize().getWidth();

        MultiTouchAction multiTouch =new MultiTouchAction(driver);

        TouchAction tAction0 =new TouchAction(driver);

        TouchAction tAction1 =new TouchAction(driver);

        tAction0.press(scrWidth/2,scrHeight/2).waitAction(1000).moveTo(beginX,beginY).release();

        tAction1.press(scrWidth/2,scrHeight/2+40).waitAction(1000).moveTo(endX,endY).release();

        multiTouch.add(tAction0).add(tAction1);

        multiTouch.perform();

    }

    /**app置于后台运行*/publicvoidrunBackgound(int runTimes){

        driver.runAppInBackground(runTimes);

    }

    /**收起键盘*/publicvoid hideKeyboard(){

        driver.hideKeyboard();

        logger.info("虚拟键盘已经收起");

    }

    /**安装app*/publicvoid instalApp(String appPath){

        try{

        driver.installApp(appPath);

        }catch(Exception e){

            logger.error("app安装失败",e);

            Assert.fail("app安装失败",e);

        }

    }

    /**app是否安装*/public boolean isAppInstalled(String appPackage){

        if(driver.isAppInstalled(appPackage)){

            logger.info(appPackage+":已经安装");

            returntrue;

        }else {

            logger.info(appPackage+":未安装");

            returnfalse;

        }

    }

    /**页面过长时候滑动页面 window.scrollTo(左边距,上边距); */publicvoidscrollPage(intx,int y){

        String js ="window.scrollTo("+x+","+y+");";

        ((JavascriptExecutor)driver).executeScript(js);

    }

}

2.因为要显示log4日志,在pom.xml中加入jar包类:

1 <dependency>

2 <groupId>log4j</groupId>

3 <artifactId>log4j</artifactId>

4 <version>1.2.16</version>

5 <scope>provided</scope>

6 </dependency>

3.加载完成后要创建一个处理log类,名为:LogConfiguration类,代码如下

package com.young.appiumcombat.utils;

import java.util.Properties;

import org.apache.log4j.PropertyConfigurator;/**

* @author young

* @decription 动态生成各个模块中的每条用例的日志,运行完成用例之后请到result/log目录下查看

* */publicclass LogConfiguration {

        publicstaticvoid initLog(String fileName){

            //获取到模块名字String founctionName = getFunctionName(fileName);

            //声明日志文件存储路径以及文件名、格式final String logFilePath  ="./result/logs/"+founctionName+"/"+fileName+".log";

            Properties prop =new Properties();

            //配置日志输出的格式prop.setProperty("log4j.rootLogger","info, toConsole, toFile");

            prop.setProperty("log4j.appender.file.encoding","UTF-8" );

            prop.setProperty("log4j.appender.toConsole","org.apache.log4j.ConsoleAppender");

            prop.setProperty("log4j.appender.toConsole.Target","System.out");

            prop.setProperty("log4j.appender.toConsole.layout","org.apache.log4j.PatternLayout ");

            prop.setProperty("log4j.appender.toConsole.layout.ConversionPattern","[%d{yyyy-MM-dd HH:mm:ss}] [%p] %m%n");

            prop.setProperty("log4j.appender.toFile","org.apache.log4j.DailyRollingFileAppender");

            prop.setProperty("log4j.appender.toFile.file", logFilePath);

            prop.setProperty("log4j.appender.toFile.append","false");

            prop.setProperty("log4j.appender.toFile.Threshold","info");

            prop.setProperty("log4j.appender.toFile.layout","org.apache.log4j.PatternLayout");

            prop.setProperty("log4j.appender.toFile.layout.ConversionPattern","[%d{yyyy-MM-dd HH:mm:ss}] [%p] %m%n");

            //使配置生效            PropertyConfigurator.configure(prop);

        }

        /**取得模块名字*/publicstatic String getFunctionName(String fileName){

            String functionName =null;

            intfirstUndelineIndex = fileName.indexOf("_");

            functionName = fileName.substring(0, firstUndelineIndex-4);

            return functionName;

    }

}

4.因为我们要处理android和ios的项目,更方便处理兼容,在Utils中创建一个SelectDriver类,代码如下:

package com.young.appiumcombat.utils;

import java.io.File;

import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.remote.DesiredCapabilities;

import org.testng.Assert;

import org.testng.ITestContext;

import io.appium.java_client.AppiumDriver;/**

* @author Young

* @description 根据测试平台的不同生成不同的driver 比如AndroidDriver 或者是IOSDriver

*

* */publicclass SelectDriver {

    //声明driverpublicAppiumDriver driver;

    //声明DesiredCapabilitiespublic DesiredCapabilities capabilities;

    //声明ITestContext,用于获取testng配置文件内容public ITestContext testContext;

    //appium server地址public String serverURL;

    //测试引擎名字public String automationName;

    //测试平台名字public String platformName;

    //测试平台版本号public String platformVersion;

    //设备名字public String deviceName;

    //ios app的路径public String iosAppPath;

    //android app路径public String androidAppPath;

    //android app的 packagepublic String appPackage;

    //android app的activitypublic String appActivity;

    //安卓独有 - 是否使用unicode键盘,使用此键盘可以输入中文字符public boolean unicodeKeyboard;

    //android独有 - 是否重置键盘,如果设置了unicodeKeyboard键盘,可以将此参数设置为true,然后键盘会重置为系统默认的public boolean resetKeyboard;

    //是否覆盖已有的seesssion,这个用于多用例执行,如果不设置的话,会提示前一个session还没有结束,用例就不能继续执行了public boolean sessionOverride;

    //暂停的等待时间publicint sleepTime;

    //元素等待超时时间publicint elementTimeOut;

    //app文件路径,主要存储的是app的名字public String appFilePath;

    //webview的名字或者叫标识符,一般以WEBVIEW开头,例如WEBVIEW_com.microsoft.bingpublicfinalstaticString WEBVIEW_NAME =null;

    //原生app的名字或者标识符,一般是NATIVE_APPpublicfinalstaticString NATIVEAPP_NAME =null;

    //实例化本类的日志输出对象publicstaticLogger logger = Logger.getLogger(SelectDriver.class);

    publicAppiumDriver selectDriver(ITestContext context,AppiumUtil appiumUtil){

          //通过testng的xml文件获取serverURL参数值,并赋给  serverURL变量serverURL = context.getCurrentXmlTest().getParameter("serverURL");

          //通过testng的xml文件获取automationName参数值,并赋给  automationName变量automationName = context.getCurrentXmlTest().getParameter("automationName");

          //通过testng的xml文件获取platformName参数值,并赋给  platformName变量platformName = context.getCurrentXmlTest().getParameter("platformName");

          //通过testng的xml文件获取platformVersion参数值,并赋给  platformVersion变量platformVersion = context.getCurrentXmlTest().getParameter("platformVersion");

          //通过testng的xml文件获取deviceName参数值,并赋给  deviceName变量deviceName = context.getCurrentXmlTest().getParameter("deviceName");

          //通过testng的xml文件获取androidAppPath参数值,并赋给  androidAppPath变量androidAppPath = context.getCurrentXmlTest().getParameter("androidAppPath");

          //通过testng的xml文件获取iosAppPath参数值,并赋给  iosAppPath变量iosAppPath = context.getCurrentXmlTest().getParameter("iosAppPath");

          //通过testng的xml文件获取appPackage参数值,并赋给  appPackage变量appPackage = context.getCurrentXmlTest().getParameter("appPackage");

          //通过testng的xml文件获取appActivity参数值,并赋给  appActivity变量appActivity = context.getCurrentXmlTest().getParameter("appActivity");

          //通过testng的xml文件获取unicodeKeyboard参数值,并赋给  unicodeKeyboard变量unicodeKeyboard = Boolean.parseBoolean(context.getCurrentXmlTest().getParameter("unicodeKeyboard"));

          //通过testng的xml文件获取resetKeyboard参数值,并赋给  resetKeyboard变量resetKeyboard = Boolean.parseBoolean(context.getCurrentXmlTest().getParameter("resetKeyboard"));

          //通过testng的xml文件获取sessionOverride参数值,并赋给  sessionOverride变量sessionOverride = Boolean.parseBoolean(context.getCurrentXmlTest().getParameter("sessionOverride"));

          //通过testng的xml文件获取sleepTime参数值,并赋给  sleepTime变量sleepTime = Integer.valueOf(context.getCurrentXmlTest().getParameter("sleepTime"));

          //通过testng的xml文件获取elementTimeOut参数值,并赋给  elementTimeOut变量elementTimeOut = Integer.valueOf(context.getCurrentXmlTest().getParameter("elementTimeOut"));

          //通过testng的xml文件获取appFilePath参数值,并赋给  appFilePath变量appFilePath = context.getCurrentXmlTest().getParameter("appFilePath");

          this.testContext = context;

          capabilities =new DesiredCapabilities();

          //告诉测试程序,当前项目目录在哪里File classpathRoot =newFile(System.getProperty("user.dir"));

          //设置capability,以便和appium创建sessioncapabilities.setCapability("platformName",platformName);

          capabilities.setCapability("platformVersion",platformVersion);

          capabilities.setCapability("deviceName",deviceName);

          capabilities.setCapability("sessionOverride", sessionOverride);

          //如果测试平台是android的话,执行下面这个if语句内容if(platformName.equalsIgnoreCase("android")){

                /**

                * 设置和android  测试相关的capability并实例化driver对象

                * */              File app =new File(classpathRoot, androidAppPath);

              capabilities.setCapability("app", app.getAbsolutePath());

              capabilities.setCapability("unicodeKeyboard", unicodeKeyboard);

              capabilities.setCapability("resetKeyboard", resetKeyboard);

              capabilities.setCapability("automationName",automationName);

              capabilities.setCapability("appPackage", appPackage);

              capabilities.setCapability("appActivity", appActivity);

              driver = appiumUtil.getDriver(serverURL, capabilities,platformName);

              testContext.setAttribute("APPIUM_DRIVER", driver);

              logger.info(PropertiesDataProvider.getTestData(appFilePath, appPackage)+"已经启动");

              driver.manage().timeouts().implicitlyWait(elementTimeOut, TimeUnit.SECONDS);

              return driver;

              //如果测试平台是ios的话,执行下面这个if语句内容}elseif(platformName.equalsIgnoreCase("ios")){

            /**

            * 设置和ios  测试相关的capability并实例化driver对象

            * */              File app =new File(classpathRoot, iosAppPath);

              capabilities.setCapability("app", app.getAbsolutePath());

              //ios设置自动接收系统alert,注意IOS弹出的alert,APPIUM可以自动处理掉,支持ios8以上系统capabilities.setCapability("autoAcceptAlerts",true);

              driver = appiumUtil.getDriver(serverURL, capabilities,platformName);

              testContext.setAttribute("APPIUM_DRIVER", driver);

              driver.manage().timeouts().implicitlyWait(elementTimeOut,TimeUnit.SECONDS);

        }else{

        logger.error("初始化driver失败");

        Assert.fail("初始化driver失败");

        }

        //最后返回dirver对象return driver;

    }

}

5.有时候我们不想把太多的配置放到testng.xml中,我们就需要根据key读取属性文件里面的value值,现在res/下创建properties,里面有app.properties 和config.properties 两个文本,然后在utils下写一个方法获取value的值,类为:PropertiesDataProvider,代码如下:

package com.young.appiumcombat.utils;

import org.apache.commons.configuration.Configuration;

import org.apache.commons.configuration.ConfigurationException;

import org.apache.commons.configuration.PropertiesConfiguration;/**

* @author young

* @Desription 从.properties文件中读取相关测试数据<br>

*

* */publicclass PropertiesDataProvider {

    publicstatic String getTestData(String configFilePath, String key) {

        Configuration config =null;

        try {

            config =new PropertiesConfiguration(configFilePath);

        } catch (ConfigurationException e) {

            e.printStackTrace();

        }

        return String.valueOf(config.getProperty(key));

    }

}

6.html报告插件

哈,我们使用https://blog.csdn.net/A_Kaka/article/details/106988528这里的arrow的报告插件,在将CONFIGFILE值修改成res/properties目录下的 config.properties,代码如下:

1retrycount=02sourcecodedir=com/young/appiumcombat/testcases3sourcecodeencoding=UTF-8

相关文章

网友评论

    本文标题:Appium自动化测试框架

    本文链接:https://www.haomeiwen.com/subject/ffkwfktx.html