mobile自动化测试-appium webdriverio

news2025/7/20 2:51:13

   WebdriverIO是一款支持mobile app和mobile web自动化测试框架,与appium集成,完成对mobile应用测试。支持ios 和android两种平台,且功能丰富,是mobile app自动化测试首选框架。且官方还提供了mobile 应用测试example代码,大大减少了从0构建移动应用自动化测试base code时间。

   如果搭建mobile app应用的UI自动化测试代码,在选择框架时需要考虑如下一些点框架是否支持

1.是否支持自动等待?自动等待可提升UI自动化测试稳定性

2.是否支持自动scroll element 到viewport中?如果不支持,UI自动化测试会很脆弱

3.是否支持上下,左右滑动

4.是否支持对目标元素进行拖动

5.是否支持错误截图

6.定位页面元素selector是否丰富

接下来看看webdriverio是否有上面的特性,以及如何实现上下的特性

WebdriverIO支持自动等待

   webdriverIO框架支持自动等待,框架有各种等待超时时间设置。例如可以在全局配置文件中,灵活设置连接appium server的超时时间(connectionRetryTimeout,connectionRetryCount),查找页面元素超时时间(waitForSelectorTimeout)。除了全局设置,还可以手动设置超时时间,例如使用await element.waitForDisplayed({timeout: 1000})。通过这些超时时间,可以增加整个UI自动化测试稳定性。

WebdriverIO支持自动scroll element到viewport中

  在查找元素的时候,如果元素不在viewport中,webdriverIO会自动向下滑动,直到找到目标元素。以Android为例,下面有三种写法查找目标元素,如果目标元素不在viewport中,框架会自动向下滑动页面,直到找到目标元素。因为三种方式都可以实现向下滑动,建议首选第一种,

//使用UiSelector()直接查找页面元素,如果元素不存在,会默认向下滑动查找目标元素
  public async goToFirstPage() {
        const firstPageSelector = driver.isAndroid
            ? 'android=new UiSelector().resourceId("com.binance.dev:id/2131435629")'
            : '//XCUIElementTypeButton[@name="xx"]';
        await $(firstPageSelector).click()
    }
// 使用了UiScrollable,如果元素不存在,会默认向下滑动查找目标元素
    public async scrollDownToSymbol(symbol: string) {
        // UiScrollable默认是向下滚动,不会向上滚动
        const symbolSelector = driver.isAndroid
            ? `android=new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(new UiSelector().text("${symbol}"))`
            : `//XCUIElementTypeStaticText[@name="${symbol}"]`;
        await $(symbolSelector).click()
    }

// scrollIntoView默认也是向下滚动,不会向上滚动
    public async scrollIntoView(symbol: string) {
        const symbolSelector = driver.isAndroid
            ? `android=new UiSelector().text("${symbol}")`
            : `//XCUIElementTypeStaticText[@name="${symbol}"]`;
        await $(symbolSelector).scrollIntoView()
    }

WebdriverIO如何支持上下、左右滑动

  上面介绍了自动向下滑动,直到找到目标元素,在实际场景中,除了向下滑动,有时候需要向上滑动到界面顶部,或者向上滑动直到找到目标元素。另外,有时候还需要左右滑动,下面是具体实现的代码。

//向上滑动
public async scrollUpToSymbol(symbol: string) {
        const topElementSelector = `new UiSelector().text("${symbol}")`;
        // 使用 mobile: scroll 支持up,down 滚动,不支持左右滚动
        await driver.execute('mobile: scroll', {
            strategy: '-android uiautomator',
            selector: topElementSelector,
            direction: 'up' // 指定滚动方向为向上
        });
    }
//向右滑动
 public async swipeRight() {
        const selector = driver.isAndroid
            ? 'android=new UiSelector().resourceId("com.binance.dev:id/tabLayout")'
            : '//XCUIElementTypeButton[@name="xx"]';
        const scrollableElement = $(selector)
        await driver.swipe({
            // swipe right,屏幕会显示左边的内容
            direction: "right",
            scrollableElement: scrollableElement,
            percent: 0.8,
        });
    }
//向左滑动
    public async swipeLeft() {
        const selector = driver.isAndroid
            ? 'android=new UiSelector().resourceId("com.binance.dev:id/tabLayout")'
            : '//XCUIElementTypeButton[@name="xx"]';
        const scrollableElement = $(selector)
        await driver.swipe({
            // swipe left,屏幕会显示右边的内容
            direction: "left",
            scrollableElement: scrollableElement,
            percent: 0.8,
        });
    }
}

