pytest框架进阶自学系列 | fixture应用在配置销毁

书籍来源:房荔枝 梁丽丽《pytest框架与自动化测试应用》

一边学习一边整理老师的课程内容及实验笔记,并与大家分享,侵权即删,谢谢支持!

附上汇总贴:pytest框架进阶自学系列 | 汇总_热爱编程的通信人的博客-CSDN博客


使用yield代替return

已经可以将测试方法前要执行的或依赖的问题解决了,但测试方法后需要销毁并清除的数据该如何处理呢?范围是模块级别的,类似setupClass。解决方法是通过在同一模块中加入yield关键字,yield调用第一次返回结果,第二次执行它下面的语句并返回结果。

步骤如下:

(1)添加@pytest.fixture(scope=module)语句。

(2)在登录的方法中添加yield,之后添加销毁清除的步骤。

代码如下:

import pytest

@pytest.fixture(scope="module")
def open():
    print("打开浏览器,打开百度首页")
    
    yield
    
    print("执行teardown")
    print("最后关闭浏览器")
    
def test_s7():
    print("用例7,")
    
def test_s8():
    print("用例8,")
    
def test_s9(open):
    print("用例9,")
D:\SynologyDrive\CodeLearning\WIN\pytest-book\venv\Scripts\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2022.1.3\plugins\python-ce\helpers\pycharm\_jb_pytest_runner.py" --path D:/SynologyDrive/CodeLearning/WIN/pytest-book/src/chapter-3/test_fixture_module_yield.py
Testing started at 11:27 ...
Launching pytest with arguments D:/SynologyDrive/CodeLearning/WIN/pytest-book/src/chapter-3/test_fixture_module_yield.py in D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-3

============================= test session starts =============================
platform win32 -- Python 3.7.7, pytest-5.4.1, py-1.11.0, pluggy-0.13.1 -- D:\SynologyDrive\CodeLearning\WIN\pytest-book\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: D:\SynologyDrive\CodeLearning\WIN\pytest-book
collecting ... collected 3 items

test_fixture_module_yield.py::test_s7 PASSED                             [ 33%]用例7,

test_fixture_module_yield.py::test_s8 打开浏览器,打开百度首页
PASSED                             [ 66%]用例8,

test_fixture_module_yield.py::test_s9 PASSED                             [100%]用例9,
执行teardown
最后关闭浏览器


============================== 3 passed in 0.02s ==============================

Process finished with exit code 0

使用with写法

对于支持with写法的对象,程序也可以隐式地执行它的清理销毁操作。当使用with出现问题时,由Python进行处理以便销毁。

代码如下:

import smtplib
import pytest

@pytest.fixture()
def smtp_connection_yield():
    with smtplib.SMTP("smtp.163.com", 25, timeout=5) as smtp_connection:
        print("---start connection")
        yield smtp_connection
        print("---end connection")
        
def test_send_mail(smtp_connection_yield):
    print("发邮件")
D:\SynologyDrive\CodeLearning\WIN\pytest-book\venv\Scripts\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2022.1.3\plugins\python-ce\helpers\pycharm\_jb_pytest_runner.py" --path D:/SynologyDrive/CodeLearning/WIN/pytest-book/src/chapter-3/test_fixture_with.py
Testing started at 11:43 ...
Launching pytest with arguments D:/SynologyDrive/CodeLearning/WIN/pytest-book/src/chapter-3/test_fixture_with.py in D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-3

============================= test session starts =============================
platform win32 -- Python 3.7.7, pytest-5.4.1, py-1.11.0, pluggy-0.13.1 -- D:\SynologyDrive\CodeLearning\WIN\pytest-book\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: D:\SynologyDrive\CodeLearning\WIN\pytest-book
collecting ... collected 1 item

test_fixture_with.py::test_send_mail 

============================== 1 passed in 0.17s ==============================

Process finished with exit code 0
---start connection
PASSED                              [100%]发邮件
---end connection

使用addfinalizer方法

fixture函数能够接收一个request参数,表示测试请求的上下文。本书使用request.addfinalizer方法为fixture添加清理销毁函数。

代码如下:

import pytest

@pytest.fixture()
def demo_fixture(request):
    print("\n这个fixture在每个用例前执行一次")

    def demo_finalizer():
        print("\n在每个用例完成后执行的teardown")

    request.addfinalizer(demo_finalizer)

def test_01(demo_fixture):
    print("\n===执行了用例:test_01===")

def test_02(demo_fixture):
    print("\n===执行了用例:test_02===")

def test_03(demo_fixture):
    print("\n===执行了用例:test_03===")
