4 Star 25 Fork 13

嘉诚开源 / jc-uitest

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.md 17.02 KB
一键复制 编辑 原始数据 按行查看 历史
wangn1218 提交于 2022-02-28 08:00 . update README.md.

嘉诚UI自动化测试框架

框架介绍

嘉诚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。

本地部署

  • 用VSCode或Pycharm打开本地项目代码,根目录下的requirements.txt文件中有UI自动化测试所用的所有依赖包,终端中执行命令即可安装:
$ 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 功能模块名称\用例文件名称

说明:

  1. 控制台中可输出脚本执行成功及失败情况,具体失败原因可查看log文件或report;
  2. 执行脚本时,可在命令行中指定运行模式(headed/headless)、测试服务器地址、是否开启企业微信通知,若不指定,则按照config.py文件中默认配置执行。如:python run.py testCases mode:headed server_address:http://uitest.jcinfo.com notice_status:True。

部署测试工程

UI自动化测试工程中,根据测试工程在测试服务器中的路径,修改gitlab-ci.yml文件

gitlab-ci

执行测试及结果通知

执行测试

  • 本地执行:在编辑器的终端中执行命令即可实现本地执行,如执行:python run.py testCases;
  • 服务端构建执行:通过配置DevOps实现自动构建并执行;
  • 定时执行:请联系产品支持和质控中心团队,在服务端设置执行测试的定时任务。

企业微信配置群机器人

UI自动化测试用例代码提交至gitlab,流水线构建完毕后,测试服务器每日定时执行UI自动化测试,采用企业微信机器人通知模式,群机器人配置方法可参考如下:

bot01 bot02 bot03

配置config.py文件

  • max_fail:当达到最大失败数时,自动停止继续执行其余用例;
  • notice_status:是否开启企业微信通知,开启企业微信通知时,设置为TRUE;否则,则不开启企业微信通知,用例运行完毕后不会发送企业微信进行通知;
  • chatbot_url:配置企业微信群机器人的Webhook地址;
  • product_name:执行UI自动化测试的产品名称(建议命名方式:产品名称+版本号,如:低代码开发平台V21.10版本);
  • project_name:项目名称(gitlab中代码仓库名称);
  • server_address:测试服务器地址(测试服务器ip地址+webserver端口号)。
modifyConfig

启动webserver服务

  • 若本地调试代码时,可不启动webserver服务,执行结果直接在report文件夹中查看;
  • 若需独立部署整个自动化测试环境,可启动webserver服务,消息通知中的报告地址可根据部署情况,在conftest.py中的“企业微信消息通知方法”中配置。

启动webserver服务方法:确认webserver使用的端口号(默认为8000,可根据情况修改)没有被占用后,进入webserver.py文件所在目录,执行以下命令:

#windows系统服务器上执行此命令
python webserver.py
 
#linux系统服务器上执行此命令(断开连接时,webserver不会中断)
nohup python3 webserver.py &

通知结果展示

按照以上方式配置完成后,在服务器或本地运行脚本,企业微信中将收到群机器人发送的UI自动化测试结果通知的消息,点击报告地址可查看本次测试报告的详细情况。

常用方法

常用断言

  • page.text_content("nav:first-child"):获取文本内容;
  • page.get_attribute("input", "alt"):获取属性值;
  • page.is_checked("input"):获取checkbox状态;
  • page.is_visible("input"):是否可见;
  • page.is_enabled("input"):是否可不输入。

更多断言方法可参考:https://playwright.dev/python/docs/assertions。

元素定位

  • path方式定位:page.click("xpath=//h2")或page.click("//h2")
  • 文本方式定位:page.click("text=退出登录")或page.click("'退出登录"')
  • CSS方式定位:page.click("css=h2")或page.click("h2")

更多元素定位方法可参考: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")))

常见问题及解决办法

浏览器驱动未安装或版本不正确

问题描述:若浏览器驱动未安装或版本不正确时,执行脚本时会报以下错误: problem01

解决办法:使用上文提到的命令,下载正确版本的浏览器驱动。

页面未加载完全,导致断言中获取元素内容失败

问题描述:运行用例时,由于操作过快,页面未加载完全,获取的断言不正确,导致脚本运行失败。

解决办法:引入sleep方法,在对应的操作步骤或断言前添加等待时间(等待时间以秒为单位)。

#引入sleep方法块
from time import sleep
 
#对应的操作步骤或断言前添加等待时间
sleep(2)
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/jiachengnet/jc-uitest.git
git@gitee.com:jiachengnet/jc-uitest.git
jiachengnet
jc-uitest
jc-uitest
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891