40. 自动化异步测试开发之编写异步业务函数、测试函数和测试类(类写法)

40. 自动化异步测试开发之编写异步业务函数、测试函数和测试类(类写法)

一、类结构设计解析

1.1 基类设计

class Base:async_driver = None  # 🚗 存储浏览器驱动实例async def get(self, url: str = 'http://secure.smartbearsoftware.com/...'):await self.async_driver.get(url)  # 🌐 导航到指定URL
  • 核心成员async_driver 存储浏览器驱动实例
  • 通用功能:提供页面导航方法
  • 默认URL:Web Orders登录页面

1.2 登录页面类

class LoginPage(Base):async def login(self, username: str = 'Tester', password: str = 'test'):# 输入用户名await self.async_driver.send_keys('id', 'ctl00_MainContent_username', text=username)# 输入密码await self.async_driver.send_keys('id', 'ctl00_MainContent_password', text=password)# 点击登录按钮await self.async_driver.click('name', 'ctl00$MainContent$login_button')
  • 功能定位:封装登录相关操作
  • 默认凭证:用户名’Tester’,密码’test’
  • 元素定位:使用ID定位输入框,Name定位按钮

1.3 主页面类

class MainPage(LoginPage):async def search(self):# 点击搜索菜单await self.async_driver.click('xpath', '//*[@id="ctl00_menu"]/li[3]/a')# 输入搜索内容(需要添加text参数)await self.async_driver.send_keys('id', 'ctl00_MainContent_fmwOrder_txtName')# 点击搜索按钮await self.async_driver.click('id', 'ctl00_MainContent_fmwOrder_InsertButton')async def logout(self):# 点击登出链接await self.async_driver.click('xpath', '//*[@id="ctl00_logout"]')
  • 继承关系:继承自LoginPage,复用登录功能
  • 扩展功能:添加搜索和登出操作
  • 元素定位:混合使用XPath和ID定位器

二、测试类实现

2.1 登录测试类

class AsyncTestLogin(MainPage):async def test_login(self, *args):await self.get()  # 打开登录页await self.login(*args)  # 执行登录# 验证登录成功title_text = await self.async_driver.text('xpath', '//*[@id="aspnetForm"]//td[1]/h1')assert title_text == 'Web Orders'
  • 测试流程
    1. 打开登录页
    2. 执行登录
    3. 验证页面标题
  • 断言验证:检查标题是否为’Web Orders’

2.2 搜索测试类

class AsyncTestMain(MainPage):async def test_search(self):await self.get()  # 打开登录页await self.login()  # 登录系统await self.search()  # 执行搜索# 验证错误提示error_msg = await self.async_driver.text('id', "ctl00_MainContent_fmwOrder_RequiredFieldValidator3")assert error_msg == "Field 'Street' cannot be empty."await self.logout()  # 退出登录
  • 测试流程
    1. 登录系统
    2. 执行搜索
    3. 验证错误提示
    4. 登出系统
  • 断言验证:检查是否显示街道字段不能为空的错误

三、完整测试执行示例

3.1 测试运行器

import asyncio
from chap9.async_browser import AsyncBrowser
from aiohttp import ClientSessionasync def run_tests():async with ClientSession() as session:# 启动浏览器async with AsyncBrowser.start(remote_driver_server='http://localhost:9515',capabilities={'browserName': 'chrome'},http_session=session) as driver:# 创建测试实例login_test = AsyncTestLogin()login_test.async_driver = driversearch_test = AsyncTestMain()search_test.async_driver = driver# 执行登录测试print("执行登录测试...")await login_test.test_login()print("登录测试通过 ✓")# 执行搜索测试print("执行搜索测试...")await search_test.test_search()print("搜索测试通过 ✓")if __name__ == "__main__":asyncio.run(run_tests())

3.2 预期执行结果

执行登录测试...
登录测试通过 ✓
执行搜索测试...
搜索测试通过 ✓

3.3 实际操作流程

登录测试:1. 打开登录页2. 输入用户名:Tester3. 输入密码:test4. 点击登录按钮5. 验证页面标题:Web Orders搜索测试:1. 打开登录页2. 输入凭证登录3. 点击搜索菜单4. 点击搜索按钮(不输入内容)5. 验证错误提示:Field 'Street' cannot be empty.6. 点击登出链接

四、类写法的优势分析

4.1 继承结构

Base│├── LoginPage│     ││     └── MainPage│           ││           ├── AsyncTestLogin│           ││           └── AsyncTestMain
  • 代码复用:通过继承复用公共方法和属性
  • 功能扩展:子类可以扩展或重写父类方法
  • 逻辑分层:清晰区分页面操作和测试验证

4.2 与函数写法的对比

特性类写法函数写法
状态管理通过类属性维护状态依赖参数传递状态
代码组织按页面/功能模块组织按操作流程组织
复用性高(继承机制)中(函数组合)
学习曲线较陡峭(需理解OOP)较平缓
适用场景大型项目/复杂页面小型项目/简单流程