D:\SynologyDrive\CodeLearning\WIN\pytest-book\venv\Scripts\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2022.1.3\plugins\python-ce\helpers\pycharm\_jb_pytest_runner.py" --path D:/SynologyDrive/CodeLearning/WIN/pytest-book/src/chapter-3/test_addfinalizer.py
Testing started at 11:50 ...
Launching pytest with arguments D:/SynologyDrive/CodeLearning/WIN/pytest-book/src/chapter-3/test_addfinalizer.py in D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-3

============================= test session starts =============================
platform win32 -- Python 3.7.7, pytest-5.4.1, py-1.11.0, pluggy-0.13.1 -- D:\SynologyDrive\CodeLearning\WIN\pytest-book\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: D:\SynologyDrive\CodeLearning\WIN\pytest-book
collecting ... collected 3 items

test_addfinalizer.py::test_01 
这个fixture在每个用例前执行一次
PASSED                                     [ 33%]
===执行了用例:test_01===

在每个用例完成后执行的teardown

test_addfinalizer.py::test_02 
这个fixture在每个用例前执行一次
PASSED                                     [ 66%]
===执行了用例:test_02===

在每个用例完成后执行的teardown

test_addfinalizer.py::test_03 
这个fixture在每个用例前执行一次
PASSED                                     [100%]
===执行了用例:test_03===

在每个用例完成后执行的teardown


============================== 3 passed in 0.03s ==============================

Process finished with exit code 0

注意:如果在yield之前或者addfinalizer注册之前代码发生错误并退出,则不会再执行后续的清理操作。

yield与addfinalizer的区别

那么,除了在使用上的区别之外,yield与addfinalizer还有什么不同呢?

addfinalizer可以注册多个终结销毁函数,而yield无法实现多个。在执行yield的过程中出现错误无法再执行yield后面的函数,而addfinalizer函数在执行的过程中即使出错也会执行后面的函数。

代码如下:

import pytest

@pytest.fixture()
def demo_fixture(request):
    print("\n这个fixture在每个用例前执行一次")

    def demo_finalizer():
        print("\n在每个用例完成后执行的teardown")

    def demo_finalizer2():
        print("\n在每个用例完成后执行的teardown2")

    def demo_finalizer3():
        print("\n在每个用例完成后执行的teardown3")

    request.addfinalizer(demo_finalizer)
    request.addfinalizer(demo_finalizer2)
    request.addfinalizer(demo_finalizer3)

def test_01(demo_fixture):
    print("\n===执行了用例:test_01===")

def test_02(demo_fixture):
    print("\n===执行了用例:test_02===")

def test_03(demo_fixture):
    print("\n===执行了用例:test_03===")

运行结果如图所示,可以看到,注册的3个函数都被执行了,但是要注意执行顺序,可以看出与注册的顺序恰好相反。

D:\SynologyDrive\CodeLearning\WIN\pytest-book\venv\Scripts\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2022.1.3\plugins\python-ce\helpers\pycharm\_jb_pytest_runner.py" --path D:/SynologyDrive/CodeLearning/WIN/pytest-book/src/chapter-3/test_addfinalizer02.py
Testing started at 10:47 ...
Launching pytest with arguments D:/SynologyDrive/CodeLearning/WIN/pytest-book/src/chapter-3/test_addfinalizer02.py in D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-3

============================= test session starts =============================
platform win32 -- Python 3.7.7, pytest-5.4.1, py-1.11.0, pluggy-0.13.1 -- D:\SynologyDrive\CodeLearning\WIN\pytest-book\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: D:\SynologyDrive\CodeLearning\WIN\pytest-book
collecting ... collected 3 items

test_addfinalizer02.py::test_01 
这个fixture在每个用例前执行一次
PASSED                                   [ 33%]
===执行了用例:test_01===

在每个用例完成后执行的teardown3

在每个用例完成后执行的teardown2

在每个用例完成后执行的teardown

test_addfinalizer02.py::test_02 
这个fixture在每个用例前执行一次
PASSED                                   [ 66%]
===执行了用例:test_02===

在每个用例完成后执行的teardown3

在每个用例完成后执行的teardown2

在每个用例完成后执行的teardown

test_addfinalizer02.py::test_03 
这个fixture在每个用例前执行一次
PASSED                                   [100%]
===执行了用例:test_03===

在每个用例完成后执行的teardown3

在每个用例完成后执行的teardown2

在每个用例完成后执行的teardown


============================== 3 passed in 0.02s ==============================

Process finished with exit code 0

当setUp的代码执行出错时,addfinalizer依旧会被执行。

猜你喜欢

转载自blog.csdn.net/guolianggsta/article/details/131609527
今日推荐