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

news2025/6/3 18:52:12

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 ClientSession

async 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 = driver
            
            search_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. 输入用户名:Tester
  3. 输入密码:test
  4. 点击登录按钮
  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.0

async_test_cls.py
"""


class Base:
    async_driver = None

    async 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.coloradmin.cn/o/2395125.html

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

相关文章

【五子棋在线对战】一.前置知识的了解

前置知识的了解 前言1.Websocketpp1.1 使用Websocketpp的原因1.2 Websocket常用接口1.3 Websocket搭建服务器流程 2.JsonCpp2.1 Json 数据对象类的表示2.2序列化和反序列化的接口2.3 演示代码 3.Mysql![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/93305f423b544fc1…

历年中国科学技术大学计算机保研上机真题

2025中国科学技术大学计算机保研上机真题 2024中国科学技术大学计算机保研上机真题 2023中国科学技术大学计算机保研上机真题 在线测评链接:https://pgcode.cn/school?classification1 拆分数字 题目描述 给定一个数字,拆分成若干个数字之和&#xff…

HackMyVM-Art

信息搜集 主机发现 ┌──(kali㉿kali)-[~] └─$ nmap -sn 192.168.43.0/24 Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-31 03:00 EDT Nmap scan report for 192.168.43.1 Host is up (0.0047s latency). MAC Address: C6:45:66:05:91:88 (Unknown) Nmap scan rep…

网页前端开发(基础进阶1)

颜色表示方法3种: 1.关键字: color:green; gray red yellow 2.rgb表示法:红,绿,蓝三原色。rgb(r,g,b),r表示红色,g表示绿…

如何找到一条适合自己企业的发展之路?

一个创业型的企业,开始就需要面向市场,通过自己的服务或产品,帮助用户解决问题,为客户创造价值,通过为客户创造的价值,出创造一定的的现金流,让企业存活下来! 企业的运营过程中&…

Vue-数据监听

数据监听 基础信息 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>数据监听</title><!-- 引入Vue --><script type"text/javascript" src"../js/vue.js&qu…

当前用户的Git全局配置情况:git config --global --list

通过config命令可以查询当前用户的全局配置情况。这些配置项定义了 Git 在全局范围内的行为&#xff0c;包括如何处理大文件、SSL 证书验证以及提交时的用户信息。 git config --global --list http.sslVerifyfalse 这个配置项禁用了 SSL 证书验证。这在与自签名证书的 Git 服…

AI生态警报:MCP协议风险与应对指南(中)——MCP Server运行时安全​​

作为连接AI模型与外部工具的“USB-C接口”&#xff0c;MCP协议成为AI生态的核心枢纽&#xff0c;其安全风险已从理论威胁转化为实际攻击目标。 AI生态警报&#xff1a;MCP协议风险与应对指南&#xff08;上&#xff09;——架构与供应链风险https://blog.csdn.net/WangsuSecur…

day15 leetcode-hot100-29(链表8)

19. 删除链表的倒数第 N 个结点 - 力扣&#xff08;LeetCode&#xff09; 1.暴力法 思路 &#xff08;1&#xff09;先获取链表的长度L &#xff08;2&#xff09;然后再次遍历链表到L-n的位置&#xff0c;直接让该指针的节点指向下下一个即可。 2.哈希表 思路 &#xff0…

MonitorSDK_性能监控(从Web Vital性能指标、PerformanceObserver API和具体代码实现)

性能监控 性能指标 在实现性能监控前&#xff0c;先了解Web Vitals涉及的常见的性能指标 Web Vitals 是由 Google 推出的网页用户体验衡量指标体系&#xff0c;旨在帮助开发者量化和优化网页在实际用户终端上的性能体验。Web Vitals 强调“以用户为中心”的度量&#xff0c;而不…

LeeCode 98. 验证二叉搜索树

给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 提示&#xff1a; 树中节…

JVM类加载高阶实战:从双亲委派到弹性架构的设计进化

前言 作为Java开发者&#xff0c;我们都知道JVM的类加载机制遵循"双亲委派"原则。但在实际开发中&#xff0c;特别是在金融支付、插件化架构等场景下&#xff0c;严格遵循这个原则反而会成为系统扩展的桎梏。本文将带你深入理解双亲委派机制的本质&#xff0c;并分享…

threejsPBR材质与纹理贴图

1. PBR材质简介 本节课没有具体的代码&#xff0c;就是给大家科普一下PBR材质&#xff0c;所谓PBR就是&#xff0c;基于物理的渲染(physically-based rendering)。 Three.js提供了两个PBR材质相关的APIMeshStandardMaterial和MeshPhysicalMaterial,MeshPhysicalMaterial是Mes…

深兰科技董事长陈海波受邀出席2025苏商高质量发展(常州)峰会,共话AI驱动产业升级

5月29日&#xff0c;2025苏商高质量发展峰会在常州隆重开幕。本次峰会聚焦新质生产力培育与产业创新转型&#xff0c;汇聚了众多江苏省内知名企业家、专家学者及政府代表。深兰科技创始人、董事长陈海波作为人工智能领域的领军企业代表&#xff0c;受邀出席盛会并参与重要活动环…

Git入门到精通:30分钟掌握核心技巧

目录 一、基础理论片 Git简介 Git安装 Git仓库 Git基本命令用法 仓库别名 二、实操命令篇 远程分支 分支的新建和合并 实操演示 1 本地新建仓库 2 gitee新建仓库 3 建立关系 4 新建分支 5 开发新功能 6 推送新分支 7 合并新分支到主分支 三、可视化工具篇 G…

Redis7底层数据结构解析

redisObject 在 Redis 的源码中&#xff0c;Redis 会将底层数据结构&#xff08;如 SDS、hash table、skiplist 等&#xff09;统一封装成一个对象&#xff0c;这个对象叫做 redisObject&#xff0c;也简称 robj。 typedef struct redisObject {unsigned type : 4; // 数…

多部手机连接同一wifi的ip一样吗?

在家庭和办公环境中&#xff0c;多台手机同时连接同一个WiFi路由器已成为常态。不少用户会产生疑问&#xff1a;这些设备的IP地址会相同吗&#xff1f;下面就一起来了解一下吧。 一、多部手机连接同一WiFi的IP‌一样吗 多部手机连接同一WiFi时的IP地址是否相同&#xff0c;需要…

大语言模型值ollama使用(1)

ollama为本地调用大语言模型提供了便捷的方式。下面列举如何在windows系统中快捷调用ollama。 winR打开运行框&#xff0c;输入cmd 1、输入ollama list 显示已下载模型 2、输入ollama pull llama3 下载llama3模型 3、 输入 ollama run llama3 运行模型 4、其他 ollama li…

thc-ssl-dos:SSL 压力测试的轻量级工具!全参数详细教程!Kali Linux教程!

简介 THC-SSL-DOS 是一款用于验证 SSL 性能的工具。 建立安全的 SSL 连接需要服务器比客户端高 15 倍的处理能力。 THC-SSL-DOS 利用这种不对称特性&#xff0c;通过使服务器过载并使其断网。 此问题影响当今所有 SSL 实现。供应商自 2003 年以来就已意识到这个问题&#x…

【速通RAG实战:进阶】17、AI视频打点全攻略:从技术实现到媒体工作流提效的实战指南

一、AI视频打点的技术底层与数据处理流程 (一)视频内容结构化的核心技术栈 AI视频打点的本质是将非结构化视频数据转化为带时间戳的结构化信息,其技术流程涵盖音视频处理、语音识别、自然语言处理三大核心模块,形成“数据采集-内容解析-智能标记-协同应用”的完整闭环。 …