本文作者:欧海锋,碧桂园服务高/级测试工程师,致力于研究测试技术。
注:本文档所有操作均基于 macOS 系统。
1 项目背景
当前 IT 项目的测试工作主要采用接口自动化及手工操作两种方式,其中手工测试方式耗时长、易出错,而且界面验证还依赖人工进行操作。基于此,我们考虑引入相应的 UI 自动化测试工具进行辅助测试。通过将稳定的项目功能实现 UI 自动化,可以提高测试回归验证的效率和准确性。
借此次工具调研的契机,我们将工具用于场地系统,以评估工具对项目带来的测试价值和效率提升情况。
2 UI 自动化工具对比
当前比较流行的 UI 自动化工具有 Playwright 和 Selenium,它们都拥有丰富的功能和 API,适用于测试 Web 应用程序。我们可以根据不同的需求和场景,选择合适的自动化测试工具。以下是这两个工具的对比情况:
基于上述的对比项,不难看出:
Playwright 相对容易学习,对使用人员的技术要求较低。
Playwright 的录制生成脚本功能可以显著提高 UI 自动化实现的效率。
Playwright 提供的功能更加全面,执行效率更高。
Playwright 拥有更突出的性能优势。
因此,在本次项目实践中,我们选用的是更加简单容易的 Playwright。
3 Playwright+ Pytest 实战
注:本项目实践基于场地系统进行。
3.1 前置准备
python 3.7+
python 三方库 Playwright(pip install playwright)
playwright 浏览器驱动安装(python -m playwright install)
注:下载资源缓慢请更换 pip 源为国内源
3.2 项目架构
codegen_data:录制的脚本存放。
common:公用方法存放。
data:测试数据存放。
log:脚本运行产生的日志存放。
test_case:测试用例脚本存放。
test_report:测试报告存放。
config.py:命令/路径等配置信息文件。
conftest.py:setup 执行的操作存放。
myRunner.py:执行 main。
3.3 录制脚本
① PC 端实操
命令行工具执行命令:
python -m playwright codegen -o 'test_login.py' --target python -b chromiumhttps://cas-test.bgyfw.com/idp/authcenter/ActionAuthChain?entityId=BIZTEST
让我们一起解读一下命令的意图:
使用当前计算机的 Chromium 打开指定 URL,生成的脚本语言为 python,保存名称为 test_login.py。
根据命令执行后进入的界面,可以发现:
当鼠标滑过元素的时候,会自动提示元素的 xpath。
启动的是无痕浏览模式,可以很容易和本地浏览的页面进行区分。
同时也会打开一个 Playwright Inspector 的窗口,显示生成的代码,以便对页面进行实时操作。
关闭浏览器时,将停止录制并输出脚本文件。从这里可以看出,脚本文件正是上述命令中指定的文件名。这里使用的是同步模式,生成代码:
生成的代码可以直接运行,运行后会自动打开 Chromium 浏览器执行相应的页面操作。
到这里我们有一个疑问:Playwright 是否支持主流的浏览器?我们如何切换到浏览器?
让我们再次查看执行的命令,发现其中有一个参数【-b】,用于指定浏览器。再看看说明:
-b, --browserbrowser to use, one of cr, chromium, ff, firefox, wk, webkit (default: "chromium")
从上述说明中可以看到,参数【-b】支持 Google Chrome、Microsoft Edge(cr,chromium)、 WebKit 内核的 Apple Safari ( wk, webkit)和 Mozilla Firefox(ff,firefox)浏览器。
让我们基于每一个浏览器都录制生成一份代码:
我们可以发现不同的浏览器在操作上是相似的,生成的代码有一个地方有所不同,如上图红框所示。换个角度来说,我们只需要基于一个浏览器生成代码后,手动修改就能实现浏览器兼容测试和代码的复用,极大地提升了效率。
② 移动端网页实操
命令行工具执行命令:
python -m playwright codegen -o 'test_login.py' --target python -b chromium --device="iPhone 12 Pro"https://cas-test.bgyfw.com/idp/authcenter/ActionAuthChain?entityId=BIZTEST
对比 PC 端实操执行的命令,当前命令多入参了一个参数【--device】
让我们一起解读一下命令的意图:
模拟 iPhone 12 Pro 设备打开指定 URL,使用 Chromium 驱动,生成的代码语言设置为 python,保存名称为 test_login.py。
以上为命令执行后进入的界面,可以发现录制的界面与 iPhone 12 Pro 打开的网页一致。这不禁让我们产生了一个想法:项目的手机界面兼容测试是不是可以通过 Playwright 解决?
答案是可以的!
Playwright 支持的手机/平板型号共有 116 种,基本覆盖了 50%左右的主流设备,具体如下图所示:
让我们抽几个手机型号录制各生成一份代码:
我们可以发现,不同的手机在相同的操作下,生成的代码只有两行不同,如上图红框所示。
换个角度来说,我们只需要基于一个手机型号生成代码后,手动修改一下就能实现手机浏览器兼容测试和代码的复用,这将大大提升效率。
3.4 conftest 应用
在 pytest 中,除了提供现成的 setup 和 teardown 方法,还提供了 conftest 文件结合 fixture 的方法来处理测试用例的前置条件和后置条件的操作。
conftest 简介:conftest 是一个固定的 py 文件,修改为其他名字不会生效。
conftest 作用域:作用范围在该目录及其下的子目录。
conftest 作用:同目录下的测试用例文件运行前都会执行 conftest.py 文件,相当于一个前置文件。
conftest 实际应用如下图所示:
对比生成的两个脚本,发现前置的步骤均一致,我们可以把一致的部分提取出来做成 setup。
同时,根据 conftest 文件的作用,我们把前置操作在 conftest.py 用方法封装起来,如下图所示:
封装完成后对脚本进行简化处理。简化效果如下图所示:
从简化效果来看,可以发现 conftest.py 文件是不需要导入的,它在执行 pytest 的时候会自动查找并使用 conftest.py 文件。
3.5 断言运用
断言当前页面的标题是否是指定的页面标题
expect(page).to_have_title("碧桂园服务统一认证")
expect(page).to_have_title("增值平台")
断言元素是否存在当前页面
assert page.wait_for_selector('#app > section > div.layout-container > section > div > h4')
断言当前元素的文本是否跟预期一致
content = page.text_content('#app > section > div.layout-container > section > div > h4')
assert content == "欢迎使用社区资源管理平台~"
断言元素的文本是否是期望值
js_content = page.locator('#app > section > div.left-menu.wujie-left-menu > div > ul > div:nth-child(3) > li > div > span').text_content()
assert js_content == "客户管理"
断言点击复选框后,复选框为选中状态
page.locator("selector").first.click()
checked = page.is_checked('selector')
assert checked
断言点击取消选择后,复选框为空状态
page.get_by_role("button", name="取消选择").click()
checked = page.is_checked('selector')
assert checked == False
断言按钮原始状态为非激活状态
enabled = page.is_enabled('selector')
assert enabled == False
断言输入内容后,按钮状态变为激活状态
page.get_by_label("新增客户", exact=True).get_by_placeholder("请输入客户税号").click()
page.get_by_label("新增客户", exact=True).get_by_placeholder("请输入客户税号").fill("test")
enabled = page.is_enabled('selector')
assert enabled
3.6 批量执行生成测试报告
生成的测试脚本加上断言后,需要批量执行测试脚本并生成测试报告。
在给出的项目架构中,可以通过配置文件来控制需要执行的测试范围。
首先,在项目中的 common/config.py 中已经定义了测试用例的路径(case_path)为项目中的 test_case 文件夹。具体如下图所示:
然后,在项目根目录 config.py 文件中定义了一个名为 cases_path 的变量,该变量可用于指定具体的测试范围。我们可以选择定义一个文件夹,以便在执行的时候运行该文件夹下的所有测试脚本;或者指定一个 py 文件以进行单独执行。具体如下图所示:
最后,配置好测试范围后,可以开始执行测试。在项目根目录 myRunner.py 文件中,点击运行按钮即可批量执行测试并生成测试报告。
3.7 失败截图定位问题
如果用例执行失败了,要如何进行定位?
根据报告提供的失败截图功能,可以在生成的报告中看到相应的截图和报错信息,帮助我们快速定位问题并进行分析。
4 项目应用取得的成果
场地系统共有数千条测试用例,使用 Playwright 后,大部分测试用例实现了 UI 自动化,整体自动化率得到大幅提升。
随着 Playwright 的使用,场地项目的自动化率不断提高,测试的回归效率也在不断地提升。
5 总结
Playwright 是一个功能强大的自动化工具,可用于测试和浏览器兼容。它提供了丰富的功能,可以大大提高测试和自动化的效率和可靠性。
Playwright 的录制生成脚本功能解决了测试人员编写操作步骤代码的问题,通过精准的定位,测试人员只需要专注于如何断言即可。相比传统的纯代码,它极大地提升了效率并降低了对测试人员的代码能力要求。
Playwright 还解决了 UI 自动化脚本维护的难题,只需重新录制一份脚本、编排断言并移除旧的脚本即可实现维护。
此外,Playwright 还提供了许多适用于自动化的功能,只有在实践中才能更好地发挥其作用。