【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相似)
  • 可以声明多个终结函数并调用

 

posted @ 2020-12-01 10:50  做一只热爱生活的小透明  阅读(125)  评论(0)    收藏  举报