移动端自动化测试 Appium 框架之数据驱动

发表于:2022-4-15 10:00

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:zuozewei    来源:稀土掘金

  背景
  自动化是为业务测试服务,如果数据与业务放在一起看起来不是专业,把数据与业务分离是完全必要的,这也是市场常见的数据驱动框架,今天咱们就聊一聊怎么搭建自己数据驱动框架。
  前置条件
  Appium 环境搭建成功,不会参考自动化工具之 Appium 入门文章,实在不会在参考网上怎么搭建。
  主要实现
  UI 自动化框架元素放文本存储、数据存储、代码直接存储等其实随便那个都行,只有自己用者方便就行,我工作中用文本文件存储,这样修改方便,脚本放 SVN/Git 管理就行,UI 自动元素操作基本常见的就是 ID/NAME/XPATH 等这几种,咱们写一个工具转换类即可。
  元素读取工具类
  /**
       * 移动端元素定位
       *
       * @return
       * @param: name
       */
      public By getLocatorApp(String name) {
          String locator = properties.getProperty(name.trim());
          String locatorType = locator.split(">>")[0].toLowerCase();
          String locatorValue = locator.split(">>")[1];
          if (locatorType != null && locatorType != null) {
              logger.info("获取元素key: " + name + "\t 获取的定位类型:" + locatorType + "\t 获取的定位表达式: " + locatorValue);
              // 根据 locatorType 的变量值内容判断,返回何种定位方式的 By 对象
              return getkeyVule(locatorType, locatorValue);
          } else {
              new RuntimeException("元素没有获取到!");
              return null;
          }
      }
      /**
       * 读取元素
       * @param locatorType
       * @param locatorValue
       * @return By
       */
      public By getkeyVule(String locatorType, String locatorValue) {
          if ("id".equals(locatorType.toLowerCase())) {
              return By.id(locatorValue);
          } else if ("name".equals(locatorType.toLowerCase())) {
              return By.name(locatorValue);
          } else if (("classname".equals(locatorType.toLowerCase())) || ("class".equals(locatorType.toLowerCase()))) {
              return By.className(locatorValue);
          } else if (("tagname".equals(locatorType.toLowerCase())) || ("tag".equals(locatorType.toLowerCase()))) {
              return By.className(locatorValue);
          } else if (("linktext".equals(locatorType.toLowerCase())) || ("link".equals(locatorType.toLowerCase()))) {
              return By.linkText(locatorValue);
          } else if ("partiallinktext".equals(locatorType.toLowerCase())) {
              return By.partialLinkText(locatorValue);
          } else if (("cssselector".equals(locatorType.toLowerCase())) || ("css".equals(locatorType.toLowerCase()))) {
              return By.cssSelector(locatorValue);
          } else if ("xpath".equals(locatorType.toLowerCase())) {
              return By.xpath(locatorValue);
          } else {
              return By.tagName(locatorValue);
          }
      }

  读取文件操作方法
      public GetByLocator(String filename) {
          properties = new Properties();
          try {
              FileInputStream in = new FileInputStream((sysProperty.getProperty("user.dir") + "/comsevenday/src/main/resources/uiElement/" + filename));
              this.properties.load(in);
              in.close();
          } catch (Exception e) {
              logger.info("找不到文件:" + filename);
              e.printStackTrace();
          }
      }

  编写元素存放位置:

  内容为:
  #\u70B9\u51FB\u9996\u9875
  clickCart=xpath>>//android.view.View[@content-desc='\u9996\u9875']

  编写测试类
      @Test
      public void ss() throws IOException {
          InputStream in = this.getClass().getResourceAsStream("/uielement/loginElement.properties");
          Properties properties = new Properties();
          properties.load(in);
          String to_shop_text1 = properties.getProperty("clickCart");
          System.out.println(to_shop_text1);
      }

  验证结果:

  元素等待查找工具类
  import io.appium.java_client.android.AndroidDriver;
  import io.appium.java_client.android.AndroidElement;
  import org.openqa.selenium.By;
  import org.openqa.selenium.support.ui.ExpectedConditions;
  import org.openqa.selenium.support.ui.WebDriverWait;
  import org.testng.Reporter;
  /**
   * @author 7DGroup
   * @Title: WaitUtil
   * @Description: 等待查找元素工具类
   * @date 2019/11/23 / 10:58
   */
  public class WaitUtil {
      public static void waitWebElement(AndroidDriver<AndroidElement> driver, By by, String name) {
          LogUtil.info("等待元素出现-->目前操步骤为:" + name);
          Reporter.log("目前操步骤为:" + name);
          WebDriverWait wait = new WebDriverWait(driver, 10);
          wait.until(ExpectedConditions.presenceOfElementLocated(by));
      }
  }

  元素定位类
  package appout.appcase.data;
  import appout.utils.GetByLocator;
  import appout.utils.LogUtil;
  import appout.utils.WaitUtil;
  import io.appium.java_client.android.AndroidDriver;
  import io.appium.java_client.android.AndroidElement;
  import org.openqa.selenium.By;
  import org.openqa.selenium.WebElement;
  import org.testng.Assert;
  import java.util.List;
  /**
   * @author 7DGroup
   * @Title: CartProvider
   * @Description: this is
   * @date 2019/11/23 / 10:57
   */
  public class CartProvider {
      private GetByLocator getByLocator;
      private WebElement element = null;
      /**
       * 构造函数
       */
      public CartProvider() {
          this.getByLocator = new GetByLocator("loginElement.properties");
      }
      /**
       * 点击首页
       */
      public void clickHome(AndroidDriver<AndroidElement> driver) {
          WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("clickCart"), "点击首页");
          element = driver.findElement(getByLocator.getLocatorApp("clickCart"));
          element.click();
      }
      /**
       * 点击百宝箱
       *
       * @param driver
       */
      public void clickbaibao(AndroidDriver<AndroidElement> driver) {
          WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("clickCart"), "百宝箱");
          String[] name = {"京东超市", "数码电器", "京东服饰", "京东生鲜"};
          for (int i = 0; i < name.length; i++) {
              element = driver.findElement(getByLocator.getLocatorApp("Jingdong_supermarket".replace("京东超市", name[i])));
              element.click();
              //断言
              assertTrue(driver, "assertTitile", name[i] + "跳转成功");
              //退回
              WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("home_back"), "退回");
              driver.findElement(getByLocator.getLocatorApp("home_back"));
          }
      }
      /**
       * 分类写法
       *
       * @param driver
       */
      public void categorylist(AndroidDriver<AndroidElement> driver) {
          WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("categorylist"), "遍历分类");
          //获取全部数据挨个遍历
          List<AndroidElement> categorylist = driver.findElements(getByLocator.getLocatorApp("categorylist"));
          for (int i = 0; i < categorylist.size(); i++) {
              String text = categorylist.get(i).getText();
              //输出遍历name
              LogUtil.info(text);
              categorylist.get(i).click();
          }
      }
      /**
       * 收藏
       *
       * @param driver
       */
      public void productdetail(AndroidDriver<AndroidElement> driver) {
          WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("productdetail"), "收藏");
          AndroidElement detail = driver.findElement(getByLocator.getLocatorApp("productdetail"));
          String attribute = detail.getAttribute("selected");
          if (attribute.equals(true)) {
              LogUtil.info("目前商品收藏,目前的属性为:" + attribute);
          } else {
              LogUtil.info("商品没有收藏,目前的属性为:" + attribute);
          }
      }
      /**
       * 统一判断是否通过
       *
       * @param driver 传driver
       * @param elemn  定元素
       * @param des    描述
       */
      public void assertTrue(AndroidDriver<AndroidElement> driver, String elemn, String des) {
          WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp(elemn), des);
          element = driver.findElement(getByLocator.getLocatorApp(elemn));
          String text = element.getText();
          if (text != null) {
              Assert.assertTrue(true, des + "验证成功");
          } else {
              //如果失败系统会自动截图
              Assert.fail("跳转失败");
          }
      }
  }
  //     Assert.assertTrue("", "验证跳转成功");
  //            driver.findElement(By.id(""))

  基础启动类
  package appout.appcase;
  import appout.base.DriverBase;
  import appout.utils.LogUtil;
  import io.appium.java_client.android.AndroidDriver;
  import io.appium.java_client.android.AndroidElement;
  import org.openqa.selenium.By;
  import org.testng.Reporter;
  import org.testng.annotations.BeforeClass;
  import org.testng.annotations.Parameters;
  import org.testng.annotations.Test;
  import java.util.concurrent.TimeUnit;
  /**
   * @author 7DGroup
   * @Title: LoginTest
   * @Description: 用例区域
   * @date 2019/11/21 / 10:06
   */
  public class BestRuner {
      static AndroidDriver<AndroidElement> driver;
      public static AndroidDriver<AndroidElement> getDriver() {
          return driver;
      }
      /**
       * 初始化运行类
       *
       * @param udid
       * @param port
       * @throws Exception
       */
      @BeforeClass
      @Parameters({"udid", "port"})
      public void BeforeClass(String udid, String port) {
          Reporter.log("步骤1:启动appium与应用", true);
          LogUtil.info("---这是设备ID号-->" + udid);
          LogUtil.info("--这是运行端口--->" + port);
          //通过路径获取包名与APP_ACTIVITY
          String apk = "com.jingdong.app.mall_70502.apk";
          driver = DriverBase.initDriver(port, udid, apk, true);
          driver.manage().timeouts().implicitlyWait(80, TimeUnit.SECONDS);
      }
      @Test(description = "初始化登录启动", testName = "进入首页", priority = 0)
      public void T001() {
          LogUtil.info("启动");
          driver.findElement(By.id("com.jingdong.app.mall:id/mj")).click();
      }
  }

  业务组合测试类
  package appout.appcase;
  import appout.appcase.data.CartProvider;
  import org.testng.annotations.Test;
  /**
   * @author 7DGroup
   * @Title: CartTest
   * @Description: 测试类 extends BestRuner
   * @date 2019/11/23 / 19:57
   */
  public class CartTest  {
      CartProvider cartProvider = new CartProvider();
      @Test(description = "点击首页百宝箱", testName = "点击百宝箱", priority = 1)
      public void T002() {
  //        cartProvider.clickHome(driver);
  //        cartProvider.clickbaibao(driver);
          System.out.println("调试");
      }
  }

  其他测试类集成,即可。
  总结
  项目虽然小但包含了数据怎么存放,怎么获取,怎么换回成 selenium 识别的类型。

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号