自动化工具之Appium框架之数据驱动

  • 2019 年 11 月 27 日
  • 筆記

背景

自动化是为业务测试服务,如果数据与业务放在一起看起来不是很规整与整洁,是否可以把数据与业务分离,是完全可以的,这也是市场常见的数据驱动框架,今天咱们就聊一聊怎么搭建自己数据驱动框架;

前置条件

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);          }      }

读取文件操作方法

private Properties properties = null;      static Properties sysProperty = System.getProperties();        public GetByLocator() {      }        public GetByLocator(String filename) {          properties = new Properties();          try {              FileInputStream in = new FileInputStream((sysProperty.getProperty("user.dir") + "/src/main/resources/uiElement/" + filename));              this.properties.load(in);              in.close();          } catch (Exception e) {              logger.info("找不到文件:" + filename);              e.printStackTrace();          }      }

编写元素存放位置:

内容为:

#点击我的  clickCart=xpath>>//android.widget.ImageView[@content-desc='我的']

编写测试类

验证结果:

元素等待查找工具类

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 liwen   * @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));      }  }

元素定位类

import com.thappium.util.GetByLocator;  import com.thappium.util.WaitUtil;  import io.appium.java_client.android.AndroidDriver;  import io.appium.java_client.android.AndroidElement;  import org.openqa.selenium.WebElement;    /**   * @author liwen   * @Title: CartProvider   * @Description: 购物车测试类   * @date 2019/11/23 / 15:12   */  public class CartProvider {        private GetByLocator getByLocator;      private WebElement element = null;        /**       * 构造函数       */      public CartProvider() {          this.getByLocator = new GetByLocator("loginElement.properties");      }        /**       * 点击购物车       */      public void clickCart(AndroidDriver<AndroidElement> driver) {          WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("clickCart"), "点击购物车");          element = driver.findElement(getByLocator.getLocatorApp("clickCart"));          element.click();      }  }

基础启动类,其他测试类集成,即可

/**   * @author liwen   * @Title: BestRuner   * @Description:   * @date 2019/11/23 / 10:07   */  @Log4j  public class BestRuner {    public static AndroidDriver<AndroidElement> getDriver() {      return driver;  }         static AndroidDriver<AndroidElement> 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 = "pinduoduov4.76.0_downcc.com.apk";          driver = DriverBase.initDriver(port, udid, apk, true);          driver.manage().timeouts().implicitlyWait(80, TimeUnit.SECONDS);      }    }

业务组合测试类

/**   * @author liwen   * @Title: CartTest   * @Description:  测试类   * @date 2019/11/23 / 11:26   */  public class CartTest extends BestRuner {        CartProvider car = new CartProvider();        /**       * 点击购物车       */      @Test(description = "点击购物车", testName = "购物车模块Dome")      public void getopent() {          car.clickCart(driver);        }    }

源码位置:

https://github.com/357712148/bodygit.git

总结

项目虽然小但包含了数据怎么存放,怎么获取,怎么换回成selenium识别的类型。