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