pytest学习文档6--fixture之yield,addfinalizer实现teardown
上一篇讲到fixture通过scope参数控制setup级别,既然有setup作为用例之前的操作,用例执行完成后那肯定也有teardown的操作
这里用到fixture的teardown操作病不是独立的函数,用yield关键字呼唤teardown操作。
scope = 'module'
1、fixture 参数 scope = ‘module’,module作用是整个.py文件都会生效,用例调用时,参数写上函数名称就行
import pytest # scope为module 代表 对整个.py文件生效,当.py模块执行前 执行一次 @pytest.fixture(scope='module', autouse=True) def open_browser(): print("\n 打开浏览器,并打开必应搜索解密那") pass def test_s1(): print("用例1,搜索Python-1") def test_s2(): print("用例2,搜索 python-2") def test_s3(): print("用例3,搜索 python-3") if __name__ == '__main__': pytest.main(['-s', '-v'])
运行结果:
从结果可以看出,fixture函数只在test-s1之前执行了一次
2、yield执行teardown
前面讲的是在用例前加前置条件,相当于setup,既然有setup,那就有teardown,fixture里的teardown用yield关键字来唤醒 teardown的执行
import pytest # scope 为module 代表作用整个.py文件生效,模块执行前执行一次 @pytest.fixture(scope='module', autouse=True) def open_browser(): print("\n 打开浏览器,并打开必应搜索解密那") yield print("module执行结束,最后关闭浏览器") pass def test_s1(): print("用例1,搜索Python-1") def test_s2(): print("用例2,搜索 python-2") def test_s3(): print("用例3,搜索 python-3") if __name__ == '__main__': pytest.main(['-s', '-v'])
执行结果如下:
3、yield遇到异常
1、如果测试用例有一例遇到异常,不影响yield后面的teardown的执行,运行结果互不影响,并且在用例全部执行完成后,会呼唤teardown的内容
import pytest # scope 为module 代表作用整个.py文件生效,模块执行前执行一次 @pytest.fixture(scope='module', autouse=True) def open_browser(): print("\n 打开浏览器,并打开必应搜索解密那") yield print("module执行结束,最后关闭浏览器") pass def test_s1(): print("用例1,搜索Python-1") def test_s2(): print("用例2,搜索 python-2") raise NameError # 模拟异常 def test_s3(): print("用例3,搜索 python-3") if __name__ == '__main__': pytest.main(['-s', '-v'])
执行结果如下:
teardown可以正常执行。
2、如果setup异常了,那么是不会去执行yield后面的teardown内容的
3、yield也可以配合with语句使用,以下是官方文档给的案例------这个看不懂 忽略吧
-----addfinalizer终结函数
1、除了yield可以实现teardown,在request-context对象中注册addfinalizer方法也可以实现终结函数
yield 和addfinalizer方法都是在测试完成后呼叫相应的代码,但是addfinalizer 不同的是:
--它可以注册多个 终结函数
--这些终结函数总是会被执行, 无论前面的setup code 有没有抛出异常,这个方法对于正确关闭所有的fixture创建的资源非常便利,即使其一在创建或获取时失败。
import pytest # scope 为module 代表作用整个.py文件生效,模块执行前执行一次 @pytest.fixture(scope='module', autouse=True) def open_browser(request): print("\n 打开浏览器,并打开必应搜索解密那") def fin(): print("-------------module执行结束,最后关闭浏览器---------") request.addfinalizer(fin) pass def test_s1(): print("用例1,搜索Python-1") def test_s2(): print("用例2,搜索 python-2") raise NameError # 模拟异常 def test_s3(): print("用例3,搜索 python-3") if __name__ == '__main__': pytest.main(['-s', '-v'])
运行结果:
当时当我这是setup 异常时 addfinalizer 并没有执行,和yield效果是一样的,不知道有没有大拿知道原因????