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

x33g5p2x  于2021-10-20 转载在 其他  
字(8.3k)|赞(0)|评价(0)|浏览(637)

背景

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

前置条件

Appium 环境搭建成功,不会参考自动化工具之 Appium 入门文章,实在不会在参考网上怎么搭建。

  • 移动端自动化测试工具 Appium 快速入门

主要实现

UI 自动化框架元素放文本存储、数据存储、代码直接存储等其实随便那个都行,只有自己用者方便就行,我工作中用文本文件存储,这样修改方便,脚本放 SVN/Git 管理就行,UI 自动元素操作基本常见的就是 ID/NAME/XPATH 等这几种,咱们写一个工具转换类即可。

元素读取工具类

  1. /** * 移动端元素定位 * * @return * @param: name */
  2. public By getLocatorApp(String name) {
  3. String locator = properties.getProperty(name.trim());
  4. String locatorType = locator.split(">>")[0].toLowerCase();
  5. String locatorValue = locator.split(">>")[1];
  6. if (locatorType != null && locatorType != null) {
  7. logger.info("获取元素key: " + name + "\t 获取的定位类型:" + locatorType + "\t 获取的定位表达式: " + locatorValue);
  8. // 根据 locatorType 的变量值内容判断,返回何种定位方式的 By 对象
  9. return getkeyVule(locatorType, locatorValue);
  10. } else {
  11. new RuntimeException("元素没有获取到!");
  12. return null;
  13. }
  14. }
  15. /** * 读取元素 * @param locatorType * @param locatorValue * @return By */
  16. public By getkeyVule(String locatorType, String locatorValue) {
  17. if ("id".equals(locatorType.toLowerCase())) {
  18. return By.id(locatorValue);
  19. } else if ("name".equals(locatorType.toLowerCase())) {
  20. return By.name(locatorValue);
  21. } else if (("classname".equals(locatorType.toLowerCase())) || ("class".equals(locatorType.toLowerCase()))) {
  22. return By.className(locatorValue);
  23. } else if (("tagname".equals(locatorType.toLowerCase())) || ("tag".equals(locatorType.toLowerCase()))) {
  24. return By.className(locatorValue);
  25. } else if (("linktext".equals(locatorType.toLowerCase())) || ("link".equals(locatorType.toLowerCase()))) {
  26. return By.linkText(locatorValue);
  27. } else if ("partiallinktext".equals(locatorType.toLowerCase())) {
  28. return By.partialLinkText(locatorValue);
  29. } else if (("cssselector".equals(locatorType.toLowerCase())) || ("css".equals(locatorType.toLowerCase()))) {
  30. return By.cssSelector(locatorValue);
  31. } else if ("xpath".equals(locatorType.toLowerCase())) {
  32. return By.xpath(locatorValue);
  33. } else {
  34. return By.tagName(locatorValue);
  35. }
  36. }

读取文件操作方法

  1. public GetByLocator(String filename) {
  2. properties = new Properties();
  3. try {
  4. FileInputStream in = new FileInputStream((sysProperty.getProperty("user.dir") + "/comsevenday/src/main/resources/uiElement/" + filename));
  5. this.properties.load(in);
  6. in.close();
  7. } catch (Exception e) {
  8. logger.info("找不到文件:" + filename);
  9. e.printStackTrace();
  10. }
  11. }

编写元素存放位置:

内容为:

  1. #\u70B9\u51FB\u9996\u9875
  2. clickCart=xpath>>//android.view.View[@content-desc='\u9996\u9875']

编写测试类

  1. @Test
  2. public void ss() throws IOException {
  3. InputStream in = this.getClass().getResourceAsStream("/uielement/loginElement.properties");
  4. Properties properties = new Properties();
  5. properties.load(in);
  6. String to_shop_text1 = properties.getProperty("clickCart");
  7. System.out.println(to_shop_text1);
  8. }

验证结果:

元素等待查找工具类

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

