39. 自动化异步测试开发之编写异步业务函数、测试函数和测试类(函数写法)
39. 自动化异步测试开发之编写异步业务函数、测试函数和测试类(函数写法)
一、异步业务函数解析
1.1 页面导航函数
async def get(async_driver, url: str = 'http://secure.smartbearsoftware.com/samples/testcomplete12/WebOrders/Login.aspx'): await async_driver.get(url)
- 功能:导航到指定URL
- 默认URL:Web Orders登录页面
- 执行效果:浏览器打开指定页面
1.2 登录功能函数
async def login(async_driver, username: str = 'Tester', password: str = 'test'): await async_driver.send_keys('id', 'ctl00_MainContent_username', text=username) await async_driver.send_keys('id', 'ctl00_MainContent_password', text=password) await async_driver.click('name', 'ctl00$MainContent$login_button')
- 操作步骤:
- 在用户名输入框输入用户名
- 在密码输入框输入密码
- 点击登录按钮
- 默认凭证:用户名’Tester’,密码’test’
- 元素定位:使用ID定位输入框,Name定位按钮
1.3 搜索功能函数
async def search(async_driver): await async_driver.click('xpath', '//*[@id="ctl00_menu"]/li[3]/a') # 点击搜索菜单 await async_driver.send_keys('id', 'ctl00_MainContent_fmwOrder_txtName') # 输入搜索内容 await async_driver.click('id', 'ctl00_MainContent_fmwOrder_InsertButton') # 点击搜索按钮
- 操作流程:
- 点击菜单中的搜索选项
- 在搜索框输入内容
- 点击搜索按钮
1.4 登出功能函数
async def logout(async_driver): await async_driver.click('xpath', '//*[@id="ctl00_logout"]') # 点击登出链接
- 功能:退出当前登录状态
- 定位方式:使用XPath定位登出链接
二、异步测试函数实现
2.1 登录功能测试
async def test_login(async_driver): await get(async_driver) # 打开登录页面 await login(async_driver) # 执行登录操作 # 验证登录成功 title_text = await async_driver.text('xpath', '//*[@id="aspnetForm"]//td[1]/h1') assert title_text == 'Web Orders' await logout(async_driver) # 退出登录
- 测试流程:
- 打开登录页
- 输入凭证登录
- 验证页面标题
- 登出系统
- 断言验证:检查登录后页面标题是否为’Web Orders’
2.2 搜索功能测试
async def test_search(async_driver): await get(async_driver) # 打开登录页 await login(async_driver) # 登录系统 await search(async_driver) # 执行搜索操作 # 验证错误提示 error_msg = await async_driver.text('id', "ctl00_MainContent_fmwOrder_RequiredFieldValidator3") assert error_msg == "Field 'Street' cannot be empty." await logout(async_driver) # 退出登录
- 测试流程:
- 登录系统
- 执行空搜索
- 验证错误提示
- 断言验证:检查是否显示’Street不能为空’的错误提示
三、完整测试执行流程
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', 'goog:chromeOptions': {'args': ['--headless']} }, http_session=session ) as driver: # 执行登录测试 print("执行登录测试...") await test_login(driver) print("登录测试通过 ✓") # 执行搜索测试 print("执行搜索测试...") await test_search(driver) print("搜索测试通过 ✓") if __name__ == "__main__": asyncio.run(run_tests())
3.2 预期执行结果
执行登录测试... 登录测试通过 ✓ 执行搜索测试... 搜索测试通过 ✓
3.3 实际页面操作流程
1. 打开登录页:http://secure.smartbearsoftware.com/... 2. 输入用户名:Tester 3. 输入密码:test 4. 点击登录按钮 5. 验证页面标题:Web Orders 6. 点击登出链接 7. 重新登录 8. 点击搜索菜单 9. 点击搜索按钮(不输入内容) 10. 验证错误提示:Field 'Street' cannot be empty. 11. 点击登出链接
四、设计优势分析
4.1 业务与测试分离
- 业务函数:封装页面操作逻辑(如login, search)
- 测试函数:组合业务函数并添加断言
- 分离好处:业务变更只需修改一处
4.2 异步执行优势
操作 同步执行时间 异步执行时间 提升效果 打开页面 2秒 0.5秒 75% 输入操作 1秒 0.3秒 70% 多测试并行 线性增长 并行执行 300%+ 4.3 可重用性设计
# 在不同测试中重用业务函数 async def test_order(async_driver): await get(async_driver) await login(async_driver) # 添加订单测试代码 await logout(async_driver)
五、最佳实践建议
-
参数化默认值:
async def login(async_driver, username: str = DEFAULT_USER, password: str = DEFAULT_PASS):
-
元素定位器集中管理:
USERNAME_FIELD = ('id', 'ctl00_MainContent_username') await async_driver.send_keys(*USERNAME_FIELD, text=username)
-
添加操作等待:
from selenium.webdriver.support.ui import WebDriverWait await WebDriverWait(async_driver, 10).until(element_visible(USERNAME_FIELD))
-
错误处理增强:
async def safe_login(async_driver): try: await login(async_driver) except LoginException: await handle_login_failure()
这种异步测试开发模式通过将业务操作、测试验证和测试执行分层设计,显著提高了测试代码的可维护性和执行效率。
六、完整代码
""" Python :3.13.3 Selenium: 4.31.0 async_test_func.py """ async def get(async_driver, url: str = 'http://secure.smartbearsoftware.com/samples/testcomplete12/WebOrders/Login.aspx'): await async_driver.get(url) async def login(async_driver, username: str = 'Tester', password: str = 'test'): await async_driver.send_keys('id', 'ctl00_MainContent_username', text=username) await async_driver.send_keys('id', 'ctl00_MainContent_password', text=password) await async_driver.click('name', 'ctl00$MainContent$login_button') async def search(async_driver): await async_driver.click('xpath', '//*[@id="ctl00_menu"]/li[3]/a') await async_driver.send_keys('id', 'ctl00_MainContent_fmwOrder_txtName') await async_driver.click('id', 'ctl00_MainContent_fmwOrder_InsertButton') async def logout(async_driver): await async_driver.click('xpath', '//*[@id="ctl00_logout"]') async def test_login(async_driver): await get(async_driver) await login(async_driver) assert await async_driver.text('xpath', '//*[@id="aspnetForm"]//td[1]/h1') == 'Web Orders' await logout(async_driver) async def test_search(async_driver): await get(async_driver) await login(async_driver) await search(async_driver) assert await async_driver.text('id', "ctl00_MainContent_fmwOrder_RequiredFieldValidator3") == "Field 'Street' cannot be empty." await logout(async_driver)
「小贴士」:点击头像→【关注】按钮,获取更多软件测试的晋升认知不迷路! 🚀
(图片来源网络,侵删)(图片来源网络,侵删)(图片来源网络,侵删) -
- 测试流程:
- 测试流程:
- 操作流程:
- 操作步骤:
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。