五、最佳实践建议

5.1 类设计优化

class BasePage:def __init__(self, driver):self.driver = driver  # ✅ 通过构造器注入驱动async def open(self, url):await self.driver.get(url)class LoginPage(BasePage):USERNAME = ('id', 'ctl00_MainContent_username')PASSWORD = ('id', 'ctl00_MainContent_password')LOGIN_BTN = ('name', 'ctl00$MainContent$login_button')async def login(self, username, password):await self.driver.send_keys(*self.USERNAME, text=username)await self.driver.send_keys(*self.PASSWORD, text=password)await self.driver.click(*self.LOGIN_BTN)

5.2 测试类优化

class TestLogin(LoginPage):TITLE = ('xpath', '//*[@id="aspnetForm"]//td[1]/h1')async def test_success_login(self):await self.open(LOGIN_URL)await self.login(TEST_USER, TEST_PASS)assert await self.driver.text(*self.TITLE) == 'Web Orders'

5.3 执行入口优化

async def main():driver = await create_driver()login_page = LoginPage(driver)await login_page.test_success_login()

这种基于类的异步测试开发模式,通过面向对象的设计思想,提供了更结构化、可维护性更高的测试代码组织方式,特别适合中大型自动化测试项目。

六、完整代码

"""
Python :3.13.3
Selenium: 4.31.0async_test_cls.py
"""class Base:async_driver = Noneasync def get(self, url: str = 'http://secure.smartbearsoftware.com/samples/testcomplete12/WebOrders/Login.aspx'):await self.async_driver.get(url)class LoginPage(Base):async def login(self, username: str = 'Tester', password: str = 'test'):await self.async_driver.send_keys('id', 'ctl00_MainContent_username', text=username)await self.async_driver.send_keys('id', 'ctl00_MainContent_password', text=password)await self.async_driver.click('name', 'ctl00$MainContent$login_button')class MainPage(LoginPage):async def search(self):await self.async_driver.click('xpath', '//*[@id="ctl00_menu"]/li[3]/a')await self.async_driver.send_keys('id', 'ctl00_MainContent_fmwOrder_txtName')await self.async_driver.click('id', 'ctl00_MainContent_fmwOrder_InsertButton')async def logout(self):await self.async_driver.click('xpath', '//*[@id="ctl00_logout"]')class AsyncTestLogin(MainPage):async def test_login(self, *args):await self.get()await self.login(*args)assert await self.async_driver.text('xpath', '//*[@id="aspnetForm"]//td[1]/h1') == 'Web Orders'class AsyncTestMain(MainPage):async def test_search(self, text: str = '1'):await self.get()await self.login()await self.search(text)assert await self.async_driver.text('id',"ctl00_MainContent_fmwOrder_RequiredFieldValidator3") == "Field 'Street' cannot be empty."await self.logout()

「小贴士」:点击头像→【关注】按钮,获取更多软件测试的晋升认知不迷路! 🚀

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

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

相关文章

面向开发者的提示词工程④——文本推断(Inferring)

文章目录 前言一、情感(正向/负向)二、识别情感类型三、识别愤怒四、从客户评论中提取产品和公司名称五、一次完成多项任务 前言 面向开发者的提示词工程——导读 在这节课中,你将从产品评论和新闻文章中推断情感和主题。 举了个商品评论的例…

java day15 (数据库)

进入数据库的学习 DB 因为数据太多了,方便统一管理的软件 操作就不用改代码了,直接改数据库则可; 命令就是sql语句 这些都是关系型数据库,sql可以控制全部,至于具体的环境我以前就有安装过了; 理解&am…

国标GB28181设备管理软件EasyGBS远程视频监控方案助力高效安全运营

一、方案背景​ 在商业快速扩张的背景下,连锁店门店数量激增,分布范围广。但传统人工巡检、电话汇报等管理方式效率低下,存在信息滞后、管理盲区,难以掌握店铺运营情况,影响企业效率与安全。网络远程视频监控系统可有…

Python 字典(dict)的高级用法与技巧

今天我们继续深入讲解 Python 字典的 高级用法与技巧,包括: defaultdict:带默认值的字典Counter:快速统计工具字典排序:按键或值排序合并字典(传统方式和 Python 3.9 新语法)嵌套字典的安全访问…

动静态库的使用(Linux)

1.库 通俗来说,库就是现有的,可复用的代码,例如:在C/C语言编译时,就需要依赖相关的C/C标准库。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。通常我们可以在windows下看到一些后…

R²ec: 构建具有推理能力的大型推荐模型,显著提示推荐系统性能!!

摘要:大型推荐模型通过编码或项目生成将大型语言模型(LLMs)扩展为强大的推荐工具,而近期在LLM推理方面的突破也同步激发了在推荐领域探索推理的动机。目前的研究通常将LLMs定位为外部推理模块,以提供辅助性思考来增强传…

