Pytest自动化测试框架-权威教程04-断言的编写和报告

断言的编写和报告

使用assert语句进行断言

pytest允许你使用标准的Pythonassert断言语句来验证测试中的期望结果和实际结果。 例如,你可以编写以下内容:

Copy# test_assert1.py文件内容deff():
    return3deftest_function():
    assert f() == 4

来断言你的函数返回一个特定的值。 如果此断言失败,你将看到函数调用的返回值:

Copy$ pytest test_assert1.py
=========================== test session starts ============================
platform linux -- Python 3.x.y,pytest-3.x.y,py-1.x.y,pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR,inifile:
collected 1 item

test_assert1.py F                                                    [100%]

================================= FAILURES =================================
______________________________ test_function _______________________________

    deftest_function():
>       assert f() == 4
E       assert3 == 4
E        +  where 3 = f()

test_assert1.py:5: AssertionError
========================= 1 failed in0.12 seconds =========================

Pytest支持显示常见的包括调用,属性,比较以及二元和一元运算符子表达式的值 (参考: pytest执行Python测试失败报告示例)。 你可以在不使用繁琐的Python惯用构造样板代码的同时,不丢失断言失败的对比信息(内省信息)。

当然,你也可以像下面所示,指定断言失败的返回消息:

Copyassert a % 2 == 0,"值为奇数,应为偶数"

这样将不会断言失败对比信息(内省信息),而只简单地在追溯信息中显示你指定的失败返回信息。

有关断言内省的更多信息,请参阅高级断言内省

异常断言

你可以像如下所示,使用pytest.raises作为上下文管理器来进行异常断言:

Copyimport pytest

deftest_zero_division():
    with pytest.raises(ZeroDivisionError):
        1 / 0

如果需要访问实际的异常信息,你可以使用:

Copydeftest_recursion_depth():
    with pytest.raises(RuntimeError) as excinfo:
        deff():
            f()
        f()
    assert'maximum recursion'instr(excinfo.value)

excinfo是一个ExceptionInfo实例,它是实际异常的装饰器。 其主要属性有.type,.value及.traceback三种

版本3.0已修改

在上下文管理器中,你可以使用参数message来指定自定义失败信息:

Copy>>> with raises(ZeroDivisionError,message="Expecting ZeroDivisionError"):
...    pass
... Failed: Expecting ZeroDivisionError

如果你想编写适用于Python 2.4的测试代码,你还可以使用其他两种方法来测试预期的异常:

Copypytest.raises(ExpectedException,func,*args,**kwargs)
pytest.raises(ExpectedException,"func(*args,**kwargs)")

两者都可以对带任意参数的函数,断言是否出现了期望的异常:ExpectedException。 即使没有异常或出现了不同的异常,报告生成器也能输出一些有用的断言信息。

注意,也可以为pytest.mark.xfail指定一个“raises”参数,当引发异常时标记用例失败:

Copy@pytest.mark.xfail(raises=IndexError)deftest_f():
    f()

对于你在代码中故意设置的异常,使用pytest.raises断言更加好用,而将@ pytest.mark.xfail与check函数一起使用对于已知未修复或依赖中的bug会更好。

此外,上下文管理器表单接受match关键字参数来测试正则表达式匹配中的异常(如unittest中的TestCase.assertRaisesRegexp方法):

Copyimport pytest

defmyfunc():
    raise ValueError("Exception 123 raised")

deftest_match():
    with pytest.raises(ValueError,match=r'.* 123 .*'):
        myfunc()

match变量后的正则表达式与使用re.search函数来进行匹配一致。 因此在上面的例子中,match ='123'不会引发异常。

警示断言

2.8版本新增

你可以使用pytest.warns检查代码是否引发了特定警告。

使用上下文对比

2.0版本新增

Pytest可以在断言的比较中提供丰富的上下文信息。 例如:

Copy# test_assert2.py文件内容deftest_set_comparison():
    set1 = set("1308")
    set2 = set("8035")
    assert set1 == set2

当你运行这个模块后

Copy$ pytest test_assert2.py
=========================== test session starts ============================
platform linux -- Python 3.x.y,pytest-3.x.y,py-1.x.y,pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR,inifile:
collected 1 item

test_assert2.py F                                                    [100%]

================================= FAILURES =================================
___________________________ test_set_comparison ____________________________

    def test_set_comparison():
        set1 = set("1308")
        set2 = set("8035")