WebdriverIO如何实现拖动目标元素

  实际项目中,有些场景需要拖动目标元素到另外一个位置,某些应用的登录页面,可能就存在拖动的场景,下面是使用webdriverio实现拖动的code。dragAndDrop比较简单,因为webdriverIO已经进行了封装,直接调用即可。

it('should demonstrate the dragAndDrop command', async () => {
    const elem = $('#someElem')
    const target = $('#someTarget')

    // drag and drop to other element
    await elem.dragAndDrop(target)

    // drag and drop relative from current position
    await elem.dragAndDrop({ x: 100, y: 200 })
})

WebdriverIO如何支持错误截图

  UI自动测试中,支持错误截图是非常重要的功能,当有大量自动化case在流水线上每天运行时,维护成本是较大的,支持错误截图可以帮助更快的判断失败case的原因,更快的进行修复。支持错误截图非常简单,在conf.ts文件中增加如下配置即可。即便是对原生app进行错误截图,也适用browser.takeScreenshot()方法。

//在conf配置文件中增加如下的配置
afterTest: async function (test, context, { error, result, duration, passed, retries }) {
        if (!passed) {
            const screenshot = await browser.takeScreenshot();
            const fileName = `FAILED_${test.title.replace(/\s+/g, '_')}.png`;
            const filePath = path.join(process.cwd(), 'screenshots', fileName);
            // 确保目录存在
            fs.mkdirSync(path.dirname(filePath), { recursive: true });
            // 保存截图
            fs.writeFileSync(filePath, screenshot, 'base64');
            console.log(`Screenshot taken: ${filePath}`);
        }
    },

  webdriverio除了支持错误截图,还支持视觉测试,视觉测试本质就是通过对比两张截图来验证功能是否符合预期,如果某些应用页面只读信息比较多,那么可以采用这种方式来进行对比,不用手写每个页面元素进行对比,减少编写代码成本。

WebdriverIO支持哪些Selector

   对于Android应用,基本都采用UiAutomator2 Driver,下面列举的selector都是UIAutomator2支持的selector,主要通过resourceId,text,className来定位,如果有多个元素,还可以通过.instance(index)来定位,或者先定位parent元素,再定位children元素。如果目标元素有content-des属性,且该属性值唯一,那么可以直接使用$('~content-desc')来定位。

    public async inputAmount(amount: string) {
        const amountInputSelector = driver.isAndroid ? 'android=new UiSelector().resourceId("com.binance.dev:id/2131441146")' : "";
        await $(amountInputSelector).setValue(amount)
    }

    public async viewAsset() {
        const holdingAssetMenu = driver.isAndroid ? 'android=new UiSelector().text("持有币种")' : "";
        await $(holdingAssetMenu).click()
    }

    public async getPnlValue(index: number) {
        // 这里查找index=2的时候,没有自动向下滑动,可以手动调用scrollIntoView的方法
        const parentSelector = driver.isAndroid ? `android=new UiSelector().resourceId("com.binance.dev:id/2131431738").instance(${index})` : "";
        const childSelector = driver.isAndroid ? 'android=new UiSelector().resourceId("com.binance.dev:id/tv_asset_daily_pnl_value")' : "";
        const pnl_value = await $(parentSelector).$(childSelector).getText()
    }

const selector = 'new UiSelector().text("Cancel").className("android.widget.Button")'
const button = await $(`android=${selector}`)
await button.click()

  对于IOS app,工具也支持多种元素定位方式,最常见的是如果目标元素有accessibility id,那么使用$('~accessibility id')定位,另外还可以通过-ios predicate string来定位目标元素。

const selector = `type == 'XCUIElementTypeSwitch' && name CONTAINS 'Allow'`
const switch = await $(`-ios predicate string:${selector}`)
await switch.click()

const element = await $(`-ios predicate string:label == 'Login'`);

const element = await $(`-ios predicate string:name BEGINSWITH 'Submit'`);

const element = await $(`-ios predicate string:value > 10`);

const element = await $(`-ios class chain:**/XCUIElementTypeCell[`name BEGINSWITH "A"`][-1]/XCUIElementTypeButton[10]`);

除此之外,webdriverio的还支持zoom,tap,swipe,longPress操作。例如,可以通过tap模拟点击右键操作。

