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. /**获取文本2*/
  207. public String getText(String locateWay,String locateValue){
  208. String str="";
  209. switch(locateWay){
  210.  
  211. case "AccessibilityId":
  212. str = driver.findElementByAccessibilityId(locateValue).getText().trim();
  213. break;
  214. // case "AndroidUIAutomator":
  215. // str = driver.findElementByAndroidUIAutomator(locateValue).getText().trim();
  216. // break;
  217. case "ClassName":
  218. str = driver.findElementByClassName(locateValue).getText().trim();
  219. break;
  220. case "CSS":
  221. str = driver.findElementByCssSelector(locateValue).getText().trim();
  222. break;
  223. case "ID":
  224. str = driver.findElementById(locateValue).getText().trim();
  225. break;
  226. case "LinkText":
  227. str = driver.findElementByLinkText(locateValue).getText().trim();
  228. break;
  229. case "Name":
  230. str = driver.findElementByName(locateValue).getText().trim();
  231. break;
  232. case "PartialLinkText":
  233. str = driver.findElementByPartialLinkText(locateValue).getText().trim();
  234. break;
  235. case "TagName":
  236. str = driver.findElementByTagName(locateValue).getText().trim();
  237. break;
  238. case "Xpath":
  239. str = driver.findElementByXPath(locateValue).getText().trim();
  240. break;
  241. default:
  242. logger.error("定位方式:"+locateWay+"不被支持");
  243. Assert.fail("定位方式:"+locateWay+"不被支持");
  244.  
  245. }
  246. return str;
  247.  
  248. }
  249.  
  250. /**提交*/
  251. public void submit(By by){
  252. WebElement element=findElement(by);
  253. try{
  254. element.submit();
  255. }catch(Exception e){
  256. logger.error("在元素:"+getLocatorByElement(element, ">")+"做的提交操作失败",e);
  257. Assert.fail("在元素:"+getLocatorByElement(element, ">")+"做的提交操作失败",e);
  258. }
  259. logger.info("在元素:"+getLocatorByElement(element, ">")+"做了提交操作");
  260. }
  261.  
  262. /**
  263. * 获得webview页面的标题
  264. * */
  265. public String getTitle() {
  266. return driver.getTitle();
  267. }
  268.  
  269. /**
  270. * 获得元素 属性的文本
  271. * */
  272. public String getAttributeText(By elementLocator, String attribute) {
  273. return findElement(elementLocator).getAttribute(attribute).trim();
  274. }
  275.  
  276. /**
  277. * 在给定的时间内去查找元素,如果没找到则超时,抛出异常
  278. * */
  279. public void waitForElementToLoad(int elementTimeOut, final By By) {
  280. logger.info("开始查找元素[" + By + "]");
  281. try {
  282. (new WebDriverWait(driver, elementTimeOut)).until(new ExpectedCondition<Boolean>() {
  283.  
  284. public Boolean apply(WebDriver driver) {
  285. WebElement element = driver.findElement(By);
  286. return element.isDisplayed();
  287. }
  288. });
  289. } catch (TimeoutException e) {
  290. logger.error("超时!! " + elementTimeOut + " 秒之后还没找到元素 [" + By + "]");
  291. Assert.fail("超时!! " + elementTimeOut + " 秒之后还没找到元素 [" + By + "]");
  292.  
  293. }
  294. logger.info("找到了元素 [" + By + "]");
  295. }
  296.  
  297. /**
  298. * 判断文本是不是和需求要求的文本一致
  299. * **/
  300. public void isTextCorrect(String actual, String expected) {
  301. try {
  302. Assert.assertEquals(actual, expected);
  303. } catch (AssertionError e) {
  304. logger.error("期望的文字是 [" + expected + "] 但是找到了 [" + actual + "]");
  305. Assert.fail("期望的文字是 [" + expected + "] 但是找到了 [" + actual + "]");
  306.  
  307. }
  308. logger.info("找到了期望的文字: [" + expected + "]");
  309.  
  310. }
  311.  
  312. /**
  313. * 暂停当前用例的执行,暂停的时间为:sleepTime
  314. * */
  315. public void pause(int sleepTime) {
  316. if (sleepTime <= 0) {
  317. return;
  318. }
  319. try {
  320. TimeUnit.SECONDS.sleep(sleepTime);
  321. logger.info("暂停:"+sleepTime+"秒");
  322. } catch (InterruptedException e) {
  323. e.printStackTrace();
  324. }
  325.  
  326. }
  327.  
  328. /** 根据元素来获取此元素的定位值 */
  329. public String getLocatorByElement(WebElement element, String expectText) {
  330. String text = element.toString();
  331. String expect = null;
  332. try {
  333. expect = text.substring(text.indexOf(expectText) + 1, text.length() - 1);
  334. } catch (Exception e) {
  335. e.printStackTrace();
  336. logger.error("failed to find the string [" + expectText + "]");
  337.  
  338. }
  339.  
  340. return expect;
  341.  
  342. }
  343.  
  344. /**
  345. * 判断实际文本时候包含期望文本
  346. *
  347. * @param actual
  348. * 实际文本
  349. * @param expect
  350. * 期望文本
  351. */
  352. public void isContains(String actual, String expect) {
  353. try {
  354. Assert.assertTrue(actual.contains(expect));
  355. } catch (AssertionError e) {
  356. logger.error("The [" + actual + "] is not contains [" + expect + "]");
  357. Assert.fail("The [" + actual + "] is not contains [" + expect + "]");
  358. }
  359. logger.info("The [" + actual + "] is contains [" + expect + "]");
  360. }
  361.  
  362. /**跳转到webview页面*/
  363. public void switchWebview(int index){
  364. Set<String> contexts = driver.getContextHandles();
  365. for (String context : contexts) {
  366. System.out.println(context);
  367. //打印出来看看有哪些context
  368. }
  369. driver.context((String) contexts.toArray()[index]);
  370.  
  371. }
  372.  
  373. /**跳转到webview页面*/
  374. public void switchWebview(String contextName){
  375. try{
  376. Set<String> contexts = driver.getContextHandles();
  377. for (String context : contexts) {
  378. System.out.println(context);
  379. //打印出来看看有哪些context
  380. }
  381. driver.context(contextName);
  382. }catch(NoSuchContextException nce){
  383. logger.error("没有这个context:"+contextName, nce);
  384. Assert.fail("没有这个context:"+contextName, nce);
  385. }
  386.  
  387. }
  388.  
  389. /**
  390. * 执行JavaScript 方法
  391. * */
  392. public void executeJS(String js) {
  393. ((JavascriptExecutor) driver).executeScript(js);
  394. logger.info("执行JavaScript语句:[" + js + "]");
  395. }
  396.  
  397. /**
  398. * 执行JavaScript 方法和对象
  399. * 用法:seleniumUtil.executeJS("arguments[0].click();", seleniumUtil.findElementBy(MyOrdersPage.MOP_TAB_ORDERCLOSE));
  400. * */
  401. public void executeJS(String js, Object... args) {
  402. ((JavascriptExecutor) driver).executeScript(js, args);
  403. logger.info("执行JavaScript语句:[" + js + "]");
  404. }
  405.  
  406. /**检查元素是不是存在*/
  407. public boolean doesElementsExist(By byElement){
  408. try{
  409. findElement(byElement);
  410. return true;
  411. }catch(NoSuchElementException nee){
  412.  
  413. return false;
  414. }
  415.  
  416. }
  417.  
  418. /**长按操作*/
  419. public void longPress(By by){
  420. TouchAction tAction=new TouchAction(driver);
  421. tAction.longPress(findElement(by)).perform();
  422. }
  423.  
  424. /**滑动*/
  425. public void swipe(int beginX,int beginY,int endX,int endY){
  426. TouchAction tAction=new TouchAction(driver);
  427. try{
  428. tAction.press(beginX,beginY).moveTo(endX,endY).release().perform();
  429. }catch(Exception e){
  430. e.printStackTrace();
  431. }
  432. }
  433.  
  434. /**滚动 - 根据文本模糊匹配*/
  435. public void scroll(String text){
  436. driver.scrollTo(text);
  437. }
  438.  
  439. /**滚动 - 根据文本精准匹配*/
  440. public WebElement scrollExact(String text){
  441. return driver.scrollToExact(text);
  442. }
  443.  
  444. /**拖拽操作*/
  445. public void DragAndDrop(By dragElement,By dropElement){
  446. TouchAction act=new TouchAction(driver);
  447. act.press(findElement(dragElement)).perform();
  448. act.moveTo(findElement(dropElement)).release().perform();
  449. }
  450.  
  451. /**放大和缩小*/
  452. public void zoomAndPinch(int beginX,int beginY,int endX,int endY){
  453. int scrHeight = driver.manage().window().getSize().getHeight();
  454. int scrWidth = driver.manage().window().getSize().getWidth();
  455. MultiTouchAction multiTouch = new MultiTouchAction(driver);
  456. TouchAction tAction0 = new TouchAction(driver);
  457. TouchAction tAction1 = new TouchAction(driver);
  458. tAction0.press(scrWidth/2,scrHeight/2).waitAction(1000).moveTo(beginX,beginY).release();
  459. tAction1.press(scrWidth/2,scrHeight/2+40).waitAction(1000).moveTo(endX,endY).release();
  460. multiTouch.add(tAction0).add(tAction1);
  461. multiTouch.perform();
  462.  
  463. }
  464.  
  465. /**app置于后台运行*/
  466. public void runBackgound(int runTimes){
  467. driver.runAppInBackground(runTimes);
  468.  
  469. }
  470.  
  471. /**收起键盘*/
  472. public void hideKeyboard(){
  473. driver.hideKeyboard();
  474. logger.info("虚拟键盘已经收起");
  475.  
  476. }
  477.  
  478. /**安装app*/
  479. public void instalApp(String appPath){
  480. try{
  481. driver.installApp(appPath);
  482. }catch(Exception e){
  483. logger.error("app安装失败",e);
  484. Assert.fail("app安装失败",e);
  485. }
  486. }
  487.  
  488. /**app是否安装*/
  489. public boolean isAppInstalled(String appPackage){
  490.  
  491. if(driver.isAppInstalled(appPackage)){
  492. logger.info(appPackage+":已经安装");
  493. return true;
  494. }else {
  495. logger.info(appPackage+":未安装");
  496. return false;
  497. }
  498. }
  499.  
  500. /**页面过长时候滑动页面 window.scrollTo(左边距,上边距); */
  501. public void scrollPage(int x,int y){
  502. String js ="window.scrollTo("+x+","+y+");";
  503. ((JavascriptExecutor)driver).executeScript(js);
  504. }
  505.  
  506. }

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. public static String getFunctionName(String fileName){
  37. String functionName = null;
  38. int firstUndelineIndex = fileName.indexOf("_");
  39. functionName = fileName.substring(0, firstUndelineIndex-4);
  40. return functionName;
  41.  
  42. }
  43.  
  44. }

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. }

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