元素定位类

  1. package appout.appcase.data;
  2. import appout.utils.GetByLocator;
  3. import appout.utils.LogUtil;
  4. import appout.utils.WaitUtil;
  5. import io.appium.java_client.android.AndroidDriver;
  6. import io.appium.java_client.android.AndroidElement;
  7. import org.openqa.selenium.By;
  8. import org.openqa.selenium.WebElement;
  9. import org.testng.Assert;
  10. import java.util.List;
  11. /** * @author 7DGroup * @Title: CartProvider * @Description: this is * @date 2019/11/23 / 10:57 */
  12. public class CartProvider {
  13. private GetByLocator getByLocator;
  14. private WebElement element = null;
  15. /** * 构造函数 */
  16. public CartProvider() {
  17. this.getByLocator = new GetByLocator("loginElement.properties");
  18. }
  19. /** * 点击首页 */
  20. public void clickHome(AndroidDriver<AndroidElement> driver) {
  21. WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("clickCart"), "点击首页");
  22. element = driver.findElement(getByLocator.getLocatorApp("clickCart"));
  23. element.click();
  24. }
  25. /** * 点击百宝箱 * * @param driver */
  26. public void clickbaibao(AndroidDriver<AndroidElement> driver) {
  27. WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("clickCart"), "百宝箱");
  28. String[] name = {"京东超市", "数码电器", "京东服饰", "京东生鲜"};
  29. for (int i = 0; i < name.length; i++) {
  30. element = driver.findElement(getByLocator.getLocatorApp("Jingdong_supermarket".replace("京东超市", name[i])));
  31. element.click();
  32. //断言
  33. assertTrue(driver, "assertTitile", name[i] + "跳转成功");
  34. //退回
  35. WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("home_back"), "退回");
  36. driver.findElement(getByLocator.getLocatorApp("home_back"));
  37. }
  38. }
  39. /** * 分类写法 * * @param driver */
  40. public void categorylist(AndroidDriver<AndroidElement> driver) {
  41. WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("categorylist"), "遍历分类");
  42. //获取全部数据挨个遍历
  43. List<AndroidElement> categorylist = driver.findElements(getByLocator.getLocatorApp("categorylist"));
  44. for (int i = 0; i < categorylist.size(); i++) {
  45. String text = categorylist.get(i).getText();
  46. //输出遍历name
  47. LogUtil.info(text);
  48. categorylist.get(i).click();
  49. }
  50. }
  51. /** * 收藏 * * @param driver */
  52. public void productdetail(AndroidDriver<AndroidElement> driver) {
  53. WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp("productdetail"), "收藏");
  54. AndroidElement detail = driver.findElement(getByLocator.getLocatorApp("productdetail"));
  55. String attribute = detail.getAttribute("selected");
  56. if (attribute.equals(true)) {
  57. LogUtil.info("目前商品收藏,目前的属性为:" + attribute);
  58. } else {
  59. LogUtil.info("商品没有收藏,目前的属性为:" + attribute);
  60. }
  61. }
  62. /** * 统一判断是否通过 * * @param driver 传driver * @param elemn 定元素 * @param des 描述 */
  63. public void assertTrue(AndroidDriver<AndroidElement> driver, String elemn, String des) {
  64. WaitUtil.waitWebElement(driver, getByLocator.getLocatorApp(elemn), des);
  65. element = driver.findElement(getByLocator.getLocatorApp(elemn));
  66. String text = element.getText();
  67. if (text != null) {
  68. Assert.assertTrue(true, des + "验证成功");
  69. } else {
  70. //如果失败系统会自动截图
  71. Assert.fail("跳转失败");
  72. }
  73. }
  74. }
  75. // Assert.assertTrue("", "验证跳转成功");
  76. // driver.findElement(By.id(""))

基础启动类

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

业务组合测试类

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

其他测试类集成,即可

总结

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

本文源码:

相关文章