移动端自动化测试工具 Appium 之元素操作小技巧

举报
zuozewei 发表于 2024/05/13 11:04:27 2024/05/13
【摘要】 appium自动化工作中,元素操作最常用的就是Id/xpath,因为【appium1.5.0后,不支持使用name定位】所有大家在工作中使用id/xpath定位;如果还是想用name定位,需要修改源码,具体大家自己去查,但在工作中id/xpath已经够用。 今天介绍目前我作最常用的一些方法,希望能帮到大家,少走弯路。

一、背景

appium自动化工作中,元素操作最常用的就是Id/xpath,因为【appium1.5.0后,不支持使用name定位】所有大家在工作中使用id/xpath定位;如果还是想用name定位,需要修改源码,具体大家自己去查,但在工作中id/xpath已经够用。

今天介绍目前我作最常用的一些方法,希望能帮到大家,少走弯路。

二、TestNG常用注解

为什么要学习testng注解,因为在写测试类的时候需要,通过小小注解让他帮我们干活,所有需要先了解下:

TestNG简单介绍几种注解:

注解 描述
@BeforeSuite 在该套件的所有测试都运行在注释的方法之前,仅运行一次
@AfterSuite 在该套件的所有测试都运行在注释方法之后,仅运行一次
@BeforeClass 在调用当前类的第一个测试方法之前运行,注释方法仅运行一次
@AfterClass 在调用当前类的第一个测试方法之后运行,注释方法仅运行一次
@BeforeTest 注释的方法将在属于test标签内的类的所有测试方法运行之前运行
@AfterTest 注释的方法将在属于test标签内的类的所有测试方法运行之后运行
@BeforeGroups 配置方法将在之前运行组列表。此方法保证在调用属于这些组中的任何一个的第一个测试方法之前不久运行
@AfterGroups 此配置方法将在之后运行组列表。该方法保证在调用属于任何这些组的最后一个测试方法之后不久运行
@BeforeMethod 注释方法将在每个测试方法之前运行
@AfterMethod 注释方法将在每个测试方法之后运行
@DataProvider 标记一种方法来提供测试方法的数据。注释方法必须返回一个Object [] [],其中每个Object []可以被分配给测试方法的参数列表。要从该DataProvider接收数据的@Test方法需要使用与此注释名称相等的dataProvider名称
@Factory 将一个方法标记为工厂,返回TestNG将被用作测试类的对象。该方法必须返回Object []
@Listeners 定义测试类上的侦听器
@Parameters 描述如何将参数传递给@Test方法
@Test 将类或方法标记为测试的一部分,此标记若放在类上,则该类所有公共方法都将被作为测试方法

注意:
在使用 @test 注解用例的时候,最好使用T001做方法名称,这样test在跑的时候会根据0–1这样的开始执行。

image.png

如果想改变执行规则可以增加 priority 注解:

@Test(description = "初始化登录启动", testName = "进入首页", priority = 0)

说明:

  • description:表示注释t
  • estName:标志测试类
  • priority:表示执行顺序

三、实战

3.1、集成启动类

下载京东APP

启动app就能看到,每次启动都会提示这个,那么在写代码的时候咱们把这个方法:

image.png

类似这样的在写测试用例的时候可以这样写,之后其他类集成这个即可:

image.png

3.2、采用xpath定位元素

如图:
image.png

类似中间这些应该怎么定位才最好,我们观察下面定位,可以采用xpath定位。

image.png

代码示例:

/**
* 点击购物车
*/
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(By.xpath("//android.widget.TextView[@text='京东超市']".replace("京东超市", name[i])));
        element.
        click();
    }
}

点击进入京东超市后再判断是否登录成可以:

image.png

上可以采用id定位

image.png

3.3、编写通用判断类

编写通用判断类

 /**
       * 统一判断是否通过
       *
       * @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("跳转失败");
     }
 }

完整代码
元素:

#点击首页
clickCart=xpath>>//android.view.View[@content-desc='首页']

#跳转成功
assertTitile=id>>com.jingdong.app.mall:id/fd

#退回
home_back=id>>com.jingdong.app.mall:id/fe

#百宝箱名字
Jingdong_supermarket=xpath>>//android.widget.TextView[@text='京东超市']

代码示例

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

    /**
         * 点击百宝箱
         * @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 传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));
    Stringtext = element.getText();
    if(text != null) {
        Assert.assertTrue(true, des + "验证成功");
    } else {
        //如果失败系统会自动截图
        Assert.fail("跳转失败");
    }
}

3.4、编写测试类

测试类:

import appout.appcase.data.CartProvider;
import org.testng.annotations.Test;

/**
 * @author liwen
 * @Title: CartTest
 * @Description: 测试类
 * @date 2019/11/23 / 19:57
 */

public class CartTest extends BestRuner {
    CartProvider cartProvider = new CartProvider();
    
    @Test(description = "点击首页百宝箱", testName = "点击百宝箱", priority = 1)
    publicvoidT002() {
        cartProvider.clickHome(driver);
        cartProvider.clickbaibao(driver);
    }
}

xpath语法:
https://www.w3school.com.cn/xpath/xpath_syntax.asp

3.5、遍历实现

观察如图:如果想遍历推荐分类每个商品应该怎么写?是每个写一个还是执行一个list之后挨个遍历?还是这么写?

image.png

观察定位方式:
image.png

在工作中我是这样写的

#分类
categorylist=id>>com.jd.lib.category:id/a1z

代码示例:

 /**
      * 分类写法
      * @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();
     }
 }

属性判断写法

查看如下图:想知道该商品是否关注,应该这么写?

image.png
image.png

通过观察,代码写法:
1、获取该元素的地位

image.png

元素为:

#收藏
productdetail=id>>com.jd.lib.productdetail:id/afr

简单代码:

/**
     * 收藏
     *
     * @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);
    }
}

通过得取属性就知道下一步怎么操作。

四、总结

上面简单介绍几个测试用例写法,随着大家不断熟悉移动端UI自动化,技能会逐渐增加,希望给大家带去一点帮助,

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。