Appium自动化测试框架的更多相关文章

  1. Appium+python自动化(三十八) - Appium自动化测试框架综合实践 - 框架简介-助你冲击高薪,迎娶白富美(超详解)

    简介 好久没有更新博客了,博友们是不是有点等不及了.不好意思啊,中秋节过后太忙了,这篇是好不容易抽点零碎时间写的.从这一篇开始小伙伴或者童鞋们,就跟随宏哥的脚步,一步步的从无到有,从0到1的搭建一个完 ...

  2. Appium+python自动化(三十九)-Appium自动化测试框架综合实践 - 代码实现(超详解)

    简介 经过一段时间的准备,完善的差不多了,继续分享有关Appium自动化测试框架综合实践.想必小伙伴们有点等不及了吧! driver配置封装 kyb_caps.yaml 配置表 参考代码 platfo ...

  3. Appium+python自动化(四十)-Appium自动化测试框架综合实践 - 代码实现(超详解)

    1.简介 今天我们紧接着上一篇继续分享Appium自动化测试框架综合实践 - 代码实现.由于时间的关系,宏哥这里用代码给小伙伴演示两个模块:注册和登录. 2.业务模块封装 因为现在各种APP的层出不群 ...

  4. Appium+python自动化(四十一)-Appium自动化测试框架综合实践 - 即将落下帷幕(超详解)

    1.简介 今天我们紧接着上一篇继续分享Appium自动化测试框架综合实践 - 代码实现.到今天为止,大功即将告成:框架所需要的代码实现都基本完成. 2.data数据封装 2.1使用背景 在实际项目过程 ...

  5. Appium+python自动化(四十二)-Appium自动化测试框架综合实践- 寿终正寝完结篇(超详解)

    1.简介 按照上一篇的计划,今天给小伙伴们分享执行测试用例,生成测试报告,以及自动化平台.今天这篇分享讲解完.Appium自动化测试框架就要告一段落了. 2.执行测试用例&报告生成 测试报告, ...

  6. 『与善仁』Appium基础 — 8、Appium自动化测试框架介绍

    目录 1.主流的移动端自动化测试框架 (1)Robotium (2)Macaca (3)Appium 2.自动化测试工具的选择 3.Appium简介 提示:我们前面说的Android环境搭建和adb命 ...

  7. Appium 自动化测试框架:关键字驱动+数据驱动

    1. 关键字驱动框架简介 2. 框架结构说明 3. 框架代码实现 action 包  page_action.py business_process 包 case_process.py data_so ...

  8. 基于C#的Appium自动化测试框架(Ⅰ)

    因为工作原因,使用的编程语言都是C#,但是国内相应的Appium资料少得可怜,Java版本的Appium也考虑过,但是奈何自己搞不定Eclipse这个编译环境[说白了就是因为懒-- 无意中看到了外面的 ...

  9. 基于C#的Appium自动化测试框架(Ⅰ):程序结构

    因为工作原因,使用的编程语言都是C#,但是国内相应的Appium资料少得可怜,Java版本的Appium也考虑过,但是奈何自己搞不定Eclipse这个编译环境[说白了就是因为懒…… 无意中看到了外面的 ...

  10. Windows系统下搭建Appium自动化测试框架

    简介 一种开源的测试框架(http://appium.io/) 能够用来测试原生Android/iOS应用.混合应用以及webapp 通过webdriver协议来操作应用,其核心是一个web服务器,接 ...

随机推荐

  1. CF 1065 E. Side Transmutations

    E. Side Transmutations http://codeforces.com/contest/1065/problem/E 题意: 长度为n的字符串,字符集为A,问多少不同的字符串.两个字 ...

  2. AngularJS中Directive指令系列

    近段时间在研究Angular中的directive用法,打算写个系列.以官方文档为主.并参考诸多教程.加上自己的思考. 基本概念及用法 scope属性的使用.  &, <, =, @ 符 ...

  3. Unity LineRenderer制作画版

    Source: using System.Collections; using System.Collections.Generic; using UnityEngine; public class ...

  4. ----------BMI指数小程序----------

    # 1.创建并输出菜单, 菜单是不可变的. 所以使用元组# menus = ("1, 录入", "2, 查询", "3, 删除", &quo ...

  5. 利用工厂模式实现serviec层和dao层解耦

    利用工厂模式实现serveice和dao层的解耦,这样就可以不用在service层实例化dao层的对象,当dao层代码发生改变的时候(数据库实现发生改变)直接修改配置文件就不用改变service层的代 ...

  6. 180725-InfluxDB-v1.6.0安装和简单使用小结

    InfluxDB安装和简单使用小结 InfluxDB是一个时序性数据库,因为工作需求,安装后使用测试下是否支持大数据下的业务场景 说明: 安装最新版本 v1.6.0 集群版本要收费,单机版本免费 内部 ...

  7. Selenide 阶段性总结介绍(UI自动化测试工具)

    今天给大家介绍一个比较新的UI自动化测试工具-- Selenide.确实是比较新的,国内应该还没有多少人用它.在百度和google上你只能搜到一个中文帖子简单介绍了一下.如果你想用这个工具,不可避免的 ...

  8. Appium+python HTML测试报告(2)——一份报告模板(转)

    (原文:https://www.cnblogs.com/fancy0158/p/10055003.html) 适用于python3: 下载地址: 英文:https://pan.baidu.com/s/ ...

  9. Ubuntu18.04重装指南

    Guide google chrome sougou 谷歌服务助手\(\rightarrow\)谷歌访问助手(谷歌应用商店)登录谷歌账号(cnyalitea@gmail.com)然后同步. \(\te ...

  10. Ubuntu—安装python的第三方包gevent

    今晚花很多时间, 使用 sudo pip3 install gevent 但是始终没有成功. 柳暗花明又一村 sudo apt-get install python3-gevent 搞定!!! 人生如 ...