zoukankan      html  css  js  c++  java
  • pytest文档6-fixture之yield实现teardown

    前言

    上一篇讲到fixture通过scope参数控制setup级别,既然有setup作为用例之前前的操作,用例执行完之后那肯定也有teardown操作。
    这里用到fixture的teardown操作并不是独立的函数,用yield关键字呼唤teardown操作

    scope="module"

    1.fixture参数scope="module",module作用是整个.py文件都会生效,用例调用时,参数写上函数名称就行

    # 新建一个文件test_f1.py
    # coding:utf-8
    import pytest
    '''
    ** 作者:上海-悠悠 QQ交流群:588402570**
    '''
    
    @pytest.fixture(scope="module")
    def open():
        print("打开浏览器,并且打开百度首页")
    
    def test_s1(open):
        print("用例1:搜索python-1")
    
    def test_s2(open):
        print("用例2:搜索python-2")
    
    def test_s3(open):
        print("用例3:搜索python-3")
    
    if __name__ == "__main__":
        pytest.main(["-s", "test_f1.py"])
    

    运行结果:

    ============================= test session starts =============================
    platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
    rootdir: D:\, inifile:
    collected 3 items
    
    ............YOYO	est_f1.py 打开浏览器,并且打开百度首页
    用例1:搜索python-1
    .用例2:搜索python-2
    .用例3:搜索python-3
    .
    
    ========================== 3 passed in 0.01 seconds ===========================
    

    从结果看出,虽然test_s1,test_s2,test_s3三个地方都调用了open函数,但是它只会在第一个用例前执行一次

    2.如果test_s1不调用,test_s2(调用open),test_s3不调用,运行顺序会是怎样的?

    # 新建一个文件test_f1.py
    # coding:utf-8
    import pytest
    '''
    ** 作者:上海-悠悠 QQ交流群:588402570**
    '''
    
    @pytest.fixture(scope="module")
    def open():
        print("打开浏览器,并且打开百度首页")
    
    def test_s1():
        print("用例1:搜索python-1")
    
    def test_s2(open): 
        print("用例2:搜索python-2")
    
    def test_s3():
        print("用例3:搜索python-3")
    
    if __name__ == "__main__":
        pytest.main(["-s", "test_f1.py"])
    

    运行结果:

    ============================= test session starts =============================
    platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
    rootdir: D:\, inifile:
    collected 3 items
    
    ............YOYO	est_f1.py 用例1:搜索python-1
    .打开浏览器,并且打开百度首页
    用例2:搜索python-2
    .用例3:搜索python-3
    .
    
    ========================== 3 passed in 0.01 seconds ===========================
    

    从结果看出,module级别的fixture在当前.py模块里,只会在用例(test_s2)第一次调用前执行一次

    yield执行teardown

    1.前面讲的是在用例前加前置条件,相当于setup,既然有setup那就有teardown,fixture里面的teardown用yield来唤醒teardown的执行

    # 新建一个文件test_f1.py
    # coding:utf-8
    import pytest
    '''
    ** 作者:上海-悠悠 QQ交流群:588402570**
    '''
    
    @pytest.fixture(scope="module")
    def open():
        print("打开浏览器,并且打开百度首页")
    
        yield
        print("执行teardown!")
        print("最后关闭浏览器")
    
    def test_s1(open):
        print("用例1:搜索python-1")
    
    def test_s2(open):
        print("用例2:搜索python-2")
    
    def test_s3(open):
        print("用例3:搜索python-3")
    
    if __name__ == "__main__":
        pytest.main(["-s", "test_f1.py"])
    

    运行结果:

    ============================= test session starts =============================
    platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
    rootdir: D:\, inifile:
    collected 3 items
    
    ............YOYO	est_f1.py 打开浏览器,并且打开百度首页
    用例1:搜索python-1
    .用例2:搜索python-2
    .用例3:搜索python-3
    .执行teardown!
    最后关闭浏览器
    
    
    ========================== 3 passed in 0.01 seconds ===========================
    

    yield遇到异常

    1.如果其中一个用例出现异常,不影响yield后面的teardown执行,运行结果互不影响,并且全部用例执行完之后,yield呼唤teardown操作

    # 新建一个文件test_f1.py
    # coding:utf-8
    import pytest
    '''
    ** 作者:上海-悠悠 QQ交流群:588402570**
    '''
    
    @pytest.fixture(scope="module")
    def open():
        print("打开浏览器,并且打开百度首页")
        yield
        print("执行teardown!")
        print("最后关闭浏览器")
    
    def test_s1(open):
        print("用例1:搜索python-1")
    
        # 如果第一个用例异常了,不影响其他的用例执行
        raise NameError  # 模拟异常
    
    def test_s2(open):
        print("用例2:搜索python-2")
    
    def test_s3(open):
        print("用例3:搜索python-3")
    
    if __name__ == "__main__":
        pytest.main(["-s", "test_f1.py"])
    

    运行结果:

    YOYO	est_f1.py 打开浏览器,并且打开百度首页
    用例1:搜索python-1
    F
    open = None
    
        def test_s1(open):
            print("用例1:搜索python-1")
        
            # 如果第一个用例异常了,不影响其他的用例执行
    >       raise NameError  # 模拟异常
    E       NameError
    
    D:YOYO	est_f1.py:16: NameError
    用例2:搜索python-2
    .用例3:搜索python-3
    .执行teardown!
    最后关闭浏览器
    

    2.如果在setup就异常了,那么是不会去执行yield后面的teardown内容了

    3.yield也可以配合with语句使用,以下是官方文档给的案例

    # 官方文档案例
    # content of test_yield2.py
    
    import smtplib
    import pytest
    '''
    ** 作者:上海-悠悠 QQ交流群:588402570**
    '''
    
    @pytest.fixture(scope="module")
    def smtp():
        with smtplib.SMTP("smtp.gmail.com") as smtp:
            yield smtp  # provide the fixture value
    

    addfinalizer终结函数

    1.除了yield可以实现teardown,在request-context对象中注册addfinalizer方法也可以实现终结函数。

    # 官方案例
    
    # content of conftest.py
    import smtplib
    import pytest
    
    @pytest.fixture(scope="module")
    def smtp_connection(request):
        smtp_connection = smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
        def fin():
            print("teardown smtp_connection")
            smtp_connection.close()
        request.addfinalizer(fin)
        return smtp_connection  # provide the fixture value
    

    2.yield和addfinalizer方法都是在测试完成后呼叫相应的代码。但是addfinalizer不同的是:

    • 他可以注册多个终结函数。

    • 这些终结方法总是会被执行,无论在之前的setup code有没有抛出错误。这个方法对于正确关闭所有的fixture创建的资源非常便利,即使其一在创建或获取时失败

    ---------------------------------pytest结合selenium自动化完整版-------------------------

    全书购买地址 https://yuedu.baidu.com/ebook/902224ab27fff705cc1755270722192e4536582b

    作者:上海-悠悠 QQ交流群:874033608

    也可以关注下我的个人公众号:yoyoketang

  • 相关阅读:
    BZOJ2821 作诗(Poetize) 【分块】
    BZOJ2724 蒲公英 【分块】
    Codeforces 17E Palisection 【Manacher】
    BZOJ2565 最长双回文串 【Manacher】
    Codeforces 25E Test 【Hash】
    CODEVS3013 单词背诵 【Hash】【MAP】
    HDU2825 Wireless Password 【AC自动机】【状压DP】
    HDU2896 病毒侵袭 【AC自动机】
    HDU3065 病毒侵袭持续中【AC自动机】
    HDU2222 Keywords Search 【AC自动机】
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/9401554.html
Copyright © 2011-2022 走看看