Appium自动化测试框架
1.在utils包中创建一个AppiumUtil类,这个类是对appium api进行封装的。
代码如下:
1 package utils; 2 3 import java.net.MalformedURLException; 4 import java.net.URL; 5 import java.util.List; 6 import java.util.Set; 7 import java.util.concurrent.TimeUnit; 8 9 import org.apache.log4j.Logger; 10 import org.openqa.selenium.By; 11 import org.openqa.selenium.JavascriptExecutor; 12 import org.openqa.selenium.NoSuchElementException; 13 import org.openqa.selenium.TimeoutException; 14 import org.openqa.selenium.WebDriver; 15 import org.openqa.selenium.WebElement; 16 import org.openqa.selenium.remote.DesiredCapabilities; 17 import org.openqa.selenium.support.ui.ExpectedCondition; 18 import org.openqa.selenium.support.ui.WebDriverWait; 19 import org.testng.Assert; 20 import org.testng.ITestResult; 21 22 import io.appium.java_client.AppiumDriver; 23 import io.appium.java_client.MultiTouchAction; 24 import io.appium.java_client.NoSuchContextException; 25 import io.appium.java_client.TouchAction; 26 import io.appium.java_client.android.AndroidDriver; 27 import io.appium.java_client.ios.IOSDriver; 28 29 /** 30 * @author young 31 * @description appium api封装 32 * */ 33 34 public class AppiumUtil { 35 36 public AppiumDriver<WebElement> driver; 37 public ITestResult it; 38 /**定义日志输出对象*/ 39 public static Logger logger = Logger.getLogger(AppiumUtil.class); 40 41 /**获取driver 42 * @throws */ 43 public AppiumDriver<WebElement> getDriver(String url,DesiredCapabilities capabilities,String platform){ 44 45 if(platform.equalsIgnoreCase("android")){ 46 try { 47 driver = new AndroidDriver<WebElement>(new URL(url), capabilities); 48 } catch (MalformedURLException e) { 49 e.printStackTrace(); 50 } 51 }else if(platform.equalsIgnoreCase("ios")){ 52 try { 53 driver = new IOSDriver<WebElement> (new URL(url),capabilities); 54 } catch (MalformedURLException e) { 55 e.printStackTrace(); 56 } 57 }else{ 58 59 } 60 return driver; 61 62 } 63 64 /**退出app*/ 65 public void closeApp(String appName){ 66 driver.closeApp(); 67 logger.info(appName+"已经关闭"); 68 } 69 70 /**退出移动浏览器*/ 71 public void quit(){ 72 driver.quit(); 73 logger.info("driver已被清理"); 74 } 75 /**通过By对象 去查找某个元素*/ 76 public WebElement findElement(By by){ 77 return driver.findElement(by); 78 } 79 80 /** 81 * 通过By对象 去查找一组元素 82 * */ 83 public List<WebElement> findElements(By by) { 84 return driver.findElements(by); 85 } 86 87 /**清空元素内容*/ 88 public void clear(By byElement){ 89 WebElement element = findElement(byElement); 90 element.clear(); 91 logger.info("清空元素:"+getLocatorByElement(element, ">")+"上的内容"); 92 } 93 94 /**输入内容*/ 95 public void typeContent(By byElement,String str){ 96 WebElement element = findElement(byElement); 97 element.sendKeys(str); 98 logger.info("在元素:"+getLocatorByElement(element, ">")+"输入内容:"+str); 99 } 100 /**点击*/ 101 public void click(By byElement){ 102 WebElement element = findElement(byElement); 103 try{ 104 element.click(); 105 logger.info("点击元素:"+getLocatorByElement(element, ">")); 106 }catch(Exception e){ 107 logger.error("点击元素:"+getLocatorByElement(element, ">")+"失败", e); 108 Assert.fail("点击元素:"+getLocatorByElement(element, ">")+"失败", e); 109 } 110 111 } 112 113 /**查找一个元素 - appium新增的查找元素方法*/ 114 public WebElement findElement(String locateWay,String locateValue){ 115 WebElement element = null; 116 switch(locateWay){ 117 118 case "AccessibilityId": 119 element = driver.findElementByAccessibilityId(locateValue); 120 break; 121 // case "AndroidUIAutomator": 122 // element = driver.findElementByAndroidUIAutomator(locateValue); 123 // break; 124 case "ClassName": 125 element = driver.findElementByClassName(locateValue); 126 break; 127 case "CSS": 128 element = driver.findElementByCssSelector(locateValue); 129 break; 130 case "ID": 131 element = driver.findElementById(locateValue); 132 break; 133 case "LinkText": 134 element = driver.findElementByLinkText(locateValue); 135 break; 136 case "Name": 137 element = driver.findElementByName(locateValue); 138 break; 139 case "PartialLinkText": 140 element = driver.findElementByPartialLinkText(locateValue); 141 break; 142 case "TagName": 143 element = driver.findElementByTagName(locateValue); 144 break; 145 case "Xpath": 146 element = driver.findElementByXPath(locateValue); 147 break; 148 default: 149 logger.error("定位方式:"+locateWay+"不被支持"); 150 Assert.fail("定位方式:"+locateWay+"不被支持"); 151 152 } 153 return element; 154 155 } 156 157 /**查找一组元素 - appium新增的查找元素方法*/ 158 public List<?> findElements(String locateWay,String locateValue){ 159 List<?> element=null; 160 switch(locateWay){ 161 162 case "AccessibilityId": 163 element = driver.findElementsByAccessibilityId(locateValue); 164 break; 165 // case "AndroidUIAutomator": 166 // element = driver.findElementsByAndroidUIAutomator(locateValue); 167 // break; 168 case "ClassName": 169 element = driver.findElementsByClassName(locateValue); 170 break; 171 case "CSS": 172 element = driver.findElementsByCssSelector(locateValue); 173 break; 174 case "ID": 175 element = driver.findElementsById(locateValue); 176 break; 177 case "LinkText": 178 element = driver.findElementsByLinkText(locateValue); 179 break; 180 case "Name": 181 element = driver.findElementsByName(locateValue); 182 break; 183 case "PartialLinkText": 184 element = driver.findElementsByPartialLinkText(locateValue); 185 break; 186 case "TagName": 187 element = driver.findElementsByTagName(locateValue); 188 break; 189 case "Xpath": 190 element = driver.findElementsByXPath(locateValue); 191 break; 192 default: 193 logger.error("定位方式:"+locateWay+"不被支持"); 194 Assert.fail("定位方式:"+locateWay+"不被支持"); 195 196 } 197 return element; 198 199 } 200 201 /**获取文本1*/ 202 public String getText(By by){ 203 return findElement(by).getText().trim(); 204 } 205 206 207 /**获取文本2*/ 208 public String getText(String locateWay,String locateValue){ 209 String str=""; 210 switch(locateWay){ 211 212 case "AccessibilityId": 213 str = driver.findElementByAccessibilityId(locateValue).getText().trim(); 214 break; 215 // case "AndroidUIAutomator": 216 // str = driver.findElementByAndroidUIAutomator(locateValue).getText().trim(); 217 // break; 218 case "ClassName": 219 str = driver.findElementByClassName(locateValue).getText().trim(); 220 break; 221 case "CSS": 222 str = driver.findElementByCssSelector(locateValue).getText().trim(); 223 break; 224 case "ID": 225 str = driver.findElementById(locateValue).getText().trim(); 226 break; 227 case "LinkText": 228 str = driver.findElementByLinkText(locateValue).getText().trim(); 229 break; 230 case "Name": 231 str = driver.findElementByName(locateValue).getText().trim(); 232 break; 233 case "PartialLinkText": 234 str = driver.findElementByPartialLinkText(locateValue).getText().trim(); 235 break; 236 case "TagName": 237 str = driver.findElementByTagName(locateValue).getText().trim(); 238 break; 239 case "Xpath": 240 str = driver.findElementByXPath(locateValue).getText().trim(); 241 break; 242 default: 243 logger.error("定位方式:"+locateWay+"不被支持"); 244 Assert.fail("定位方式:"+locateWay+"不被支持"); 245 246 } 247 return str; 248 249 } 250 251 /**提交*/ 252 public void submit(By by){ 253 WebElement element=findElement(by); 254 try{ 255 element.submit(); 256 }catch(Exception e){ 257 logger.error("在元素:"+getLocatorByElement(element, ">")+"做的提交操作失败",e); 258 Assert.fail("在元素:"+getLocatorByElement(element, ">")+"做的提交操作失败",e); 259 } 260 logger.info("在元素:"+getLocatorByElement(element, ">")+"做了提交操作"); 261 } 262 263 /** 264 * 获得webview页面的标题 265 * */ 266 public String getTitle() { 267 return driver.getTitle(); 268 } 269 270 /** 271 * 获得元素 属性的文本 272 * */ 273 public String getAttributeText(By elementLocator, String attribute) { 274 return findElement(elementLocator).getAttribute(attribute).trim(); 275 } 276 277 /** 278 * 在给定的时间内去查找元素,如果没找到则超时,抛出异常 279 * */ 280 public void waitForElementToLoad(int elementTimeOut, final By By) { 281 logger.info("开始查找元素[" + By + "]"); 282 try { 283 (new WebDriverWait(driver, elementTimeOut)).until(new ExpectedCondition<Boolean>() { 284 285 public Boolean apply(WebDriver driver) { 286 WebElement element = driver.findElement(By); 287 return element.isDisplayed(); 288 } 289 }); 290 } catch (TimeoutException e) { 291 logger.error("超时!! " + elementTimeOut + " 秒之后还没找到元素 [" + By + "]"); 292 Assert.fail("超时!! " + elementTimeOut + " 秒之后还没找到元素 [" + By + "]"); 293 294 } 295 logger.info("找到了元素 [" + By + "]"); 296 } 297 298 /** 299 * 判断文本是不是和需求要求的文本一致 300 * **/ 301 public void isTextCorrect(String actual, String expected) { 302 try { 303 Assert.assertEquals(actual, expected); 304 } catch (AssertionError e) { 305 logger.error("期望的文字是 [" + expected + "] 但是找到了 [" + actual + "]"); 306 Assert.fail("期望的文字是 [" + expected + "] 但是找到了 [" + actual + "]"); 307 308 } 309 logger.info("找到了期望的文字: [" + expected + "]"); 310 311 } 312 313 /** 314 * 暂停当前用例的执行,暂停的时间为:sleepTime 315 * */ 316 public void pause(int sleepTime) { 317 if (sleepTime <= 0) { 318 return; 319 } 320 try { 321 TimeUnit.SECONDS.sleep(sleepTime); 322 logger.info("暂停:"+sleepTime+"秒"); 323 } catch (InterruptedException e) { 324 e.printStackTrace(); 325 } 326 327 } 328 329 330 331 /** 根据元素来获取此元素的定位值 */ 332 public String getLocatorByElement(WebElement element, String expectText) { 333 String text = element.toString(); 334 String expect = null; 335 try { 336 expect = text.substring(text.indexOf(expectText) + 1, text.length() - 1); 337 } catch (Exception e) { 338 e.printStackTrace(); 339 logger.error("failed to find the string [" + expectText + "]"); 340 341 } 342 343 return expect; 344 345 } 346 347 348 /** 349 * 判断实际文本时候包含期望文本 350 * 351 * @param actual 352 * 实际文本 353 * @param expect 354 * 期望文本 355 */ 356 public void isContains(String actual, String expect) { 357 try { 358 Assert.assertTrue(actual.contains(expect)); 359 } catch (AssertionError e) { 360 logger.error("The [" + actual + "] is not contains [" + expect + "]"); 361 Assert.fail("The [" + actual + "] is not contains [" + expect + "]"); 362 } 363 logger.info("The [" + actual + "] is contains [" + expect + "]"); 364 } 365 366 /**跳转到webview页面*/ 367 public void switchWebview(int index){ 368 Set<String> contexts = driver.getContextHandles(); 369 for (String context : contexts) { 370 System.out.println(context); 371 //打印出来看看有哪些context 372 } 373 driver.context((String) contexts.toArray()[index]); 374 375 } 376 377 378 /**跳转到webview页面*/ 379 public void switchWebview(String contextName){ 380 try{ 381 Set<String> contexts = driver.getContextHandles(); 382 for (String context : contexts) { 383 System.out.println(context); 384 //打印出来看看有哪些context 385 } 386 driver.context(contextName); 387 }catch(NoSuchContextException nce){ 388 logger.error("没有这个context:"+contextName, nce); 389 Assert.fail("没有这个context:"+contextName, nce); 390 } 391 392 } 393 394 395 /** 396 * 执行JavaScript 方法 397 * */ 398 public void executeJS(String js) { 399 ((JavascriptExecutor) driver).executeScript(js); 400 logger.info("执行JavaScript语句:[" + js + "]"); 401 } 402 403 /** 404 * 执行JavaScript 方法和对象 405 * 用法:seleniumUtil.executeJS("arguments[0].click();", seleniumUtil.findElementBy(MyOrdersPage.MOP_TAB_ORDERCLOSE)); 406 * */ 407 public void executeJS(String js, Object... args) { 408 ((JavascriptExecutor) driver).executeScript(js, args); 409 logger.info("执行JavaScript语句:[" + js + "]"); 410 } 411 412 /**检查元素是不是存在*/ 413 public boolean doesElementsExist(By byElement){ 414 try{ 415 findElement(byElement); 416 return true; 417 }catch(NoSuchElementException nee){ 418 419 return false; 420 } 421 422 423 } 424 425 /**长按操作*/ 426 public void longPress(By by){ 427 TouchAction tAction=new TouchAction(driver); 428 tAction.longPress(findElement(by)).perform(); 429 } 430 431 /**滑动*/ 432 public void swipe(int beginX,int beginY,int endX,int endY){ 433 TouchAction tAction=new TouchAction(driver); 434 try{ 435 tAction.press(beginX,beginY).moveTo(endX,endY).release().perform(); 436 }catch(Exception e){ 437 e.printStackTrace(); 438 } 439 } 440 441 /**滚动 - 根据文本模糊匹配*/ 442 public void scroll(String text){ 443 driver.scrollTo(text); 444 } 445 446 /**滚动 - 根据文本精准匹配*/ 447 public WebElement scrollExact(String text){ 448 return driver.scrollToExact(text); 449 } 450 451 /**拖拽操作*/ 452 public void DragAndDrop(By dragElement,By dropElement){ 453 TouchAction act=new TouchAction(driver); 454 act.press(findElement(dragElement)).perform(); 455 act.moveTo(findElement(dropElement)).release().perform(); 456 } 457 458 /**放大和缩小*/ 459 public void zoomAndPinch(int beginX,int beginY,int endX,int endY){ 460 int scrHeight = driver.manage().window().getSize().getHeight(); 461 int scrWidth = driver.manage().window().getSize().getWidth(); 462 MultiTouchAction multiTouch = new MultiTouchAction(driver); 463 TouchAction tAction0 = new TouchAction(driver); 464 TouchAction tAction1 = new TouchAction(driver); 465 tAction0.press(scrWidth/2,scrHeight/2).waitAction(1000).moveTo(beginX,beginY).release(); 466 tAction1.press(scrWidth/2,scrHeight/2+40).waitAction(1000).moveTo(endX,endY).release(); 467 multiTouch.add(tAction0).add(tAction1); 468 multiTouch.perform(); 469 470 } 471 472 /**app置于后台运行*/ 473 public void runBackgound(int runTimes){ 474 driver.runAppInBackground(runTimes); 475 476 } 477 478 /**收起键盘*/ 479 public void hideKeyboard(){ 480 driver.hideKeyboard(); 481 logger.info("虚拟键盘已经收起"); 482 483 } 484 485 /**安装app*/ 486 public void instalApp(String appPath){ 487 try{ 488 driver.installApp(appPath); 489 }catch(Exception e){ 490 logger.error("app安装失败",e); 491 Assert.fail("app安装失败",e); 492 } 493 } 494 495 /**app是否安装*/ 496 public boolean isAppInstalled(String appPackage){ 497 498 if(driver.isAppInstalled(appPackage)){ 499 logger.info(appPackage+":已经安装"); 500 return true; 501 }else { 502 logger.info(appPackage+":未安装"); 503 return false; 504 } 505 } 506 507 /**页面过长时候滑动页面 window.scrollTo(左边距,上边距); */ 508 public void scrollPage(int x,int y){ 509 String js ="window.scrollTo("+x+","+y+");"; 510 ((JavascriptExecutor)driver).executeScript(js); 511 } 512 513 514 515 }
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类,代码如下:
1 package com.young.appiumcombat.utils; 2 import java.util.Properties; 3 4 import org.apache.log4j.PropertyConfigurator; 5 /** 6 * @author young 7 * @decription 动态生成各个模块中的每条用例的日志,运行完成用例之后请到result/log目录下查看 8 * */ 9 public class LogConfiguration { 10 11 public static void initLog(String fileName){ 12 //获取到模块名字 13 String founctionName = getFunctionName(fileName); 14 //声明日志文件存储路径以及文件名、格式 15 final String logFilePath = "./result/logs/"+founctionName+"/"+fileName+".log"; 16 Properties prop = new Properties(); 17 //配置日志输出的格式 18 prop.setProperty("log4j.rootLogger","info, toConsole, toFile"); 19 prop.setProperty("log4j.appender.file.encoding","UTF-8" ); 20 prop.setProperty("log4j.appender.toConsole","org.apache.log4j.ConsoleAppender"); 21 prop.setProperty("log4j.appender.toConsole.Target","System.out"); 22 prop.setProperty("log4j.appender.toConsole.layout","org.apache.log4j.PatternLayout "); 23 prop.setProperty("log4j.appender.toConsole.layout.ConversionPattern","[%d{yyyy-MM-dd HH:mm:ss}] [%p] %m%n"); 24 prop.setProperty("log4j.appender.toFile", "org.apache.log4j.DailyRollingFileAppender"); 25 prop.setProperty("log4j.appender.toFile.file", logFilePath); 26 prop.setProperty("log4j.appender.toFile.append", "false"); 27 prop.setProperty("log4j.appender.toFile.Threshold", "info"); 28 prop.setProperty("log4j.appender.toFile.layout", "org.apache.log4j.PatternLayout"); 29 prop.setProperty("log4j.appender.toFile.layout.ConversionPattern", "[%d{yyyy-MM-dd HH:mm:ss}] [%p] %m%n"); 30 //使配置生效 31 PropertyConfigurator.configure(prop); 32 33 } 34 35 36 /**取得模块名字*/ 37 public static String getFunctionName(String fileName){ 38 String functionName = null; 39 int firstUndelineIndex = fileName.indexOf("_"); 40 functionName = fileName.substring(0, firstUndelineIndex-4); 41 return functionName; 42 43 } 44 45 46 }
4.因为我们要处理android和ios的项目,更方便处理兼容,在Utils中创建一个SelectDriver类,代码如下:
1 package com.young.appiumcombat.utils; 2 import java.io.File; 3 import java.util.concurrent.TimeUnit; 4 5 import org.apache.log4j.Logger; 6 import org.openqa.selenium.WebElement; 7 import org.openqa.selenium.remote.DesiredCapabilities; 8 import org.testng.Assert; 9 import org.testng.ITestContext; 10 11 import io.appium.java_client.AppiumDriver; 12 /** 13 * @author Young 14 * @description 根据测试平台的不同生成不同的driver 比如AndroidDriver 或者是IOSDriver 15 * 16 * */ 17 18 public class SelectDriver { 19 //声明driver 20 public AppiumDriver<WebElement> driver; 21 //声明DesiredCapabilities 22 public DesiredCapabilities capabilities; 23 //声明ITestContext,用于获取testng配置文件内容 24 public ITestContext testContext; 25 //appium server地址 26 public String serverURL; 27 //测试引擎名字 28 public String automationName; 29 //测试平台名字 30 public String platformName; 31 //测试平台版本号 32 public String platformVersion; 33 //设备名字 34 public String deviceName; 35 //ios app的路径 36 public String iosAppPath; 37 //android app路径 38 public String androidAppPath; 39 //android app的 package 40 public String appPackage; 41 //android app的activity 42 public String appActivity; 43 //安卓独有 - 是否使用unicode键盘,使用此键盘可以输入中文字符 44 public boolean unicodeKeyboard; 45 //android独有 - 是否重置键盘,如果设置了unicodeKeyboard键盘,可以将此参数设置为true,然后键盘会重置为系统默认的 46 public boolean resetKeyboard; 47 //是否覆盖已有的seesssion,这个用于多用例执行,如果不设置的话,会提示前一个session还没有结束,用例就不能继续执行了 48 public boolean sessionOverride; 49 //暂停的等待时间 50 public int sleepTime; 51 //元素等待超时时间 52 public int elementTimeOut; 53 //app文件路径,主要存储的是app的名字 54 public String appFilePath; 55 //webview的名字或者叫标识符,一般以WEBVIEW开头,例如WEBVIEW_com.microsoft.bing 56 public final static String WEBVIEW_NAME = null; 57 //原生app的名字或者标识符,一般是NATIVE_APP 58 public final static String NATIVEAPP_NAME = null; 59 //实例化本类的日志输出对象 60 public static Logger logger = Logger.getLogger(SelectDriver.class); 61 62 public AppiumDriver<WebElement> selectDriver(ITestContext context,AppiumUtil appiumUtil){ 63 //通过testng的xml文件获取serverURL参数值,并赋给 serverURL变量 64 serverURL = context.getCurrentXmlTest().getParameter("serverURL"); 65 //通过testng的xml文件获取automationName参数值,并赋给 automationName变量 66 automationName = context.getCurrentXmlTest().getParameter("automationName"); 67 //通过testng的xml文件获取platformName参数值,并赋给 platformName变量 68 platformName = context.getCurrentXmlTest().getParameter("platformName"); 69 //通过testng的xml文件获取platformVersion参数值,并赋给 platformVersion变量 70 platformVersion = context.getCurrentXmlTest().getParameter("platformVersion"); 71 //通过testng的xml文件获取deviceName参数值,并赋给 deviceName变量 72 deviceName = context.getCurrentXmlTest().getParameter("deviceName"); 73 //通过testng的xml文件获取androidAppPath参数值,并赋给 androidAppPath变量 74 androidAppPath = context.getCurrentXmlTest().getParameter("androidAppPath"); 75 //通过testng的xml文件获取iosAppPath参数值,并赋给 iosAppPath变量 76 iosAppPath = context.getCurrentXmlTest().getParameter("iosAppPath"); 77 //通过testng的xml文件获取appPackage参数值,并赋给 appPackage变量 78 appPackage = context.getCurrentXmlTest().getParameter("appPackage"); 79 //通过testng的xml文件获取appActivity参数值,并赋给 appActivity变量 80 appActivity = context.getCurrentXmlTest().getParameter("appActivity"); 81 //通过testng的xml文件获取unicodeKeyboard参数值,并赋给 unicodeKeyboard变量 82 unicodeKeyboard = Boolean.parseBoolean(context.getCurrentXmlTest().getParameter("unicodeKeyboard")); 83 //通过testng的xml文件获取resetKeyboard参数值,并赋给 resetKeyboard变量 84 resetKeyboard = Boolean.parseBoolean(context.getCurrentXmlTest().getParameter("resetKeyboard")); 85 //通过testng的xml文件获取sessionOverride参数值,并赋给 sessionOverride变量 86 sessionOverride = Boolean.parseBoolean(context.getCurrentXmlTest().getParameter("sessionOverride")); 87 //通过testng的xml文件获取sleepTime参数值,并赋给 sleepTime变量 88 sleepTime = Integer.valueOf(context.getCurrentXmlTest().getParameter("sleepTime")); 89 //通过testng的xml文件获取elementTimeOut参数值,并赋给 elementTimeOut变量 90 elementTimeOut = Integer.valueOf(context.getCurrentXmlTest().getParameter("elementTimeOut")); 91 //通过testng的xml文件获取appFilePath参数值,并赋给 appFilePath变量 92 appFilePath = context.getCurrentXmlTest().getParameter("appFilePath"); 93 this.testContext = context; 94 capabilities = new DesiredCapabilities(); 95 //告诉测试程序,当前项目目录在哪里 96 File classpathRoot = new File(System.getProperty("user.dir")); 97 //设置capability,以便和appium创建session 98 capabilities.setCapability("platformName",platformName); 99 capabilities.setCapability("platformVersion",platformVersion); 100 capabilities.setCapability("deviceName",deviceName); 101 capabilities.setCapability("sessionOverride", sessionOverride); 102 //如果测试平台是android的话,执行下面这个if语句内容 103 if(platformName.equalsIgnoreCase("android")){ 104 /** 105 * 设置和android 测试相关的capability并实例化driver对象 106 * */ 107 File app = new File(classpathRoot, androidAppPath); 108 capabilities.setCapability("app", app.getAbsolutePath()); 109 capabilities.setCapability("unicodeKeyboard", unicodeKeyboard); 110 capabilities.setCapability("resetKeyboard", resetKeyboard); 111 capabilities.setCapability("automationName",automationName); 112 capabilities.setCapability("appPackage", appPackage); 113 capabilities.setCapability("appActivity", appActivity); 114 driver = appiumUtil.getDriver(serverURL, capabilities,platformName); 115 testContext.setAttribute("APPIUM_DRIVER", driver); 116 logger.info(PropertiesDataProvider.getTestData(appFilePath, appPackage)+"已经启动"); 117 driver.manage().timeouts().implicitlyWait(elementTimeOut, TimeUnit.SECONDS); 118 return driver; 119 120 //如果测试平台是ios的话,执行下面这个if语句内容 121 }else if(platformName.equalsIgnoreCase("ios")){ 122 /** 123 * 设置和ios 测试相关的capability并实例化driver对象 124 * */ 125 File app = new File(classpathRoot, iosAppPath); 126 capabilities.setCapability("app", app.getAbsolutePath()); 127 //ios设置自动接收系统alert,注意IOS弹出的alert,APPIUM可以自动处理掉,支持ios8以上系统 128 capabilities.setCapability("autoAcceptAlerts", true); 129 driver = appiumUtil.getDriver(serverURL, capabilities,platformName); 130 testContext.setAttribute("APPIUM_DRIVER", driver); 131 driver.manage().timeouts().implicitlyWait(elementTimeOut,TimeUnit.SECONDS); 132 133 }else{ 134 logger.error("初始化driver失败"); 135 Assert.fail("初始化driver失败"); 136 } 137 138 //最后返回dirver对象 139 return driver; 140 141 142 } 143 144 145 }
5.有时候我们不想把太多的配置放到testng.xml中,我们就需要根据key读取属性文件里面的value值,现在res/下创建properties,里面有app.properties 和config.properties 两个文本,然后在utils下写一个方法获取value的值,类为:PropertiesDataProvider,代码如下:
1 package com.young.appiumcombat.utils; 2 3 import org.apache.commons.configuration.Configuration; 4 import org.apache.commons.configuration.ConfigurationException; 5 import org.apache.commons.configuration.PropertiesConfiguration; 6 7 /** 8 * @author young 9 * @Desription 从.properties文件中读取相关测试数据<br> 10 * 11 * */ 12 public class PropertiesDataProvider { 13 14 public static String getTestData(String configFilePath, String key) { 15 Configuration config = null; 16 try { 17 config = new PropertiesConfiguration(configFilePath); 18 } catch (ConfigurationException e) { 19 e.printStackTrace(); 20 } 21 return String.valueOf(config.getProperty(key)); 22 23 } 24 }
6.html报告插件
哈,我们使用 http://www.cnblogs.com/sunny-sl/p/7451582.html这里的arrow的报告插件,在将CONFIGFILE值修改成res/properties目录下的 config.properties,代码如下:
1 retrycount=0 2 sourcecodedir=com/young/appiumcombat/testcases 3 sourcecodeencoding=UTF-8