问题背景
在使用 pytest-html 生成测试报告时,如果测试用例名称或参数化数据包含中文,生成的 HTML 报告会出现乱码。常见的乱码形式有两种:
-
Unicode 转义形式 :
\u5355\u4e2a\u5546\u54c1\u5355\u4e2a\u6570\u91cf -
双重编码形式 :
å个ååå个æ°é
这两种乱码严重影响了测试报告的可读性,特别是在 Windows 环境下尤为常见。
问题分析
经过深入分析,发现 pytest-html 在 Windows 环境下存在两个编码问题:
1. 文件写入编码问题
html_report.py 中的 _save_report 方法使用默认编码写入文件,在 Windows 系统上默认使用 GBK 编码,导致 UTF-8 字符无法正确保存。
2. 内存编码处理问题
result.py 中的 TestResult 类在处理 report.nodeid 时,由于多次编码转换,导致 UTF-8 字符被双重编码,最终显示为乱码。
解决方案
环境说明
-
Python 版本:3.x
-
pytest-html 版本:3.2.0(已验证可行)
-
操作系统:Windows 10/11
修改步骤
第一步:定位插件安装目录
bash
# 查看 pytest-html 安装位置
python -c "import pytest_html; print(pytest_html.__file__)"
输出示例:
text
xx\envs\test\Lib\site-packages\pytest_html\__init__.py
插件目录为:xx\envs\test\Lib\site-packages\pytest_html\
第二步:修改 html_report.py(修复文件写入编码)
文件路径 :[插件目录]/html_report.py
找到 _save_report 方法(大约第 259 行),修改如下:
python
def _save_report(self, report_content):
dir_name = self.logfile.parent
assets_dir = dir_name / "assets"
dir_name.mkdir(parents=True, exist_ok=True)
if not self.self_contained:
assets_dir.mkdir(parents=True, exist_ok=True)
# 修改前(会导致编码错误)
# self.logfile.write_text(report_content)
# 修改后(明确指定 UTF-8 编码)
self.logfile.write_text(report_content, encoding='utf-8')
if not self.self_contained:
style_path = assets_dir / "style.css"
# 修改前
# style_path.write_text(self.style_css)
# 修改后
style_path.write_text(self.style_css, encoding='utf-8')
修改说明 :为所有 write_text 方法调用添加 encoding='utf-8' 参数,确保文件以 UTF-8 编码保存。
第三步:修改 result.py(修复内存编码)
文件路径 :[插件目录]/result.py
找到 TestResult 类的 __init__ 方法,修改如下:
python
class TestResult:
def __init__(self, outcome, report, logfile, config):
self.outcome = outcome
# 修改前(会导致双重编码)
# self.test_id = report.nodeid.encode("utf-8").decode("unicode_escape")
# 修改后(修复双重编码)
nodeid = report.nodeid
if isinstance(nodeid, str):
try:
# 将 Latin-1 编码的字符串解码为 UTF-8
nodeid = nodeid.encode('latin1').decode('utf-8')
except:
pass
self.test_id = nodeid
self.report = report
self.logfile = logfile
self.config = config
# ... 其余代码保持不变
修改说明 :使用 encode('latin1').decode('utf-8') 修复双重编码问题,将错误的 Latin-1 编码字符串正确还原为 UTF-8。
验证修复
创建测试文件验证:
python
# test_chinese.py
import pytest
def test_中文测试用例():
"""测试中文显示"""
assert True
@pytest.mark.parametrize("商品名称", ["苹果", "香蕉", "橙子"])
def test_参数化中文测试(商品名称):
"""参数化测试包含中文参数"""
assert 商品名称 in ["苹果", "香蕉", "橙子"]
@pytest.mark.parametrize("用户名,密码", [
("张三", "123456"),
("李四", "password"),
])
def test_登录测试(用户名, 密码):
"""多参数中文测试"""
assert len(用户名) > 0
运行测试:
bash
# 生成 HTML 报告
pytest test_chinese.py --html=report.html --self-contained-html
# 或在脚本中运行
python -m pytest test_chinese.py --html=report.html --self-contained-html
打开生成的 report.html,检查中文是否正常显示。
常见问题
Q1:修改后报告仍然显示乱码怎么办?
A1:请确认以下几点:
-
修改的文件是否正确(路径和代码行)
-
修改后是否保存文件
-
是否重新运行了测试(旧报告需要重新生成)
-
浏览器编码是否设置为 UTF-8
Q2:修改后出现新的错误怎么办?
A2:可以恢复修改,使用备份文件还原:
bash
# 如果有备份文件
copy html_report.py.backup html_report.py
copy result.py.backup result.py
Q3:如何避免每次升级都重新修改?
A3:推荐以下方案之一:
-
使用虚拟环境,修改后不要轻易升级
-
创建修改记录文档,便于升级后重新修改
-
考虑使用 Allure 替代 pytest-html
Q4:在其他操作系统(Linux/macOS)上会这样吗?
A4:这个问题主要出现在 Windows 系统上。Linux 和 macOS 默认使用 UTF-8 编码,通常不会有此问题。
进阶方案:使用 Allure 报告
如果 pytest-html 的中文问题持续困扰你,强烈建议切换到 Allure 报告框架,它完美支持中文,功能更强大。
安装 Allure
bash
# 安装 allure-pytest 插件
pip install allure-pytest
# 安装 Allure 命令行工具
# Windows (使用 scoop)
scoop install allure
# macOS
brew install allure
# Linux (Ubuntu/Debian)
sudo apt-add-repository ppa:qameta/allure
sudo apt update
sudo apt install allure
生成报告
bash
# 运行测试并生成 Allure 数据
pytest tests/ --alluredir=allure-results
# 生成 HTML 报告
allure generate allure-results -o allure-report --clean
# 打开报告
allure open allure-report
Allure 的优势
-
✅ 完美支持中文,无需任何修改
-
✅ 报告界面美观,交互性强
-
✅ 支持测试步骤、截图、附件
-
✅ 支持历史趋势分析
-
✅ 支持测试分类和过滤
总结
通过修改 pytest-html 插件中的两个文件(html_report.py 和 result.py)的关键代码,可以彻底解决 Windows 环境下的中文乱码问题。虽然这个方案需要修改第三方库的源码,但它简单有效,且不影响插件的其他功能。
如果未来有更稳定的需求,建议考虑使用 Allure 作为测试报告方案,它不仅能完美解决中文问题,还能提供更专业的报告功能。
参考资料
适用版本 :pytest-html 3.2.0
测试环境:Windows 10/11, Python 3.13