【pytest-7】-fixture之yield实现teardown
前言
前面讲的,其实都是setup的操作,那么现在就来讲下teardown是怎么实现的
用fixture实现teardown并不是一个独立的函数,而是用 yield 关键字来开启teardown操作
scope="module"
#encoding:utf-8 #@Time:2020/11/30 17:21 #@Author:sunny import pytest @pytest.fixture(scope="module") def open(): print("我是打开浏览器")def test_s1(open): print("我是用例1,搜索python1") def test_s2(open): print("我是用例2,搜索python2") if __name__ == '__main__': pytest.main(['-s','test_fix_a.py'])
运行结果:
Testing started at 17:57 ...
============================= test session starts =============================0collected 2 items test_fix_a.py 我是打开浏览器 .我是用例1,搜索python1 .我是用例2,搜索python2 [100%] ========================== 2 passed in 0.02 seconds ===========================
从结果看出,虽然test_s1,test_s2两个地方都调用了open函数,但是它只会在第一个用例前执行一次
如果我只想在test_s1不调用,test_s2调用呢,和前面一样,不调用open就不执行
#encoding:utf-8 #@Time:2020/11/30 17:21 #@Author:sunny import pytest @pytest.fixture(scope="module") def open(): print("我是打开浏览器")def test_s1(): print("我是用例1,搜索python1") def test_s2(open): print("我是用例2,搜索python2") if __name__ == '__main__': pytest.main(['-s','test_fix_a.py'])
运行结果:
Testing started at 9:33 ... ============================= test session starts =============================collected 2 items test_fix_a.py .我是用例1,搜索python1 我是打开浏览器 .我是用例2,搜索python2 [100%] ========================== 2 passed in 0.02 seconds =========================== Process finished with exit code 0
从结果看出,module级别的fixture在当前.py模块里,只会在用例(test_s2)第一次调用前执行一次
yield执行teardown
前面说的是在用例前加前置条件,相当于setup,当然teardown也有,对应fixture里面的yeild
示例:
#encoding:utf-8 #@Time:2020/11/30 17:21 #@Author:sunny import pytest @pytest.fixture(scope="module") def open(): print("我是打开浏览器") yield print("我是关闭浏览器") def test_s1(open): print("我是用例1,搜索python1") def test_s2(open): print("我是用例2,搜索python2") if __name__ == '__main__': pytest.main(['-s','test_fix_a.py'])
运行结果:
Testing started at 9:45 ... ============================= test session starts =============================collected 2 items test_fix_a.py 我是打开浏览器 .我是用例1,搜索python1 .我是用例2,搜索python2 我是关闭浏览器 [100%] ========================== 2 passed in 0.02 seconds =========================== Process finished with exit code 0
yeild遇到的异常
如果其中一个用例出现异常,不影响yeild后面的teardown执行,运行结果互不影响,并且全部用例执行完之后,yeild唤醒teardown
示例:
#encoding:utf-8 #@Time:2020/11/30 17:21 #@Author:sunny import pytest @pytest.fixture(scope="module") def open(): print("我是打开浏览器") yield print("我是关闭浏览器") def test_s1(open): print("我是用例1,搜索python1") raise NameError #模拟异常 def test_s2(open): print("我是用例2,搜索python2") if __name__ == '__main__': pytest.main(['-s','test_fix_a.py'])
运行结果:
Testing started at 10:02 ... ============================= test session starts =============================collected 2 items test_fix_a.py 我是打开浏览器 F我是用例1,搜索python1 test_fix_a.py:12 (test_s1) open = None def test_s1(open): print("我是用例1,搜索python1") > raise NameError #模拟异常 E NameError test_fix_a.py:15: NameError .我是用例2,搜索python2 我是关闭浏览器 [100%] ================================== FAILURES =================================== ___________________________________ test_s1 ___________________________________ open = None def test_s1(open): print("我是用例1,搜索python1") > raise NameError #模拟异常 E NameError test_fix_a.py:15: NameError ---------------------------- Captured stdout setup ---------------------------- 我是打开浏览器 ---------------------------- Captured stdout call ----------------------------- 我是用例1,搜索python1 ===================== 1 failed, 1 passed in 0.06 seconds ====================== Process finished with exit code 0
2.如果在setup就异常了,那么是不会去执行yield后面的teardown内容了
3.yeild可以配合with语句使用
# 官方例子 @pytest.fixture(scope="module") def smtp_connection(): with smtplib.SMTP("smtp.gmail.com", 587, timeout=5) as smtp_connection: yield smtp_connection # provide the fixture value
该 smtp_connection 连接将测试完成执行后已经关闭,因为 smtp_connection 对象自动关闭时, with 语句结束。
addfinalizer终结函数
#encoding:utf-8 #@Time:2020/12/1 10:18 #@Author:sunny import pytest @pytest.fixture(scope="module") def test_addfinalizer(request): # 前置操作setup print("==再次打开浏览器==") test = "test_addfinalizer" def fin(): # 后置操作teardown print("==再次关闭浏览器==") request.addfinalizer(fin) # 返回前置操作的变量 return test def test_anthor(test_addfinalizer): print("==最新用例==", test_addfinalizer)
运行结果:
Testing started at 10:40 ...============================= test session starts =============================collected 1 item test_c.py ==再次打开浏览器== .==最新用例== test_addfinalizer ==再次关闭浏览器== [100%] ========================== 1 passed in 0.02 seconds =========================== Process finished with exit code 0
注意:
- 如果 request.addfinalizer() 前面的代码,即setup部分已经抛出异常了,则不会执行 request.addfinalizer() 的teardown内容(和yield相似)
- 可以声明多个终结函数并调用
善于跌倒仍喜爱奔跑~