【Java后端基础 005】ThreadLocal-线程数据共享和安全

📚博客主页:代码探秘者 ✨专栏:文章正在持续更新ing… ✅C语言/C:C(详细版) 数据结构) 十大排序算法 ✅Java基础:JavaSE基础 面向对象大合集 JavaSE进阶 Java版数据结构JDK新特性…

Tesseract配置参数详解及适用场景(PyTesseract进行OCR)

在使用 PyTesseract 进行 OCR 时,合理配置参数是提高识别准确率的关键。以下是 Tesseract 常用参数的详细解释和适用场景。 一、关键参数 (1)页面分割模式(Page Segmentation Mode, --psm) 控制 Tesseract 如何分析…

【Zephyr 系列 12】BLE + NVS + 低功耗融合实战:打造可配置蓝牙信标系统

🧠关键词:Zephyr、BLE 广播、信标、NVS 参数、低功耗、状态机、周期唤醒 📌适合人群:希望实现 BLE 信标类产品(定位标签、资产管理)的开发者 📊预计篇幅:约 5200+ 字 🎯 项目目标 构建一个可广泛应用于资产标签、定位信标、设备标识等场景的蓝牙广播模块,具备:…

图解浏览器多进程渲染:从DNS到GPU合成的完整旅程

目录 浏览器进程架构的演化 进程和线程关系图示 进程(Process) 线程(Thread) 协程(Coroutine) 进程&线程&协程核心对比 单进程和多进程浏览器 单进程浏览器​编辑 单进程浏览器存在的问题…

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…

C# 类和继承(抽象成员)

抽象成员 抽象成员是指设计为被覆写的函数成员。抽象成员有以下特征。 必须是一个函数成员。也就是说,字段和常量不能为抽象成员。必须用abstract修饰符标记。不能有实现代码块。抽象成员的代码用分号表示。 例如,下面取自一个类定义的代码声明了两个抽…

基于JWT+SpringSecurity整合一个单点认证授权机制

基于 JWT Spring Security 的授权认证机制,在整体架构设计上体现了高度的安全性与灵活性。其在整合框架中的应用,充分展示了模块化、可扩展性和高效鉴权的设计理念,为开发者提供了一种值得借鉴的安全架构模式。 1.SpringSecurity概念理解 …

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…

Git 切换到旧提交,同时保证当前修改不丢失

在 Git 中&#xff0c;可以通过以下几种方式切换到之前的提交&#xff0c;同时保留当前的修改 1. 使用 git checkout 创建临时分离头指针&#xff08;推荐用于查看代码&#xff09; git checkout <commit-hash>这会让你进入"分离头指针"状态&#xff0c;你可…

东芝Toshiba DP-4528AG打印机信息

东芝 Toshiba DP 4528AG 是一款黑白激光数码复合机&#xff1a; 类型&#xff1a;激光数码复合机&#xff0c;涵盖复印、打印、扫描、传真功能&#xff0c;能满足办公室多样化的文档处理需求。速度类型&#xff1a;中速&#xff0c;黑白复印和打印速度可达 45 页 / 分钟&#…

Qt生成日志与以及捕获崩溃文件(mingw64位,winDbg)————附带详细解说

文章目录 Qt生成日志与以及报错文件(mingw64位&#xff0c;winDbg)0 背景与结果0.1 背景0.2 结果1 WinDbg1.1 安装1.2 使用 2 编写代码2.1 ccrashstack类2.2 编写输出捕获异常的dmp文件2.2 编写输出日志文件2.3 调用生成日志和dmp文件 参考 Qt生成日志与以及报错文件(mingw64位…

Nginx + Tomcat负载均衡群集

目录 一、案例环境 二、部署 Tomcat&#xff08;102/103&#xff09; 1、准备环境 &#xff08;1&#xff09;关闭firewalld 防火墙 &#xff08;2&#xff09;安装JDK 2、安装配置 Tomcat &#xff08;1&#xff09;Tomcat 的安装和配置 &#xff08;2&#xff09;移动…

三、元器件的选型

前言&#xff1a;我们确立了题目的功能后&#xff0c;就可以开始元器件的选型&#xff0c;元器件的选型关乎到我们后面代码编写的一个难易。 一、主控的选择 主控的选择很大程度上决定我们后续使用的代码编译器&#xff0c;比如ESP32使用的是VScode&#xff0c;或者Arduino&a…

API是什么意思?如何实现开放API?

目录 一、API 是什么 &#xff08;一&#xff09;API 的定义 &#xff08;二&#xff09;API 的作用 二、API 的类型 &#xff08;一&#xff09;Web API 1. RESTful API 2. SOAP API &#xff08;二&#xff09;操作系统 API &#xff08;三&#xff09;数据库 API …