默认的报错信息重写pytest断言报错信息重写常见的断言报错信息 正文 默认的报错信息
比如编写如下测试用例
def test_01(): assert 1==1def test_02(): assert 1==2def test_03(): assert "1"==1
执行结果如下:
$ pytest============================== test session starts ===============================platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0rootdir: D:summer_osppsummer_ospp_autotestfunction_tests, configfile: pytest.ini, testpaths: testsplugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0collected 3 items tests/test_demo.py::test_01 PASSED [ 33%]tests/test_demo.py::test_02 FAILED [ 66%]tests/test_demo.py::test_03 FAILED [100%]==================================== FAILURES ====================================____________________________________ test_02 _____________________________________ def test_02():> assert 1==2E assert 1 == 2E +1E -2teststest_demo.py:7: AssertionError____________________________________ test_03 _____________________________________ def test_03():> assert "1"==1E AssertionError: assert '1' == 1E +'1'E -1teststest_demo.py:10: AssertionError============================ short test summary info =============================FAILED tests/test_demo.py::test_02 - assert 1 == 2FAILED tests/test_demo.py::test_03 - AssertionError: assert '1' == 1========================== 2 failed, 1 passed in 0.18s ===========================
对于许多测试人员,可能习惯于看中文描述或者更加准确的中文描述,而当看到上述报错时,虽说从报错描述来说已经很清晰了,但是从多年的自动化测试经历中发现,其实很多测试人员或者编写自动化测试脚本的测试人员,调试或者执行自动化用例的时候看到上述报错的时候仍然是一脸茫然,他们更加的希望看到中文描述,甚至是更加人性化的中文描述,当然pytest的断言也提供了在脚本中自定义报错信息的方式,比如如下的方式,但是在实际测试开发中发现,虽然这种方式给自动化脚本开发人员自己定义的权利,但是在进行脚本开发的过程中如果每个断言都按照如下的方式增加断言报错信息,又很占用时间,感觉不方便,甚至有很多断言报错信息其实都是类似的,比如判断两个变量是否相等,其实断言信息都是类似的,而在脚本中每次断言都加断言报错信息又会显得很冗余,因此,另外一种在conftest.py中重写断言报错信息的处理方式就显得非常好用了
def test_03(): assert "1"==1,f"期望 ’1‘与1 相等,实际不相等"
重写pytest断言报错信息在测试用例的根目录中的conftest.py中编写如下代码:即这里对==运算符的报错信息进行了重写,比如如下首先判断是否是一个类型,如果不是一个类型,则直接提示两个数据不是一个类型,如果是一个类型的,在进行数值的比较,并且报错信息都是中文描述
def pytest_assertrepr_compare(op, left, right): if op == "==": if not isinstance(right,type(left)): return [ f"断言错误,期望值与实际值的数据类型不一致,期望值数据类型为:{type(right)}, 实际值为:{type(left)}", f"期望值为:{right}, 实际值为:{left}", ] else: return [ f"断言错误,期望值与实际值不一致,期望值为:{right}, 实际值为:{left}", ]
此时编写如下测试用例,如下,断言同样还是采用如下的简单的方式,即不去自己增加报错信息
def test_01(): assert 1==1def test_02(): assert 1==2def test_03(): assert "1"==1
执行结果如下:可以看出,虽然在用例中没有自定义报错信息,而在执行结果中仍然打印出了中文描述的报错信息,对于这样中文报错信息,相信任何测试人员看到都能知道为啥报错了,也不会因为满屏的英文报错而头大了
$ pytest========================================================================= test session starts ==========================================================================platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0rootdir: D:summer_osppsummer_ospp_autotestfunction_tests, configfile: pytest.ini, testpaths: testsplugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0collected 3 items tests/test_demo.py::test_01 PASSED [ 33%]tests/test_demo.py::test_02 FAILED [ 66%]tests/test_demo.py::test_03 FAILED [100%]=============================================================================== FAILURES ===============================================================================_______________________________________________________________________________ test_02 ________________________________________________________________________________ def test_02():> assert 1==2E assert 断言错误,期望值与实际值不一致,期望值为:2, 实际值为:1teststest_demo.py:7: AssertionError_______________________________________________________________________________ test_03 ________________________________________________________________________________ def test_03():> assert "1"==1E AssertionError: assert 断言错误,期望值与实际值的数据类型不一致,期望值数据类型为:
如下,重写了 ==,in,not in 的断言报错信息,其他的比如 >, <,>=,<=,!=等运算符重写方法类似,这里不在一一列举,conftest.py中编写如下代码:
def pytest_assertrepr_compare(op, left, right): if op == "==": if not isinstance(right,type(left)): return [ f"断言错误,期望值与实际值的数据类型不一致,期望值数据类型为:{type(right)}, 实际值为:{type(left)}", f"期望值为:{right}, 实际值为:{left}", ] else: return [ f"断言错误,期望值与实际值不一致,期望值为:{right}, 实际值为:{left}", ] if op == "in": if isinstance(left,str) and isinstance(right,str): return [ f"期望 {left} 是 {right} 的子串,实际 {left} 不是 {right} 的子串," ] elif isinstance(right,list) or isinstance(right,set) or isinstance(right,tuple): return [ f"期望 {left} 是集合 {right} 中的一个元素,实际集合 {right} 中没有 {left} 元素" ] elif isinstance(right,dict): return [ f"期望 {left} 是字典 {right} 中的一个key,实际字典 {right} 中没有值为 {left} 的key" ] else: return [ f"期望 {left} 是 {right} 中的一部分,实际上 {left} 并不是 {right} 的一部分" ] if op == "not in": if isinstance(left, str) and isinstance(right, str): return [ f"期望 {left} 不是 {right} 的子串,实际 {left} 是 {right} 的子串," ] elif isinstance(right, list) or isinstance(right, set) or isinstance(right, tuple): return [ f"期望 {left} 不是集合 {right} 中的一个元素,实际集合 {right} 中有 {left} 元素" ] elif isinstance(right, dict): return [ f"期望 {left} 不是字典 {right} 中的一个key,实际字典{right}中有值为 {left} 的key" ] else: return [ f"期望 {left} 不是 {right} 中的一部分,实际上 {left} 是 {right} 的一部分" ]
如下为实例脚本
def test_01(): assert 1==1def test_02(): assert 1==2def test_03(): assert "1"==1def test_04(): assert "aa" in "bbaa"def test_05(): assert "aa" in "bba"def test_06(): assert "aa" in ["aa","bb"]def test_07(): assert "aa" in ("aa","bb")def test_08(): assert "aa" in {"aa","bb"}def test_09(): assert "ab" in ["aa", "bb"]def test_10(): assert "ab" in ("aa", "bb")def test_11(): assert "ab" in {"aa", "bb"}def test_12(): assert "name" in {"name":"张三丰","age":100}def test_13(): assert "gender" in {"name":"张三丰","age":100}def test_14(): assert "aa" not in "bbaa"def test_15(): assert "aa" not in "bba"def test_16(): assert "aa" not in ["aa","bb"]def test_17(): assert "aa" not in ("aa","bb")def test_18(): assert "aa" not in {"aa","bb"}def test_19(): assert "ab" not in ["aa", "bb"]def test_20(): assert "ab" not in ("aa", "bb")def test_21(): assert "ab" not in {"aa", "bb"}def test_22(): assert "name" not in {"name":"张三丰","age":100}def test_23(): assert "gender" not in {"name":"张三丰","age":100}
执行结果如下:
$ pytest========================================================================= test session starts ==========================================================================platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0rootdir: D:summer_osppsummer_ospp_autotestfunction_tests, configfile: pytest.ini, testpaths: testsplugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0collected 23 items tests/test_demo.py::test_01 PASSED [ 4%]tests/test_demo.py::test_02 FAILED [ 8%]tests/test_demo.py::test_03 FAILED [ 13%]tests/test_demo.py::test_04 PASSED [ 17%]tests/test_demo.py::test_05 FAILED [ 21%]tests/test_demo.py::test_06 PASSED [ 26%]tests/test_demo.py::test_07 PASSED [ 30%]tests/test_demo.py::test_08 PASSED [ 34%]tests/test_demo.py::test_09 FAILED [ 39%]tests/test_demo.py::test_10 FAILED [ 43%]tests/test_demo.py::test_11 FAILED [ 47%]tests/test_demo.py::test_12 PASSED [ 52%]tests/test_demo.py::test_13 FAILED [ 56%]tests/test_demo.py::test_14 FAILED [ 60%]tests/test_demo.py::test_15 PASSED [ 65%]tests/test_demo.py::test_16 FAILED [ 69%]tests/test_demo.py::test_17 FAILED [ 73%]tests/test_demo.py::test_18 FAILED [ 78%]tests/test_demo.py::test_19 PASSED [ 82%]tests/test_demo.py::test_20 PASSED [ 86%]tests/test_demo.py::test_21 PASSED [ 91%]tests/test_demo.py::test_22 FAILED [ 95%]tests/test_demo.py::test_23 PASSED [100%]=============================================================================== FAILURES ===============================================================================_______________________________________________________________________________ test_02 ________________________________________________________________________________ def test_02():> assert 1==2E assert 断言错误,期望值与实际值不一致,期望值为:2, 实际值为:1teststest_demo.py:7: AssertionError_______________________________________________________________________________ test_03 ________________________________________________________________________________ def test_03():> assert "1"==1E AssertionError: assert 断言错误,期望值与实际值的数据类型不一致,期望值数据类型为: