三、fixture介绍
1. fixture介绍:
fixture用 @pytest.fixture() 标识,定义在函数前面。
在编写测试函数时,可以将此函数的名称作为传入参数,pytest会以依赖注入方式将该函数的返回值作为测试函数的传入参数。
fixture 允许通过配置和组件选项参数化 fixture 和测试用例,或者跨功能、类、模块,甚至整个测试会话复用 fixture。
fixture 主要目的是为了提供一种可靠和可重复性的手段去运行那些最基本的测试内容。例如在测试网站时,每个测试用例都要登录和退出,利用 fixture 就可以只执行一次,否则每个测试用例都要执行这两步也是冗余。
fixture以一种模块化的方式实现,因为每个 fixture 的名字都能触发一个 fixture 函数,而这个函数本身又能调用其他的 fixture,这就是 fixture 的嵌套功能。
fixture 还提供了参数化功能,根据配置和不同组件来选择不同的参数。
2. fixture 的优势:
① 命名方式灵活,不局限于 setup 和 teardown 这几个命名
② conftest.py 配置里可以实现数据共享,不需要 import 就能自动找到 fixture
③ scope="module" 可以实现多个 .py 文件共享前置
④ scope="session" 可以实现多个 .py 跨文件使用一个 session 来完成多个用例
3. fixture 参数列表:
@pytest.fixture(scope="function", params=None, autouse=False, ids=None, name=None)
def test():
print("fixture初始化的参数列表")
4. fixture的应用:
3.4.1 fixture应用在初始化配置:
初始化过程一般进行数据初始化、连接初始化等。
常用场景:测试用例执行时,有的用例的数据是可读取的,需要把数据读进来再执行测试用例。setup 和 treadown 可以实现,fixture 可以灵活命名实现。
具体实现步骤:
1.导入pytest
2.创建 data() 函数
3.在 data() 函数上加 @pytest.fixture()
4.在要使用的测试方法 test_login 中传入data函数名称,也就是先执行 data() 函数再执行测试方法
5.不传入参数表明可以直接执行测试方法
3.4.2 fixture应用在配置销毁:
测试方法后需要销毁并清除数据:yield,yield调用第一次返回结果,第二次执行它下面的语句并返回结果
步骤:
(1)添加 @pytest.fixture(scope=module) 语句。
(2)在登录的方法中添加 yield,之后添加销毁清除的步骤。
5. 不同层级 scope 使用 fixture 实例:
fixture(scope='function', params=None, autouse=False, ids=None, name=None) :
scope 有 5 个级别参数:function(默认)、class、module、package(实验性的)、session
function:每个函数或方法都会调用
class:每个类调用一次,一个类可以有多种方法
module:每个 .py 文件调用一次,该文件内又有多个 function 和 class
session:多个文件调用一次,可以跨 .py 文件调用,每个 .py 文件就是 module
function 与 class 的区别:
作用于测试函数:两者是等价的,表示创建全新的固件对象;
针对的是类中测试方法:function表示每个测试方法创建全新的对象,class表示测试类中的所有测试用例公用一个固件对象;
session 与 module 的区别:
session:表示整个会话,不同的模块使用的对象也是相同的;
module:针对模块而言,每个模块中使用的是同一个固件对象,不同的模块创建的固件对象是不同的;
3.5.1 模块(module)级别使用 fixture 实例:
当把 scope 参数设置为 module 时,只在文件开始执行一次。
3.5.2 类(class)级别使用fixture 实例:
当 fixture 为class级别时,如果一个 class 里有多个用例,则都调用了此 fixture,此 fixture 只在该class中所有用例开始前执行一次。
3.5.3 会话(session)级别使用 fixture 与 conftest.py 配合:
fixture 为 session 级别是可以跨 .py 模块调用的,也就是当有多个 .py 文件用例时,如果多个用例只需调用一次 fixture,那就设置为 scope='session'。
采用一个单独的 conftest.py 文件,文件名称固定,pytest会自动识别该文件。放到工程目录下就可以全局调用,放到 package 下,就只在该 package 内有效。
from demo_selenium.demo_24_pytest import Cal
import pytest
@pytest.fixture(scope="session")
def get_cal():
return Cal()
# 声明一个测试函数
def test_add_1(get_cal):
print("test_add_1 使用的对象", get_cal)
# 一个类的测试用例
class TestCal(object):
def test_add_2(self, get_cal):
print("TestCal类 test_add_2 使用的对象:", get_cal)
def test_add_1(self, get_cal):
print("TestCal类 test_add_1 使用的对象:", get_cal)
# 第二个函数
def test_add_2(get_cal):
print("test_add_2 使用的对象", get_cal)
6. 使用 params 传递不同数据:
fixture(scope='function', params=None, autouse=False, ids=None, name=None),params是参数,默认可以不选。
如果需要在一系列测试用例的执行中,每轮执行都使用同一个 fixture,但是有不同的依赖场景,则可以考虑对 fixture 进行参数化,这种方式适用于对多场景的功能模块进行详尽测试。在 fixture 的声 明函数中,可以使用 request.param 获取当前使用的入参。
3.6.1 有效测试数据与预期失败 xfail 的测试数据:
在测试某些功能时,如果步骤一致,则可以使用数据驱动方式执行测试,也就是说多组数据使用一个测试方法。
当步骤相同而数据不同时,预期失败和预期正确的数据可以在一个测试方法中实现,这样就只有一组或几组数据会引起预期的失败,但不能在测试方法中标记预期失败,而应该通过参数传递的测试数据中使用 pytest.param 标记预期失败。
3.6.2 params与ids的应用:
对于复杂类型的测试数据通常加上 id 或 name 来表明数据的含义,并标记测试要点。测试数据除了字符串外,还可以是表达式、元组、字典、类等类型。
使用 ids 关键字参数自定义测试id
7. fixture的并列与嵌套调用:
测试方法传入多个 fixture 对象的方式有两种形式:
(1)以元组、列表或者字典等容器的形式存储一个需要返回多个数据的 fixture 对象;
(2)将多个数据分为每个 fixture 对象进行返回。
举例:
import pytest
def demo_add(a, b):
res = a + b
return res
@pytest.fixture()
def get_number():
print("获取加法运算的两个数")
a = 1
b = 2
return a, b
# 1.以元组的形式存储于一个返回多个数据的 fixture 对象
def test_1(get_number):
a = get_number[0]
b = get_number[1]
print("测试加法运算的被加数:%s,加数:%s" % (a, b))
assert demo_add(a, b) == 3
# 2.将多个数据分为多个 fixture 传入测试方法
@pytest.fixture()
def get_a():
print("获取被加数值")
a = 1
return a
@pytest.fixture()
def get_b():
print("获取加数的值")
b = 2
return b
# 将多个数据分为多个 fixture 对象传入测试方法
def test_2(get_a, get_b):
# 传入多个 fixture
assert demo_add(get_a, get_b) == 3
嵌套调用 fixture:常用使用场景:有先后关系的嵌套调用,多个@注解依赖可以通过传参方式,测试方法调用时只需调用最后的那种方法 fixture。
举例:
@pytest.fixture()
def get_c():
c = 1
return c
@pytest.fixture()
def get_d(get_c):
c = get_c
d = 2
return c, d
# fixture存在先后调用关系,
def test_3(get_d):
assert demo_add(get_d[0], get_d[1]) == 3
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 分享4款.NET开源、免费、实用的商城系统
· 解决跨域问题的这6种方案,真香!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库
· 5. Nginx 负载均衡配置案例(附有详细截图说明++)