嘉诚ui自动化测试框架集成了playwright和pytest,提供简单、快捷、可视化的用例录制手段,以及结果统计、报告生成、持续构建等特性,实现UI自动化测试的全链路解决方案。
软件 | 版本 | 备注 |
---|---|---|
操作系统 | win7及以上; centos7及以上 | centos系统要求:CLIBC版本为2.18+,字符集为zn_CN.UTF8 |
python | v3.7+ | |
pip/pip3 | v22.0.3+ |
PS:可使用命令:python -m pip install --upgrade pip,升级pip/pip3版本。
将UI自动化框架代码下载到本地,gitee地址:https://gitee.com/jiachengnet/jc-uitest。
$ pip install -r requirements.txt
python -m playwright install
说明:以上步骤操作完毕后,可在本地运行测试框架自带的测试用例,检验环境是否安装成功。
jc-uitest # UI自动化测试工程
├── logs # 脚本执行日志
├── testCases # 测试用例存放路径
│ ├── login # 功能模块名
│ └── test_login.py # UI测试用例-登录系统
│ ├── test_baidu.py # UI测试用例-访问百度
│ └ ──data.json # 存放参数化的数据(若不使用参数化,此文件可忽略)
├── tools # 存放公共方法的目录
├── report # 每次运行均可在此目录下生成测试报告,包含:错误日志时的屏幕截图、html格式的报告
├── requirements.txt # 所有UI自动化测试实施时所需的依赖环境
├── config.py # UI自动化测试框架的配置文件,可配置浏览器驱动类型等
├── conftest.py # UI自动化测试框架的自带的底层方法
├── webserver.py # 启动后可通过点击企业微信通知中报告地址查看测试报告内容
└── run.py # 批量运行全部/部分用例
配置名称 | 说明 | 默认值 | |
---|---|---|---|
1 | browser | 浏览器驱动类型,支持chromium, firefox, webkit | browser = "chromium" |
2 | mode | 用例运行模式,包括headless和headedheadless:无头模式,运行用例时不弹出浏览器;headed:有头模式,运行用例时,弹出浏览器 | mode = "headless" |
3 | rerun | 失败重跑次数 | rerun = "0" |
4 | fail | 当达到最大失败数,停止执行 | max_fail = "5" |
5 | notice_status | 是否开启企业微信消息通知。开启企业微信通知时,设置为TRUE;否则,则不开启企业微信通知 | notice_status=True |
6 | chatbot_url | 企业微信机器人地址 | |
7 | product_name | 产品名称及版本号 | product_name="嘉城中台v21.10版本" |
8 | project_name | 项目名称(gitlab项目名称) | project_name = "jcmp_uitest" |
9 | server_address | 测试报告地址(测试服务器ip地址+webserver端口号) | server_address = "http://172.31.6.10:8000" |
"""
编写人
编写时间
"""
#引入脚本所用的模块
import os
import sys
import time
from playwright.sync_api import Page
import pytest
from os.path import dirname, abspath
from tools.get_log import GetLog
from tools.read_json import get_data
#指定参数化文件路径
logincommon_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
sys.path.insert(0, logincommon_path)
logger = GetLog.get_log()
#添加装饰器,实现测试用例参数化
@pytest.mark.parametrize(
"url,loginname,password",
get_data(logincommon_path + "/data.json","login")
)
#定义测试用例中使用的方法,引用参数化文件中的参数
def test_login(page: Page, url,loginname, password):
"""
用例名称:用户中心登录;
用例步骤:
1)输入用户中心地址,访问用户中心;
2)输入用户名、密码。点击登录按钮;
3)登录成功后,判断系统名称是否为“嘉城开发平台”;
4)点击退出登录
"""
#获取当前正在执行的测试用例名称,以日志形式打印出来
casename = os.path.splitext(os.path.basename(__file__))[0]
logger.info("正在执行用例:{}".format(casename))
#以下为测试用例中具体的操作步骤
# Go to http://test-env.jcinfo.com/jcdp/
page.goto(url)
# Click [placeholder="请输入账号"]
page.click("[placeholder=\"请输入账号\"]")
# Fill [placeholder="请输入账号"]
page.fill("[placeholder=\"请输入账号\"]", loginname)
# Click [placeholder="请输入密码"]
page.click("[placeholder=\"请输入密码\"]")
# Fill [placeholder="请输入密码"]
page.fill("[placeholder=\"请输入密码\"]", password)
# Click input[type="submit"]
# with page.expect_navigation(url="http://test-env.jcinfo.com/jcmms/#/404"):
with page.expect_navigation():
page.click("input[type=\"submit\"]")
# 添加断言:系统登录成功后,获取并判断浏览器标题是否为“嘉诚开发平台”,如果不是,则抛出异常
try:
assert "嘉诚开发平台" == page.text_content(".avue-logo_title")
logger.info("用例{}的断言结果为{}".format(casename, "嘉诚开发平台" == page.text_content(".avue-logo_title")))
except Exception as e:
logger.error("用例{}的断言结果为{},错误信息是:{}".format(casename, "嘉诚开发平台" == page.text_content(".avue-logo_title"), e))
raise
# Click span[role="button"]
page.click("span[role=\"button\"]")
# Click text=退出登录
page.click("text=退出登录")
# Click [aria-label="提示"] button:has-text("确定")
with page.expect_navigation():
page.click("[aria-label=\"提示\"] button:has-text(\"确定\")")
# Close page
page.close()
在cmd或编辑器的终端中,进入到UI自动化测试工程的testCases目录;
执行录制命令,如:浏览器输入地址为http://test-env.jcinfo.com/jcdp,将录制生成的文件名称指定为test_userCenter_login.py,可输入以下命令
python -m playwright codegen -o test_userCenter_login.py http://test-env.jcinfo.com/jcdp
录制完毕后关闭浏览器,录制内容可自动保存至文件中,内容如下:
from playwright.sync_api import Playwright, sync_playwright
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
# Open new page
page = context.new_page()
# Go to http://test-env.jcinfo.com/jcdp/
page.goto("http://test-env.jcinfo.com/jcdp/")
# Click [placeholder="请输入账号"]
page.click("[placeholder=\"请输入账号\"]")
.....
# Close page
page.close()
# ---------------------
context.close()
browser.close()
with sync_playwright() as playwright:
run(playwright)
双击录制生成的脚本文件可以回放整个录制过程,检查是录制内容是否正确。
说明:UI自动化测试用例文件名称需以“test_”开头,否则工程中将不会执行此用例。
使用pycharm或VSCode打开UI自动化测试工程,在录制好的脚本最上方,添加引入工程包的语句(不需要修改,直接复制即可)
import os
import sys
import time
import pytest
from playwright.sync_api import Page
from os.path import dirname, abspath
from tools.get_log import GetLog
from tools.read_json import get_data
测试用例中经常使用的变量(如:网址、用户名、密码等),可放在testCases目录下得data.json文件中,每个测试用例均可引用此变量作为方法的参数使用。若用例需要更换用户名及密码进行登录,则不需要修改用例本身,可直接修改data.json文件中的参数值即可。
如:将登录时使用的网址、用户名、密码配置在testCases\data.json文件中
{
"login":
[
{
"url":"http://test-env.jcinfo.com/jcdp/",
"loginname": "super",
"password": "admin12345"
}
]
}
在测试用例文件中,定义方法上方增加指定参数化文件路径及参数注入的语句(不需要修改,直接复制即可):
logincommon_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
sys.path.insert(0, logincommon_path)
logger = GetLog.get_log()
@pytest.mark.parametrize(
"url,loginname,password",
get_data(logincommon_path + "/data.json","login")
)
在测试用例文件中,定义方法时传入并使用用户名参数、密码参数(定义方法后,在注释中说明测试用例名称及步骤):
def test_login(page: Page,url, loginname, password):
"""
用例名称:按照登录账户查询用户;
用例步骤:
1)登录系统;
2)进入用户中心-系统管理-用户管理页面;
3)登录账户查询条件中输入“super”,点击查询;
4)点击退出登录
"""
# Go to http://test-env.jcinfo.com/jcdp/
page.goto(url)
# Click [placeholder="请输入账号"]
page.click("[placeholder=\"请输入账号\"]")
# Fill [placeholder="请输入账号"]
page.fill("[placeholder=\"请输入账号\"]", loginname)
# Click [placeholder="请输入密码"]
page.click("[placeholder=\"请输入密码\"]")
# Fill [placeholder="请输入密码"]
page.fill("[placeholder=\"请输入密码\"]", password)
# Click input[type="submit"]
with page.expect_navigation():
page.click("input[type=\"submit\"]")
说明: 测试用例文件若不使用参数化方式对变量进行设置,则变量值发生变化时直接在测试用例文件中修改即可。
在录制生成的脚本中,需要根据用例添加对应的断言
#系统登录成功后,获取并判断浏览器标题是否为“嘉诚开发平台”,如果不是,则抛出异常
assert "嘉诚开发平台" == page.text_content(".avue-logo_title")
录制生成的脚本中,需要将以下代码注释或删除,脚本才可运行成功。
# browser = playwright.chromium.launch(headless=False)
# context = browser.newContext()
# page = context.newPage()
# context.close()
# browser.close()
# with sync_playwright() as playwright:
# run(playwright)
$ python run.py testCase
$ python run.py 功能模块名称
$ python run.py 功能模块名称\用例文件名称
说明:
UI自动化测试工程中,根据测试工程在测试服务器中的路径,修改gitlab-ci.yml文件
UI自动化测试用例代码提交至gitlab,流水线构建完毕后,测试服务器每日定时执行UI自动化测试,采用企业微信机器人通知模式,群机器人配置方法可参考如下:
启动webserver服务方法:确认webserver使用的端口号(默认为8000,可根据情况修改)没有被占用后,进入webserver.py文件所在目录,执行以下命令:
#windows系统服务器上执行此命令
python webserver.py
#linux系统服务器上执行此命令(断开连接时,webserver不会中断)
nohup python3 webserver.py &
按照以上方式配置完成后,在服务器或本地运行脚本,企业微信中将收到群机器人发送的UI自动化测试结果通知的消息,点击报告地址可查看本次测试报告的详细情况。
更多断言方法可参考:https://playwright.dev/python/docs/assertions。
更多元素定位方法可参考:https://playwright.dev/python/docs/selectors。
在定义方法上方添加以下语句(不需要修改,直接复制即可)
logger = GetLog.get_log()
在定义方法后,获取当前用例名称,输出显示在日志中;
断言中也需要输出日志,描述失败原因,如:
#获取当前用例名称,打印在日志中
casename = os.path.splitext(os.path.basename(__file__))[0]
logger.info("正在执行用例:{}".format(casename))
#断言中输出日志,描述失败原因
logger.info("用例{}的断言结果为{}".format(casename, "嘉诚开发平台" == page.text_content(".avue-logo_title")))
问题描述:若浏览器驱动未安装或版本不正确时,执行脚本时会报以下错误:
解决办法:使用上文提到的命令,下载正确版本的浏览器驱动。
问题描述:运行用例时,由于操作过快,页面未加载完全,获取的断言不正确,导致脚本运行失败。
解决办法:引入sleep方法,在对应的操作步骤或断言前添加等待时间(等待时间以秒为单位)。
#引入sleep方法块
from time import sleep
#对应的操作步骤或断言前添加等待时间
sleep(2)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。