it('should be able to swipe right 3 times in a custom scroll areas to an element and tap on the element', async () => {
    const elem = $('~myElement')
    // Swipe right 3 times in the custom scrollable element to find the element
    await elem.tap({
        direction: 'right',
        maxScrolls: 3,
        scrollableElement: $('#scrollable')
    })
})

 除了常规的定位页面元素,操作页面元素外,webdriverio还支持视觉测试,即通过对比图片来达到验证的效果。如果某些app界面变化很小,那么可以采用视觉测试的方法,可有效降低编写代码的成本。

WebdriverIO视觉测试

 使用webdriverio开展视觉测试,首先需要在conf文件的services中进行如下配置,配置好后即可开始视觉测试,常用的方法就四个saveElement,checkElement,saveScreenshot,checkScreenshot。

[
            "visual", {
                baselineFolder: path.join(process.cwd(), "virtual", "baseline"),
                formatImageName: "{tag}",
                screenshotPath: path.join(process.cwd(), "virtual", "tmp"),
                savePerInstance: true,
                autoSaveBaseline: true,
                blockOutStatusBar: true,
                blockOutToolBar: true,
                ignoreNothing: true,
            }
        ]

//通过saveElement对目标元素进行截图存放到baseline中,再通过checkElement进行对比,如果对比不一致,会在diff文件中存放不一致的图片
   public async saveScreenForNormalFeature() {
        const selector = driver.isAndroid
            ? 'android=new UiSelector().resourceId("com.binance.dev:id/2131438006")'
            : '//XCUIElementTypeButton[@name="xx"]';
        await browser.saveElement(await $(selector), "normalFeature", {
            enableLayoutTesting: true
        })
    }
    public async checkScreenshotNormalFeature() {
        const selector = driver.isAndroid
            ? 'android=new UiSelector().resourceId("com.binance.dev:id/2131438006")'
            : '//XCUIElementTypeButton[@name="xx"]';
        await browser.checkElement(await $(selector), "normalFeature", {
            enableLayoutTesting: true
        })
    }

运行测试后,会自动创建响应的目录,并将目标元素截图存放到对应folder中。

以上就是对webdriverio工具的总体介绍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2374926.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Bean有哪几种配置方式?

大家好,我是锋哥。今天分享关于【Spring Bean有哪几种配置方式?】面试题。希望对大家有帮助; Spring Bean有哪几种配置方式? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring Bean的配置方式主要有三种&#xff…

解析小米大模型MiMo:解锁语言模型推理潜力

一、基本介绍 1.1 项目背景 在大型语言模型快速发展的背景下,小米AI团队推出MiMo系列模型,突破性地在7B参数规模上实现卓越推理能力。传统观点认为32B以上模型才能胜任复杂推理任务,而MiMo通过创新的训练范式证明:精心设计的预训练和强化学习策略,可使小模型迸发巨大推理…

证券行业数字化转型:灵雀云架设云原生“数字高速路”

01 传统架构难承重负,云原生破局成必然 截至2024年,证券行业总资产突破35万亿元,线上交易占比达85%,高频交易、智能投顾等业务对算力与响应速度提出极限要求。然而,以虚拟化为主导的传统IT架构面临四大核心瓶颈&#…

Centos系统详解架构详解

CentOS 全面详解 一、CentOS 概述 CentOS(Community Enterprise Operating System) 是基于 Red Hat Enterprise Linux(RHEL) 源代码构建的免费开源操作系统,专注于稳定性、安全性和长期支持,广泛应用于服…

【后端】SpringBoot用CORS解决无法跨域访问的问题

SpringBoot用CORS解决无法跨域访问的问题 一、跨域问题 跨域问题指的是不同站点之间,使用 ajax 无法相互调用的问题。跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。但这个保护机制也带来了新的…

MySQL 8.0(主从复制)

MySQL 8.0 的 主从复制(Master-Slave Replication) 是一种数据库高可用和数据备份的核心技术,下面用 一、什么是主从复制? 就像公司的「领导-秘书」分工: 主库(Master):负责处理所…

TCPIP详解 卷1协议 十 用户数据报协议和IP分片

10.1——用户数据报协议和 IP 分片 UDP是一种保留消息边界的简单的面向数据报的传输层协议。它不提供差错纠正、队列管理、重复消除、流量控制和拥塞控制。它提供差错检测,包含我们在传输层中碰到的第一个真实的端到端(end-to-end)校验和。这…

finebi使用资源迁移无法导入资源,解决方法

finebi使用资源迁移无法导入资源,解决方法 最近在使用finebi开发finebi报表,报表开发之后,从一台电脑将资源导入另一台电脑后,出现不允许导入的提示,如下: 原因: 两个finebi的管理员名称不一致…