>       assert set1 == set2
E       AssertionError: assert {'0','1','3','8'} == {'0','3','5','8'}
E         Extra items in the left set:
E         '1'
E         Extra items in the right set:
E         '5'
E         Use -v to get the full diff

test_assert2.py:5: AssertionError
========================= 1 failed in 0.12 seconds =========================

对大量用例进行了特定对比:

  • 长字符串断言:显示上下文差异

  • 长序列断言:显示第一个失败的索引

  • 字典断言:显示不同的key-value对

有关更多示例,请参阅 报告样例。

自定义断言对比信息

可以通过实现hook方法pytest_assertrepr_compare来在断言结果中添加你自己的详细说明信息。

**pytest_assertrepr_compare(config,op,left,right)*- [源码]

返回失败断言表达式中的对比信息。

如果没有自定义对比信息,则返回None,否则返回一列字符串。 字符串将由换行符连接,但字符串中的任何换行符都将被转义。 请注意,除第一行外的所有行都将略微缩进,目的是将第一行作为摘要。

参数: config(pytest.config.Config* - pytest config 对象

例如,在conftest.py文件中添加以下钩子(Hook)方法,可以为Foo对象提供了附加对比信息:

Copy# conftest.py内容from test_foocompare import Foo
defpytest_assertrepr_compare(op,left,right):
    ifisinstance(left,Foo) andisinstance(right,Foo) and op == "==":
        return ['Foo实例对比:',
                '   值: %s != %s' % (left.val,right.val)]

现在,在测试模块使用

Copy# test_foocompare.py内容classFoo(object):
    def__init__(self,val):
        self.val = val

    def__eq__(self,other):
        return self.val == other.val

deftest_compare():
    f1 = Foo(1)
    f2 = Foo(2)
    assert f1 == f2

运行这个测试模块你可以看到conftest.py文件中定义的自定义输出:

Copy$ pytest -q test_foocompare.py
F                                                                    [100%]
================================= FAILURES =================================
_______________________________ test_compare _______________________________

    def test_compare():
        f1 = Foo(1)
        f2 = Foo(2)
>       assert f1 == f2
E       assert Foo实例对比:
E            值: 1 != 2

test_foocompare.py:11: AssertionError
1 failed in 0.12 seconds

高级断言内省

2.1版本新函数

报告有关失败断言的详细信息是通过在运行之前重写assert语句来实现的。 重写的断言语句将内省信息放入断言失败消息中。 Pytest只重写测试收集过程直接发现的测试模块中的assert断言,因此在支持模块(非测试模块)中的断言,不会被重写

你可以在导入模块前通过调用register_assert_rewrite手动启用断言重写(比如可以在conftest.py这样使用)。

注意
Pytest通过使用导入hook方法写入新的pyc文件来重写测试模块。 通常这种结构比较清晰。 但是,如果你混乱导入,导入的hook方法可能会受到干扰。
如果是这种情况,你有两种选择:
通过将字符串PYTEST_DONT_REWRITE添加到其docstring来禁用特定模块的重写。
使用--assert = plain禁用所有模块的重写。
此外,如果无法写入新的.pyc文件(如在只读文件系统或zip文件中),重写将无提示失败。
有关进一步的信息,课参阅:本杰明彼得森写的[pytest的新断言改写的幕后故事。

版本2.1新函数:添加断言重写作为备用内省技术。

版本2.1更改:引入--assert选项。 弃用--no-assert和--nomagic。

版本3.0版更改:删除--no-assert和--nomagic选项。 删除--assert = reinterp`选项。

实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

电商项目实战

web测试项目

web+App+h5+小程序 测试项目

接口自动化测试实战项目

Linux实战项目

面试资料

我们进阶学习自动化测试必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

以上资料,对于想要测试进阶的朋友们来说应该会很有帮助,需要的小伙伴可以后台私信找我免费领取

总结

我见过很多leader在面试的时候,遇到处于迷茫期的大龄程序员,比面试官年龄都大。这些人有一些共同特征:可能工作了好几年,更夸张的是7、8年工作内容的重复性比较高,没有什么技术含量的工作。

凡事要趁早,特别是技术行业,一定要提升技术功底,丰富自动化项目实战经验,这对于你未来几年职业规划,以及测试技术掌握的深度非常有帮助。

如有不懂还要咨询下方小卡片,博主也希望和志同道合的测试人员一起学习进步

在适当的年龄,选择适当的岗位,尽量去发挥好自己的优势。

我的自动化测试开发之路,一路走来都离不每个阶段的计划,因为自己喜欢规划和总结,

测试开发视频教程、学习笔记领取传送门!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值