• 目录结构如下:
    (包含:驱动的基础配置、全局异常处理、异常截图、报告自动生成、app常用操作方法封装、常用工具类封装)

  • 各包分层关系
    basepage包负责存放app公共操作方法、AndroidDriver基础配置、testNG公共执行顺序BaseTest,对外暴露驱动等。

  • BaseApp类包含app操作有:封装By类型的点击操作和输入框输入数据操作、切换到下一个窗口操作、上下左右滑动操作、具体坐标点击操作、直接使用adb命令的操作、前进后退刷新的操作等,其它方法可自行封住。

  • 部分封装方法如下:

  1. /**
  2. * 通过元素定位拿到 Element 元素对象
  3. *
  4. * @param locator By 类型元素定位
  5. * @return 定位到的元素
  6. */
  7. public WebElement locateElement(AndroidDriver driver,By locator) {
  8. try {
  9. wait = new WebDriverWait(driver, 10);
  10. return wait.until(ExpectedConditions.presenceOfElementLocated(locator));
  11. }catch (NoSuchElementException | TimeoutException e) {
  12. System.out.println("================当前页面未捕获该元素,继续执行用例==================");
  13. }
  14. return null;
  15. }
  16. /**
  17. * 点击元素
  18. * @param locator By 类型元素定位,做弹框或元素异常后接着往下执行
  19. * @return 点击的元素
  20. */
  21. public WebElement clickButton(AndroidDriver driver,By locator) {
  22. try {
  23. long time1 = DateUtils.getCurrentMillisecond();
  24. MobileElement buttonElement = (MobileElement) locateElement(driver,locator);
  25. wait.until(ExpectedConditions.elementToBeClickable(locator));
  26. if (buttonElement.isEnabled()){
  27. buttonElement.click();
  28. log.info("该点击事件耗时时间(ms):"+(DateUtils.getCurrentMillisecond()-time1));
  29. return buttonElement;
  30. }
  31. } catch (NoSuchElementException | TimeoutException e) {
  32. System.out.println("================当前页面未捕获该元素,截图保留>>>>继续执行用例==================");
  33. ScreenshotUtil.snapshot(driver);
  34. }
  35. return null;
  36. // System.out.println("改点击事件耗时时间(ms):"+(DateUtils.getCurrentMillisecond()-time1));
  37. }
  38. /**
  39. * 输入框输入数据
  40. * @param locator By 类型元素定位
  41. * @param content 输入的内容,支持多内容,可以键盘输入
  42. * @return 输入框元素
  43. */
  44. public WebElement sendInput(AndroidDriver driver,By locator, CharSequence... content) {
  45. WebElement inputElement = locateElement(driver,locator);
  46. inputElement.clear();
  47. inputElement.sendKeys(content);
  48. return inputElement;
  49. }
  50. /*=====================通过动作滑动==================================*/
  51. /**
  52. *向上滑动操作
  53. */
  54. public void swipeToUp(AndroidDriver driver) {
  55. int width = driver.manage().window().getSize().width;
  56. int height = driver.manage().window().getSize().height;
  57. TouchAction action=new TouchAction(driver).press(PointOption.point(width/2, height*3/4)).waitAction(WaitOptions.waitOptions(duration))
  58. .moveTo(PointOption.point(width/2, height/4)).release();
  59. action.perform();
  60. }
  61. /**
  62. *向下滑动操作
  63. */
  64. public void swipeToDown(AndroidDriver driver) {
  65. int height = driver.manage().window().getSize().height;
  66. int width = driver.manage().window().getSize().width;
  67. TouchAction action=new TouchAction(driver).press(PointOption.point(width/2, height/4)).waitAction(WaitOptions.waitOptions(duration))
  68. .moveTo(PointOption.point(width/2, height*3/4)).release();
  69. action.perform();
  70. }
  71. /**
  72. *向左滑动操作
  73. */
  74. public void swipeToLeft(AndroidDriver driver) {
  75. int width = driver.manage().window().getSize().width;
  76. int height = driver.manage().window().getSize().height;
  77. TouchAction action=new TouchAction(driver).press(PointOption.point(width*3/4, height/2)).waitAction(WaitOptions.waitOptions(duration))
  78. .moveTo(PointOption.point(width/4,height/2)).release();
  79. action.perform();
  80. }
  81. /**
  82. *向右滑动操作
  83. */
  84. public void swipeToRight(AndroidDriver driver) {
  85. int width = driver.manage().window().getSize().width;
  86. int height = driver.manage().window().getSize().height;
  87. TouchAction action=new TouchAction(driver).press(PointOption.point(width / 4, height / 2)).waitAction(WaitOptions.waitOptions(duration))
  88. .moveTo(PointOption.point(width*3/4,height/2)).release();
  89. action.perform();
  90. }
  91. /*=====================通过具体坐标点击操作,appium&&adb两种方式==================================*/
  92. /**
  93. * 通过具体坐标点击
  94. */
  95. public void taptest(AndroidDriver driver,int x, int y){
  96. /**设置显示等待时间10s driver=baseAndroidDriver.getDriver(baseConfig)
  97. 特注:显示等待与隐式等待相对,显示等待必须在每一个需要等待的元素前面进行声明,如果在规定的时间内找到元素,则直接执行,即找到元素就执行相关操作
  98. */
  99. wait = new WebDriverWait(driver,5);
  100. //tap点击坐标,输入坐标,然后再release()释放坐标点,用perform()去执行一系列action操作
  101. action = new TouchAction(driver).tap(PointOption.point(x,y)).release().perform();
  102. }
  103. /**
  104. * 通过adb命令驱动被测设备
  105. */
  106. public void adbInput(AndroidDriver driver ,String input){
  107. try {
  108. Process process = Runtime.getRuntime().exec(input);
  109. wait = new WebDriverWait(driver,5);
  110. process.destroy();
  111. } catch (IOException e) {
  112. e.printStackTrace();
  113. }
  114. }
  • page包(通用PO模式):分为data数据包和element元素操作包,把定位元素和输入框数据统一放到data包中,元素的操作放到element包中。其中元素的操作数据来源于data包中。
    image.png

  • testcase包是根据业务流程编写用例步骤(后面的用例维护均在此包下)

  • resource包下可以放chromedriver驱动或者存放异常捕获的截图、测试报告自动生成index.html报告(由于使用springboot可以直接访问报告)另一种测试报告用的最多的是allure2,一个开源很好的报告模板allure2 的GitHub地址测试报告输出到allure-results包下。

  • allure2报告集成,win下需要先下载allure2的zip包GitHub官网下载地址allure2,下载zip包后需要配置下环境变量,用例执行完成后会生成allure-results文件夹,在当前文件夹下执行

  1. allure serve allure-results

即可自动打开web测试报告,如下:

模板流程说明
  • 1、先在testcase包内写测试用例流程,testcase包下的类需要继承BaseTest 来获取driver驱动
    eg:
  1. public class YynCases extends BaseTest {
  2. /**
  3. * 测试示例用例,继承BaseTest获取driver驱动
  4. * 操作层
  5. */
  6. EnterYynElemnt enterMiniElemnt = new EnterYynElemnt();
  7. public void getDriverCase(){
  8. System.out.println(driver);
  9. //点击弹框按钮
  10. enterMiniElemnt.popupClick(driver);
  11. }
  12. }
  • 2、创建page包下的element包中的元素操作类,即:EnterYynElemnt 类此包下的类需要继承BaseApp类来获取封装的公共操作方法。
  1. @Slf4j
  2. public class EnterYynElemnt extends BaseApp{
  3. /**
  4. * 继承BaseApp使用公共封装方法
  5. * */
  6. //点击弹框
  7. public void popupClick(AndroidDriver driver) {
  8. //使用封装By类型元素定位,且数据和元素分离
  9. log.info("点击弹框");
  10. clickButton( driver, PopupData.POPUP1);
  11. }
  12. }
  • 3、创建page包下的data包的定位数据或者是输入框数据,所有的元素定位和输入数据均在此包下维护。上面参数POPUP1通过id定位,PopupData类下的POPUP1数据如下:
  1. public class PopupData {
  2. //升级弹框
  3. public static final By POPUP1= By.id("com.tengyun.yyn:id/layout_confirm_cancel");
  4. //第二个弹框
  5. public static final By POPUP2 = By.id("com.tengyun.yyn:id/layout_activity_cancel");
  • 4、其中第二步使用的是BaseApp封装的公共类方法clickButton
  1. public WebElement clickButton(AndroidDriver driver,By locator) {
  2. try {
  3. long time1 = DateUtils.getCurrentMillisecond();
  4. MobileElement buttonElement = (MobileElement) locateElement(driver,locator);
  5. wait.until(ExpectedConditions.elementToBeClickable(locator));
  6. if (buttonElement.isEnabled()){
  7. buttonElement.click();
  8. log.info("该点击事件耗时时间(ms):"+(DateUtils.getCurrentMillisecond()-time1));
  9. return buttonElement;
  10. }
  11. } catch (NoSuchElementException | TimeoutException e) {
  12. System.out.println("================当前页面未捕获该元素,截图保留>>>>继续执行用例==================");
  13. ScreenshotUtil.snapshot(driver);
  14. }
  15. return null;
  16. // System.out.println("改点击事件耗时时间(ms):"+(DateUtils.getCurrentMillisecond()-time1));
  17. }

输入框输入数据方法也是很常用的

  1. public WebElement sendInput(AndroidDriver driver,By locator, CharSequence... content) {
  2. WebElement inputElement = locateElement(driver,locator);
  3. inputElement.clear();
  4. inputElement.sendKeys(content);
  5. return inputElement;
  6. }
  • 5、最后可以统一把testcase包下的类放到testNG的入口中执行测试并生成报告(由于使用springboot框架没有用testNG的xml配置,而是通过封装方法进行配置)
  1. /**
  2. * 测试用例总入口
  3. * */
  4. @Test
  5. public void runCases(){
  6. //执行测试用例入口
  7. BaseTestngInit baseTestngInit = new BaseTestngInit();
  8. baseTestngInit.baseTestngInitCode();
  9. }

testNG封装的工具类BaseTestngInit(工具类中也可以通过testng.xml初始化testng,具体看个人使用习惯)

  1. /**
  2. * 初始化testng
  3. */
  4. public void baseTestngInitCode() {
  5. //创建testng对象
  6. TestNG testng = new TestNG();
  7. //创建报告监听器对象
  8. ExtentTestNGIReporterListener reportListener = new ExtentTestNGIReporterListener();
  9. // TestLogListener testLogListener = new TestLogListener();
  10. //设置需要执行的测试用例类
  11. testng.setTestClasses(new Class[] { com.iappium.testcase.YynCases.class});
  12. //添加监听器
  13. testng.addListener(reportListener);
  14. // testng.addListener(testLogListener);
  15. //运行测试
  16. testng.run();
  17. }

点击可获取该项目源码地址

更多测试技术分享、学习资源以及一些其他福利可关注公众号:【Coding测试】获取:
Coding测试

版权声明:本文为CodingTest原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/CodingTest/p/13744480.html