可参考:
使用Playwright+Pytest+Yaml+Allure搭建UI自动化测试用例框架_自动化测试框架playwright allure-优快云博客
1、UI自动化框架_结构目录及说明
- Python:核心编程语言,提供基础语法和丰富的第三方库支持。
- Playwright:浏览器自动化工具,实现跨浏览器网页操作与测试。同Selenium
- Pytest:测试框架,管理用例、断言及执行,支持扩展插件。
- Allure:可视化测试报告工具,生成结构化结果便于问题追溯。
- YAML:配置文件格式,结构化存储测试数据或环境参数。
- nb_log:Python日志库,提供灵活日志记录与多线程异步输出。
AutomatedTesting
├─ common 公共层包
├─ logs 日志文件
├─ pageElement 存放页面元素定位文件的文件夹目录
├─ testdata 测试用例数据
├─ testScripts 测试用例
├─ util 工具
├─ create_tree_with_args.py 用于生成指定目录结构树
├─ nb_log_config.py 日志模板配置脚本文件
├─ README.md ReadMe
└─ requirements.txt 依赖包及其精确的版本号
README.md
AutomatedTesting
├─ common 公共层包目录
│ ├─ page_action.py 封装常用页面组件的操作方法脚本
│ └─ __init__.py
├─ logs 存放所有自动化测试用例的运行日志文件夹目录
│ ├─ 20231120.log 一个log文件代表一天中所有的日志
│ └─ 20231121.log
├─ pageElement 存放页面元素定位文件的文件夹目录
│ ├─ ams_main_page_element.yml 定位文件命名应该能直观看出是代表系统中哪一个页面
│ ├─ login_page_element.yml
│ └─ main_page_element.yml
├─ testdata 存放测试用例运行中输入的数据的文件夹目录
│ └─ login_test_data.yml 数据文件命名要能直观看出是用于哪个模块的测试用例
├─ testScripts 存放测试用例脚本的包目录
│ ├─ allure-report 所有测试用例的运行结果报告文件夹--结果统计报告是html格式
│ ├─ allure_result 所有测试用例的运行结果数据文件夹--结果数据文件是json格式
│ ├─ test-results 存放所有测试用例运行结果的截图和录屏数据
│ ├─ conftest.py 主要用来定义一些fixture前后置方法
│ ├─ run.py 运行项目中所有测试用例并生成报告
│ ├─ test_iotdevicelist.py 测试用例--命名规则必须以“test”开头
│ ├─ test_mainpagefunc.py
│ └─ __init__.py
├─ util 定义实用工具的包目录
│ ├─ dirAndTime.py 获取当前时间和获取当前日期
│ ├─ handle_logging.py 生成运行日志
│ ├─ handle_yaml.py 读取yml格式文件中的数据
│ └─ __init__.py
├─ create_tree_with_args.py 用于生成指定目录结构树
├─ nb_log_config.py 日志模板配置脚本文件
├─ README.md ReadMe
└─ requirements.txt 用于记录所有依赖包及其精确的版本号,以便新环境部署
2、安装软件库
1. 安装python
如果你的电脑已经装有python且是3.8以上版本请跳过本章
打开浏览器并访问Python官网,下载windows版安装程序:https://www.python.org
下载好安装包后,右击“以管理员身份运行”,在安装对话框中勾选“Add python.exe to PATH”,选择“Customize installation”来自定义一个python安装路径(注意:安装路径中不要有中文目录,需要所有目录是纯英文的),选择好安装路径后点击[Install]
安装完成后,点击“禁用路径长度限制”,然后点击[关闭]
再单击[关闭]按钮,即可结束安装
校验是否安装成功:使用快捷键“WIN+R”打开运行窗口,输入“cmd”,单击[确定]打开命令窗口,输入命令“python --version”(有的windows系统输入“python -V”),会看到安装的python版本号输出,这个时候就说明完全安装好了。
2. 安装Pycharm(社区版)
打开浏览器访问Pycharm官网:
Download PyCharm: The Python IDE for data science and web development by JetBrains
下载完毕后,根据安装向导安装即可:
选择安装路径,注意:安装路径中不要有中文目录,需要所有目录是纯英文的
建议全部勾选
点击install
安装完成后点击Finish
这时候桌面已经有pycharm快捷方式,双击快捷方式,打勾并点击继续
点击加号”+”,创建一个新项目
选择项目路径,默认C盘,我这里自定义选择,选择完毕后,最后点击Create
选择需要运行的.py文件,单击右键-run
结果如下则表示配置成功
3. 安装Java、Allure
1)安装Java
首先需要下载java开发工具包jdk,下载地址:
https://www.oracle.com/java/technologies/downloads/archive/,这里显示各种版本的jdk,建议下载1.8及以上的版本
点进去之后拉最下面选择Windows x64名字开头的安装包下载,下载时需要登录Oracle账户(没有就注册一个)。
下载完成后右击安装包->使用管理员方式运行,安装过程中可以自定义安装目录并记住安装路径(后面需要使用其配置环境变量)。注意:安装路径中不要有中文目录,需要所有目录是纯英文的
安装完成后右击“我的电脑”点击“属性”,选择“高级系统设置”
点击环境变量按钮,打开环境变量编辑窗口,在系统变量区域新建JAVA_HOME变量:
变量名:JAVA_HOME 变量值:上面的jdk安装路径(绝对路径)
再新建CLASSPATH变量:变量名:CLASSPATH 变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar
在系统变量中找到Path变量点击[编辑]按钮,打开编辑环境变量窗口,点击[新建]按钮,在底部增加一个输入框,输入%JAVA_HOME%\bin,再次点击[新建]按钮,再增加一个输入框,输入%JAVA_HOME%\jre\bin
一路点击[确定]按钮直到关掉所有环境变量设置窗口。配置完成后,右击电脑左下角windows系统图标->“运行”,输入“cmd”,在命令窗口中输入“java”回车
再输入“java -version”回车
输入以上命令回车后出现如图所示文字即代表java安装成功。
2)安装allure
由于allure需要依赖java环境,所以在上节就说明了jdk安装,接着就要下载allure包并配置环境变量:allure包下载地址:Releases · allure-framework/allure2 · GitHub
我们下载windows版的zip压缩包即可
在本地解压下载好的allure包,解压后有4个文件夹,复制bin文件夹目录路径,并用其设置allure环境变量,添加到Path变量中:
运行“cmd”打开cmd命令窗口,输入:allure --version 出现下图所示版本号即代表安装成功
4. 安装库
1. 初步使用
pip install pyaml
pip install playwright
playwright install chromium
pip install allure-pytest
pip install pytest
pip install pytest-playwright
pip install nb_log -i https://mirrors.aliyun.com/pypi/simple
可选的镜像地址有
豆瓣 https://pypi.douban.com/simple
阿里云 https://mirrors.aliyun.com/pypi/simple
清华大学 https://pypi.tuna.tsinghua.edu.cn/simple
中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple
2. 详细使用
在本地写一个requirements.txt文本文件,放在上面已创建项目的根目录下,打开cmd命令窗口进入requirements文件所在路径,执行安装第三方库的命令:
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
-i 参数代表从指定镜像源下载
这个命令的意思是从国内镜像网站下载安装requirements.txt这个文件中所有的库。
全部下载完成后,在命令窗口输入:pip list 即可看到已经安装好的库名及版本
然后执行playwright install命令安装自动化运行所需的浏览器,Playwright介绍见官网:Installation | Playwright Python
建议大家平时多研究playwright官网,官网手册全面且简单易学,使用微软的Edge浏览器访问官网可以翻译成中文。为后续手写测试用例脚本打下基础。
另一个学习网站:什么是playwright?-playwright-何三笔记
PS:安装过程中如果一直安装不成功的话,说明你安装的python版本比较高,有些第三方库难以适配到,那么请卸载该python,重新下载安装较低版本的python,推荐3.9\3.10左右的版本。
3、common公共层包
1. 浏览器启动方法封装browser_manager.py
from playwright.sync_api import sync_playwright
class BrowserManager:
def __init__(self):
self.playwright=None
self.browser=None
self.page=None
def launchChrome(self,headless=False, channel="chrome"):
"""
launchChrome为无头模式下启动谷歌浏览器
:param headless:
:param channel:
:return:
"""
self.playwright = sync_playwright().start()
self.browser = self.playwright.chromium.launch(headless=headless, channel=channel)
self.page = self.browser.new_page()
return self.page
def close(self):
"""
关闭浏览器、关闭playwright
"""
self.browser.close()
self.playwright.stop()
# 检验是否可以使用playwright
# if __name__ == "__main__":
# # 使用示例
# BrowserManager = BrowserManager()
# try:
# page =BrowserManager.launchChrome()
# # 访问网页并执行操作
# page.goto("https://www.baidu.com/")
# print("当前标题:", page.title())
# page.wait_for_timeout(2000) # 等待2秒查看效果
#
# finally:
# BrowserManager.close()
4、logs日志文件
1)使用nb_log记录日志,配置logger
import os
import time
import logging
from nb_log import LogManager
# 获取项目根目录(更可靠的获取方式)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
LOG_DIR = os.path.join(BASE_DIR, 'logs') # 日志目录定义
# 确保日志目录存在
os.makedirs(LOG_DIR, exist_ok=True)
def get_logger():
"""单例模式获取 Logger 对象"""
logger_name = __name__ # 使用模块名作为 Logger 名称
log_filename = f"{time.strftime('%Y%m%d')}.log" # 按日期命名日志文件
# 创建 Logger 并配置处理器
logger = LogManager(logger_name).get_logger_and_add_handlers(
log_level_int=logging.DEBUG, # 使用常量提高可读性
is_add_stream_handler=True, # 启用控制台输出
log_path=LOG_DIR, # 直接使用 LOG_DIR
log_filename=log_filename, # 动态生成文件名
formatter_template=logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
)
return logger
# 全局唯一 Logger 实例
test_log = get_logger()
if __name__ == "__main__":
# 测试日志输出
test_log.debug("Debug 信息(测试)")
test_log.info("Info 信息(测试)")
2)使用实例
from util.handle_logging import test_log # 引入函数
# 特定位置标记插入即可
test_log.info("成功登录系统")
test_log.error("登录识别")
test_log.debug("调试内容")
test_log.warnning("提示内容")
3)报错解决(已安装包,仍提示未安装)
set PYTHONPATH=项目根目录
5、pageElement页面元素定位文件
6、testdata测试用例数据
7、testScripts测试用例
1. 测试用例test_001
import pytest
def test_001(page):
page.goto("https://www.baidu.com/")
print("当前标题:", page.title())
page.wait_for_timeout(2000) # 等待2秒查看效果
2. 正式用例
待补充...
8、util工具包
9、create_tree_with_args.py 用于生成指定目录结构树
生成目录说明:运行此脚本,复制控制台打印内容到readme.md即可
#! -*-conding=: UTF-8 -*-
# 2023/11/22 9:52
"""
描述:python实现tree命令
"""
from pathlib import Path
import argparse
from typing import Optional
# 黑名单 不想列出的目录
blacklist = [".git", ".idea"]
# ANSI颜色代码
BLUE = "\033[34m"
WHITE = "\033[0m"
def is_hidden(file: Path) -> bool:
return file.name.startswith(".")
def get_entries(path: Path, show_hidden: bool = False):
entries = list(path.iterdir())
if not show_hidden:
entries = [entry for entry in entries if not is_hidden(entry)]
return sorted(entries, key=lambda entry: entry.is_file())
def print_tree(path: Path, depth: Optional[int], show_hidden: bool = False, indent: str = "", is_last: bool = True):
entries = get_entries(path, show_hidden)
total_entries = len(entries)
for i, entry in enumerate(entries):
is_dir = entry.is_dir()
entry_name = entry.name
if i == total_entries - 1:
branch = "└─ "
new_indent = indent + " " if is_last else indent + "│ "
else:
branch = "├─ "
new_indent = indent + "│ "
if is_dir:
print(f"{indent}{branch}{BLUE}{entry_name}{WHITE}")
if depth is None or (depth and depth > 1):
print_tree(entry, None if depth is None else depth - 1, show_hidden, new_indent, i == total_entries - 1)
else:
print(f"{indent}{branch}{entry_name}")
def main():
parser = argparse.ArgumentParser(description="Python实现tree命令")
parser.add_argument("-p", "--path", type=str, nargs="?", default=".", help="要遍历的目录路径")
parser.add_argument("-d", "--depth", type=int, help="限制显示的层数")
parser.add_argument("--hidden", action="store_true", help="显示隐藏文件")
args = parser.parse_args()
path = Path(args.path).resolve()
print(path)
print_tree(path, args.depth, args.hidden)
if __name__ == "__main__":
# 在终端窗口输入命令:python create_tree_with_args.py -d 3
# 这个命令表示打印当前工程目录结构,且深度是3层,层数可以自定义
main()
10、nb_log_config.py日志模板配置脚本文件
11、README.md
使用create_tree_with_args.py生成
12、requirements.txt依赖包及其精确的版本号
13、执行命令run.py
# 控制台执行命令:
python -m pytest -sv
集成后执行命令待补充...
14、fixture初始化、清除- conftest.py
可参考:
python3.x中 pytest之fixture - 漂泊的小虎 - 博客园
fixture
是指夹具(把用例夹在中间),它包括前置工作和后置工作,前置是用例代码的准备阶段,后置是用例执行之后的清理阶段,用例是放在前置代码和后置代码
使用fixture来创建对象,启动浏览器,运行结束后再进行清除
import pytest
from common.browser_manager import BrowserManager
@pytest.fixture(scope="function")
def page():
"""
函数初始化打开浏览器,函数结束后清除
初始化、清除分别在前后执行,并且只会执行1次
:return:
"""
browser_manager = BrowserManager()
try:
browser_page = browser_manager.launchChrome()
yield browser_page
finally:
browser_manager.close()
15、报错解决
1. 解决 AttributeError: 'str' object has no attribute 'iter_parents'
的步骤
问题原因
- 版本冲突:
pytest
8.1.0 及以上版本与某些插件(如allure-pytest
或pytest-xdist
)的兼容性被破坏,导致访问item.nodeid
时触发iter_parents
方法缺失的错误31。
解决方案:降级 pytest
到兼容版本
# 卸载当前版本 pip uninstall pytest
# 安装指定兼容版本 pip install pytest==8.0.2