分布式锁redisson的中断操作

1、先贴代码 RequestMapping(value "/update", method RequestMethod.POST)ResponseBodypublic Result update(RequestBody Employee employee) { // 修改数据库(存在线程不安全 需要使用redison设置分布式锁 防止被修改) // 设…

Docker:安装配置教程(最新版本)

文章目录 一、前言二、具体操作2.1 卸载 Docker (可选)2.2 重新安装(使用清华大学镜像)2.3 配置轩辕镜像加速2.4 Docker 基本命名2.5 测试是否成功 三、结语 一、前言 Docker 是一种容器化技术,在软件开发和部署中得到广泛的应用&#xff0c…

neo4j官方示例

目录 一、准备数据 1.执行查看结果 二、操作 1.find 单个节点 2.同上,已某个属性去查询 3. 指定查询个数 4.条件查询 5.查询某个人出演的电影汇总 6.查询tom出演的电影中,还有其他演员的信息。 7.查询跟电影(Cloud Atlas)有关的演员&#xff0…

前端自学入门:HTML 基础详解与学习路线指引

在互联网的浪潮中,前端开发如同构建数字世界的基石,而 HTML 则是前端开发的 “入场券”。对于许多渴望踏入前端领域的初学者而言,HTML 入门是首要挑战。本指南将以清晰易懂的方式,带大家深入了解 HTML 基础,并梳理前端…

vue实现与后台springboot传递数据【传值/取值 Axios 】

vue实现与后台springboot传递数据【传值/取值】 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是node.js和vue的使用。前后每一小节的内容是存在的有:学习and理解的关联性。【帮帮志系列文章】:每…

【英语笔记(三)】介绍谓语动词的分类,初步讲解四种基本状态:一般、进行、完成、完成进行

1. 五大类谓语动词 2. 谓语动词分类 3. 动词时间 过去--------------------------现在-----------------------未来 3. 动词状态 3.1 进行状态 3.2 完成状态 3.3 完成进行状态 3.4 一般状态 4. 时间 状态 名称说明例句现在现在现在现在进行时态现在某物正在做什么事情一只…

【Python】让Selenium 像Beautifulsoup一样,用解析HTML 结构的方式提取元素!

我在使用selenium的find_element的方式去获取网页元素,一般通过xpath、css_selector、class_name的方式去获取元素的绝对位置。 但是有时候如果网页多了一些弹窗或者啥之类的,绝对位置会发生变化,使用xpath等方法,需要经常变动。…

2025 后端自学UNIAPP【项目实战:旅游项目】3、API接口请求封装,封装后的简单测试以及实际使用

一、创建请求封装目录 选中自己的项目,右键鼠标---->新建---->目录---->名字自定义【我的是api】 二、创建两个js封装文件 选中封装的目录,右键鼠标---->新建---->js文件---->名字自定义【我的两个js文件分别是my_http和my_api】 三…

Ascend的aclgraph(二)_npu_backend中还有些什么秘密?

1 _npu_backend 文章还是从代码开始 import torch_npu, torchair config torchair.CompilerConfig() # 设置图下沉执行模式 config.mode "reduce-overhead" npu_backend torchair.get_npu_backend(compiler_configconfig) opt_model torch.compile(model, back…

ventoy安全启动怎么选_ventoy安全启动支持是开还是关

ventoy安全启动怎么选?Ventoy新一代多系统启动U盘解决方案。国产开源U盘启动制作工具,支持Legacy BIOS和UEFI模式,理论上几乎支持任何ISO镜像文件,支持加载多个不同类型的ISO文件启动,无需反复地格式化U盘,…

CC53.【C++ Cont】二分查找的普通模版

目录 1.知识回顾 2.关键点 特点 三个模版 普通的模版(有局限) 以LeetCode上的一道题为例:704. 二分查找 分析 引入二段性:分两段,舍一段,操作另一段(这个是二分查找的本质!) 代码 提交结果 当然也可以使用随机数来分两段 普通模版总结 1.知识回顾 之前在C语言专栏…

【优选算法 | 链表】链表操作技巧:常见算法

算法相关知识点可以通过点击以下链接进行学习一起加油!双指针滑动窗口二分查找前缀和位运算模拟 链表是一种灵活的数据结构,广泛用于需要频繁插入和删除的场景。掌握链表的常见操作技巧,如插入、删除、翻转和合并等,能帮助开发者更…