Python测试框架pytest(08)fixture - conftest.py、yield、addfinalizer

29 篇文章 8 订阅
28 篇文章 13 订阅

目录

1、conftest.py作用范围

2、yield实现teardown

3、yield+with的结合

4、addfinalizer终结函数


1、conftest.py作用范围

conftest.py 文件名称是固定的,pytest 会自动识别该文件,可以理解成一个专门存放 fixture 的配置文件。

一个工程下可以建多个 conftest.py 的文件,一般在工程根目录下设置的 conftest 文件起到全局作用。在不同子目录下也可以放 conftest.py 的文件,作用范围只能在该层级以及以下目录生效。

conftest.py 配置 fixture 注意事项:

  • pytest 会默认读取 conftest.py 里面的所有 fixture。

  • conftest.py 文件名称是固定的,不能改动。

  • conftest.py 只对同一个 package 下的所有测试用例生效。

  • 不同目录可以有自己的 conftest.py,一个项目中可以有多个 conftest.py。

  • 测试用例文件中不需要手动 import conftest.py,pytest 会自动查找。

示例:

目录结构:

1、My_pytest_Demo/conftest.py

脚本代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import pytest

@pytest.fixture(scope='session', autouse=True)
def login():
    print("====准备登录====")

2、My_pytest_Demo/fixture_chapter/conftest.py

脚本代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import pytest

@pytest.fixture(scope='session', autouse=True)
def bai_du():
    print("====登录成功====")

3、My_pytest_Demo/fixture_chapter/login_demo.py

脚本代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import pytest

class TestCase:
    def test_case(self):
        print("====执行用例====")

if __name__ == '__main__':
    pytest.main(['-s', 'login_demo.py'])

4、运行结果:

执行login_demo.py文件,根目录下的conftest.py先执行,之后执行fixture_chapter目录下的conftest.py,最后才执行login_demo.py

2、yield实现teardown

前面章节讲的其实都是 setup 的操作,接下来讲解怎样来实现 teardown 的操作。

用 fixture 实现 teardown 并不是一个独立的函数,而是用 yield 关键字来开启 teardown 操作。

  • 当 pytest.fixture(scope="session") 时,作用域是整个测试会话,即开始执行 pytest 到结束测试只会执行一次。

  • 当 pytest.fixture(scope="function") 时,pytest 的 yield 类似 unittest 的 teardown。每个方法(函数)都会执行一次。

  • 当 pytest.fixture(scope="module") 时,module 作用是整个 .py 文件都会生效(整个文件只会执行一次),用例调用时,参数写上函数名称就可以。

1、创建test_fixture4.py文件

脚本代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""
import pytest

@pytest.fixture(scope="session")
def open():
    # 会话前置操作setup
    print("===打开浏览器open===")
    yield
    # 会话后置操作teardown
    print("===关闭浏览器open===")

@pytest.fixture
def login(open):
    # 方法级别前置操作setup
    print("===登陆操作login===")
    name = "===账号==="
    pwd = "===密码==="
    # 返回变量
    yield name, pwd
    # 方法级别后置操作teardown
    print("===登录成功login===")

def test_case1(login):
    print("===测试用例1===")
    # 返回的是一个元组
    print(login)
    # 分别赋值给不同变量
    name, pwd = login
    print(name, pwd)
    assert "账号" in name
    assert "密码" in pwd

def test_case2(login):
    print("===测试用例2===")
    print(login)

2、运行结果:

注意要点:

  • 如果 yield 前面的代码,即 setup 部分已经抛出异常,则不会执行 yield 后面的 teardown 内容。

  • 如果测试用例抛出异常,yield 后面的 teardown 内容还是会正常执行。

3、yield+with的结合

yield 也可以配合 with 语句使用。

创建test_fixture5.py文件

脚本代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""
import pytest
import smtplib

@pytest.fixture(scope="module")
def smtp_connection():
    with smtplib.SMTP("smtp.gmail.com", 587, timeout=5) as smtp_connection:
        yield smtp_connection

4、addfinalizer终结函数

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

1、创建test_fixture6.py文件

在用法上,addfinalizer 跟 yield 是不同的,需要你去注册作为终结器使用的函数。例如:增加一个函数 fin,并且注册成终结函数。

脚本代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""
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_case(test_addfinalizer):
    print("===最新用例===", test_addfinalizer)

2、运行结果:

yield 与 addfinalizer 的区别:

1、addfinalizer 可以注册多个终结函数。

创建test_fixture_7.py文件

脚本代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""
import pytest

@pytest.fixture()
def demo_addfinalizer(request):
    print("====setup====")
    def fin1():
        print("====teardown1====")
    def fin2():
        print("====teardown2====")
    def fin3():
        print("====teardown3====")

    # 注册demo_addfinalizer为终结函数
    request.addfinalizer(fin1)
    request.addfinalizer(fin2)
    request.addfinalizer(fin3)

def test_case1(demo_addfinalizer):
    print("====执行用例test_case1====")

def test_case2(demo_addfinalizer):
    print("====执行用例test_case2====")

def test_case3(demo_addfinalizer):
    print("====执行用例test_case3====")

运行结果:

注册的3个函数都被执行了,但是要注意的是执行顺序,与注册的顺序相反。

2、当setup的代码执行错误,addfinalizer依旧会执行。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wangmcn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值