根本原因是终端、Python运行环境与文件编码三者解码规则不一致;Windows下cmd默认用GBK解码,而Python源码和字符串为UTF-8,导致中文被转义为u5355u4e2a等Unicode形式,需统一各环节为UTF-8编码。

pytest 命令行输出中文乱码,根本原因不是 pytest 本身有问题,而是终端、Python 运行环境、文件编码三者之间解码规则不一致。Windows 下尤其高发,因为 cmd 默认用 GBK 解码,而 Python 源码和字符串是 UTF-8。
为什么终端显示 u5355u4e2au5546u54c1 而不是“单个商品”?
这是 Unicode 转义形式,说明 pytest 把中文字符串当作了普通 ASCII 字符串处理,没走 UTF-8 解码路径。常见触发场景:
- 测试用例名或
ids参数含中文,但 pytest 没正确识别其编码来源 - Windows cmd 用
chcp 936(即 GBK)运行,而 Python 输出的是 UTF-8 字节流 -
pytest-html插件写 HTML 文件时没指定encoding='utf-8',导致浏览器按 GBK 解析
pytest.ini 中 disable_test_id_escaping_and_forfeit_all_rights_to_community_support=True 真的有用吗?
有用,但只解决一部分问题——它禁用 pytest 对测试 ID 的自动转义(比如把中文转成 uXXXX),让原始字符串透传到终端或报告中。但它不解决底层编码输出问题。
必须配合其他措施才有效:
立即学习“Python免费学习笔记(深入)”;
- 确保终端已切换为 UTF-8:
chcp 65001(cmd)或[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()(PowerShell) -
pytest.ini中加addopts = --tb=short避免 traceback 混入 GBK 字节干扰 - 不要同时启用
--tb=long和中文 ID,长 traceback 容易触发隐式 encode/decode 错误
修改 pytest-html 源码时,哪些 write_text() 必须加 encoding='utf-8'?
不是所有 write_text() 都要改,关键是**所有直接写 HTML 内容的地方**,尤其是:
-
html_report.py中的_save_report()方法里对self.logfile.write_text(report_content)的调用 - 同文件中对
style_path.write_text(self.style_css)的调用 -
result.py中若存在json.dumps(...).encode().decode()类操作,需删掉中间 encode/decode,直接用json.dumps(..., ensure_ascii=False)
注意:write_text() 在 Python 3.7+ 默认用系统 locale 编码(Windows 是 GBK),不显式指定 encoding 就必然出错。
conftest.py 里用 item.name.encode('utf-8').decode('unicode_escape') 是什么原理?
这是在“强行纠错”:假设 pytest 已把中文错误转成了 Unicode 转义字符串(如 '\u5355\u4e2a'),再用 unicode_escape 解码还原。但它依赖字符串已被双反斜杠转义过,属于补救手段,不是源头治理。
更稳妥的做法是避免让它被转义:
- 在
@pytest.mark.parametrize中,ids参数直接传 str,别传 bytes 或已 encode 的值 - 确保测试文件本身存为 UTF-8 且开头有
# -*- coding: utf-8 -*- - 不用
sys.setdefaultencoding('utf-8')—— Python 3 不允许改默认编码,该调用会静默失败
真正稳定的解法,是让每个环节都明确使用 UTF-8:源文件编码、终端编码、文件 I/O 编码、JSON 序列化选项、插件写入参数。少一个环节,就可能在某个路径上“鸡同鸭讲”。


















