pytest+uiautomation+allure Excel 数据驱动桌面自动化
一、安装依赖
bash
pip install pytest uiautomation allure-pytest openpyxl
openpyxl 专门读写xlsx 格式Excel
二、调整项目结构
Plain
desktop_automation/
├── config/setting.py
├── data/
│ └── case_data.xlsx # Excel测试数据
├── common/
│ └── read_excel.py # 封装读取Excel工具类
├── page/
│ ├── base_page.py
│ └── notepad_page.py
├── testcase/test_notepad.py
├── conftest.py
└── pytest.ini
三、Excel 测试数据格式
新建 data/case\_data\.xlsx,工作表名:input\_data
| case_name | input_content | expect_content |
|---|---|---|
| 普通文本输入 | 桌面自动化 Excel 数据驱动 | 桌面自动化 Excel 数据驱动 |
| 特殊字符输入 | 123@#$ 测试 | 123@#$ 测试 |
| 空值输入 | ||
| 长文本输入 | 基于 pytest+uiautomation 做桌面 UI 自动化 | 基于 pytest+uiautomation 做桌面 UI 自动化 |
四、封装 Excel 读取工具 common/read\[_excel.py](_excel.py)
python
from openpyxl import load_workbook
class ReadExcel:
@staticmethod
def get_excel_data(file_path, sheet_name):
"""
读取Excel用例数据,返回列表字典格式
:param file_path: excel路径
:param sheet_name: 工作表名
:return: [{},{},...]
"""
wb = load_workbook(filename=file_path)
ws = wb[sheet_name]
# 获取表头
headers = [cell.value for cell in ws[1]]
data_list = []
# 遍历行数据,跳过表头
for row in ws.iter_rows(min_row=2, values_only=True):
row_dict = dict(zip(headers, row))
data_list.append(row_dict)
wb.close()
return data_list
五、配置文件 config/[setting.py](setting.py)
python
# 被测应用
APP_PATH = "notepad.exe"
# 全局等待
IMPLICIT_WAIT = 3
# Excel数据路径
EXCEL_DATA_PATH = "./data/case_data.xlsx"
# Excel工作表名
EXCEL_SHEET = "input_data"
六、页面层代码不变
base\[_page.py](_page.py) 不变
notepad\[_page.py](_page.py) 不变
七、Excel 数据驱动测试用例 testcase/test\[_notepad.py](_notepad.py)
python
import pytest
from common.read_excel import ReadExcel
from page.notepad_page import NotePadPage
from config.setting import APP_PATH, EXCEL_DATA_PATH, EXCEL_SHEET
# 读取Excel所有测试数据
def get_excel_case_data():
return ReadExcel.get_excel_data(EXCEL_DATA_PATH, EXCEL_SHEET)
class TestNotePadExcelDDT:
def setup_class(self):
self.page = NotePadPage()
self.page.start_app(APP_PATH)
def teardown_class(self):
self.page.close_app()
# Excel数据驱动参数化
@pytest.mark.parametrize("case", get_excel_case_data(), ids=lambda x: x["case_name"])
def test_input_by_excel(self, case):
"""Excel数据驱动-记事本输入测试"""
in_text = case["input_content"]
exp_text = case["expect_content"]
self.page.input_edit_content(in_text)
actual = self.page.get_edit_content()
assert actual == exp_text, f"失败:预期{exp_text},实际{actual}"
八、[conftest.py](conftest.py) 失败截图不变
python
import pytest
import allure
import uiautomation as auto
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
report = outcome.get_result()
if report.when == "call" and report.failed:
try:
img = auto.CaptureToImage()
allure.attach(img, "失败截图", allure.attachment_type.PNG)
except:
pass
九、pytest.ini 不变
ini
[pytest]
testpaths = testcase
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts = -vs --alluredir=./report/temp --clean-alluredir
十、运行命令
bash
# 执行用例
pytest
# 生成并打开allure报告
allure generate ./report/temp -o ./report/html --clean
allure open ./report/html
十一、扩展用法
- 增加用例状态控制
Excel 新增列is\_run,值为1执行,0跳过
读取数据时过滤:
python
data_list = [d for d in data_list if d.get("is_run") == 1]
-
区分正向 / 逆向用例
Excel 加
case\_type字段,用例内做不同业务逻辑 -
登录场景直接套用
Excel 填账号、密码、预期结果,页面写登录方法即可
十二、注意事项
-
只支持 .xlsx,不支持老版.xls
-
Excel 表头名称必须和代码取值字段完全一致
-
空单元格读取为
None,代码可自行转为空字符串