Skip to content

【线上】用户端App自动化测试

用户端 App 自动化测试

预习准备

  • 提前先预习完以下相关的知识,再开始本章节的学习。
知识模块 等级 知识点 Python 班级 Java 班级
用户端 APP 自动化测试 L3 自动化关键数据记录 Python 版录播 Java 版录播
用户端 APP 自动化测试 L3 app 弹窗异常处理
用户端 APP 自动化测试 L3 自动化测试架构优化
用户端 APP 自动化测试 L3 【实战】基于 page object 模式的测试框架优化实战

课程目标

  • 掌握 App 自动化测试框架封装能力。
  • 掌握 App 自动化测试框架优化能力。
  • 掌握 App 多设备自动化测试的原理与方案。

需求说明

被测对象

  • 企业微信
  • 腾讯微信团队打造的企业通讯与办公工具,具有与微信一致的沟通体验,丰富的 OA 应用,和连接微信生态的能力。
  • 可帮助企业连接内部、连接生态伙伴、连接消费者。专业协作、安全管理、人即服务。
  • 前提条件:
  • 手机端安装好企业微信 App。
  • 企业微信注册用户。

测试需求

  • 完成 App 自动化测试框架搭建。
  • 在自动化测试框架中编写自动化测试用例。
  • 优化测试框架。
  • 输出测试报告。
  • 实现多设备自动化测试。

实战思路

uml diagram

使用 PO 模式封装测试框架

  1. PO 设计模式 回顾。
  2. 构造页面相关类和方法,实现暂时留空。
  3. 根据业务逻辑编写,编写测试用例。

uml diagram

分层 作用 示例
BasePage 封装和业务无关的公共方法(操作) 查找元素
滑动行为
业务 App 和具体 App 相关的操作 初始化 App
回到首页
业务 Page 具体的业务页面 ContactPage(通讯录页)
MainPage(首页)
测试用例层 测试步骤,相关的页面以及断言 添加成员用例
查找成员用例

填充测试框架

  1. app 启动。
  2. BasePage 封装。
  3. 封装元素为私有属性。
  4. 封装测试数据记录方法。

  5. Python 实现:

# base_page.py
class BasePage:
    IMPLICITLY_WAIT = 10

    def __init__(self, driver: WebDriver = None):
        self.driver = driver

    @black_wrapper
    def find(self, by, value):
        """
        单个元素查找
        :param by:
        :param value:
        :return:
        """
        step_text = f"使用 {by} 的定位方式进行 {value} 的定位操作"
        logger.info(step_text)
        with allure.step(step_text):
            self.screenshot()
            self.save_page_source()
            return self.driver.find_element(by, value)

    @black_wrapper
    def finds(self, by, value):
        """
        多个元素查找
        :param by:
        :param value:
        :return:
        """
        step_text = f"使用 {by} 的定位方式进行 {value} 的定位操作"
        logger.info(step_text)

        return self.driver.find_elements(by, value)
    ...省略其他方法...
# wework_app.py
class WeworkApp(BasePage):
    APP_PACKAGE = "com.tencent.wework"

    def start(self):
        """
        启动app
        :return:
        """
        if self.driver:
            self.driver.activate_app(self.APP_PACKAGE)
        else:
            # 准备资源
            caps = {}
            # 被测手机的平台名
            caps["appium:platformName"] = "Android"
            # ... 省略其他配置 ...
            # 把 caps 转换成 AppiumOptions
            options = AppiumOptions().load_capabilities(caps)
            # 关键的步骤!!!调用Remote() 建立连接 ,返回 一个session对象
            self.driver = webdriver.Remote("http://127.0.0.1:4723", options=options)
            # 隐式等待, 动态的等到元素出现
            self.set_implicitly_wait(self.IMPLICITLY_WAIT)
        return self
# error_handle.py
black_list = [
    (AppiumBy.XPATH, "//*[@text='确定']"),
    (AppiumBy.XPATH, "//*[@text='取消']")
]
# 传入的 fun 相当于 find 方法
def black_wrapper(fun):
    def run(*args, **kwargs):
        # 相当于传入的第一个参数 self
        basepage = args[0]
        try:
            logger.info(f"开始查找元素:{args[2]}")
            return fun(*args, **kwargs)
        except Exception as e:
            logger.warning("未找到元素,处理异常")
            # 遇到异常截图
            # 获取当前工具文件所在的路径
            image_path = basepage.screenshot()
            allure.attach.file(image_path, name="查找元素异常截图", attachment_type=allure.attachment_type.PNG)
            # 保存页面源码
            pagesource_path = basepage.save_page_source()
            allure.attach.file(pagesource_path, name="page_source", attachment_type=allure.attachment_type.TEXT)

            for b in black_list:
                basepage.set_implicitly_wait()
                #  查找黑名单中的每一个元素
                eles = basepage.driver.find_elements(*b)
                if len(eles) > 0:
                    # 点击弹框
                    eles[0].click()
                    # 继续查找元素
                    basepage.set_implicitly_wait(10)
                    return fun(*args, **kwargs)
            logger.error(f"遍历黑名单,仍未找到元素,异常信息为 ====> {e}")
            logger.error(f"traceback.format_exc() 信息为 ====> {traceback.format_exc()}")
            raise e
    return run
  • Java 实现:
// BasePage.java
public class BasePage {
    public static final Logger logger = getLogger(lookup().lookupClass());
    AndroidDriver driver;
    public WebElement find(By by) {
        logger.debug("元素定位:{}", by);
        return driver.findElement(by);
    }
    public List<WebElement> finds(By by) {
        logger.debug("元素定位:{}", by);
        return driver.findElements(by);
    }
}
// ...省略其他方法...

public class WeworkApp extends BasePage {
    public WeworkApp() {
        UiAutomator2Options uiAutomator2Options = new UiAutomator2Options().amend("appium:appPackage", "com.tencent.wework")
        .amend("appium:appActivity", ".launch.LaunchSplashActivity")
        // ...省略其他配置...
        //初始化
        try {
            // appium 1.x 版本 url 换成这个 http://127.0.0.1:4723/wd/hub
            driver = new AndroidDriver(new URL("http://127.0.0.1:4723"), uiAutomator2Options);
            // 隐式等待
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }
    public WeworkApp(AndroidDriver androidDriver) {
        driver = androidDriver;
    }
    public void gotoMain(){
        logger.info("回到首页");
        // ...省略..
    }
}

多设备自动化测试

总结

  1. PO 设计模式优化脚本。
  2. 多设备自动化测试的多种方案与原理。

课后练习

点击查看课后练习