fixture简介及调用
阅读目录:
1.fixture的优势
2.fixture介绍
3.fixture的调用
4.fixture嵌套
fixture的优势:
- fixture可以根据需要自定义测试用例的前置、后置操作;
- fixture是通过yield来区分前后置的,前后置均可以单独存在,fixture如果有后置,前置不报错就都会执行,前置报错后置就不会执行。
- 与setup、teardown类似,fixture提供了测试执行前和测试执行后的处理,但是又比setup、teardown更灵活好用,比如:fixture命名更加灵活,不局限于setup和teardown
- conftest.py配置里可以实现数据共享,可以方便管理、修改和查看fixture函数,并且不需要import就能自动找到fixture
- fixture可用于封装数据,也可用于封逻辑动作等
fixture使用介绍
简介:
fixture装饰器来标记固定的功能函数,
在其他函数、类、模块或整个工程调用它时,会被激活并优先执行,通常会被用于完成预置处理和重复操作。
方法:fixture(scope=“function”, params=None, autouse=False, ids= None, name=None)
常用参数
- scope: 被
@pytest.fixture
标记为方法的的作用域,默认是function, 还可以是class、module、package、session等,(简而言之 就是在需要前置后置后置的函数) - params: 用于给fixture传参,可实现数据基于fixture的数据驱动,接收一个可以迭代的对象, 比如:列表[], 元组[], 字典列表{[],[],[]}、字典元组{(),(),()},提供参数数据供调用fixture的用例使用; 传进去的参数,可以用request.param调用
- autouse: 是否自动运行,是一个bool值,默认为false; 当为True时, 作用域内的测试用例都会自动调用该fixture
- ids: 用例标识id,每一个ids 和 params 一一对应,如果没有id,将从params自动产生
- name: 给被
@pytest.fixture
标记的方法取一个别名,如果使用了nam, 那只能将name传入,函数名不再生效
fixture调用
函数引用/参数引用
方法:
- 将fixture名称作为测试用例函数/方法的参数;
- 如果fixture有返回值,必需使用这种方式,否则获取不到返回值(比如:`@pytest.mark.usefixtures()这种方式就获取不到返回值,详情见:后续填坑)
- 函数引用: 测试类中测试方法形参是测试类外被
@pytest.fixture()
标记的测试函数,也就是说,fixture标记的函数可以用于测试类 内部 - 参数引用: 测试类中测试方法性参数是当前测试类中被
@pytest.fixture()
标记的方法
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : zcs
# @wx :M_haynes
import pytest
@pytest.fixture()
def fun():
z = "fixture_fun函数"
print(" --- fixture ---")
assert 1 == 1
return z
@pytest.fixture()
def fun1():
z_1 = "fixture_fun1函数"
print(" --- fixture1 ---")
assert 2==2
return z_1
def test_a(fun):
print(" --- ------------------- test_a")
assert fun == "fixture_fun函数"
print("fun返回值判断正确:%s"%fun)
class TestB(object):
def test_b(self, fun1):
print(" --------------------- test_b")
ass = 'AAAA'
if fun1 == ass:
print("返回的值正确")
else:
print("判断的值是:%s"%ass)
print("fixture的返回值是:{}".format(fun1))
def test_c(self, fun3):
print(" --------------------- test_c")
@pytest.fixture()
def fun3(self):
print(" --------------------- test_d")
运行结果:
fixture 返回params中的值
@pytest.fixture(params=['zzd', '接口自动化测试', 'pytest测试大纲'])
def fun4(request): # 必须是 request这个参数名
return request.param # 依次取列表总的每一个值返回
class TestC(object):
def test_d(self, fun4):
print(" --------------------- test_d")
print(f"----------fun4, data={fun4}")
@pytest.fixture(params=[1,2,3,4,5,6,7,8,9,0])
def fun5(request):
return request.param * 10
def test_d(fun5):
print("--------------------- test_d")
print("传入的值是:%s"%fun5)
运行结果:
加装饰器
测试用例上加装饰器
- 可以多个fixture参数,放前面的先执行,放后面的后执行,即 执行顺序和usefixtures后面引用顺序对应
示例一
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : zsc
# @wx :M_haynes
import pytest
@pytest.fixture()
def fun():
print("---fixture")
@pytest.fixture()
def fun2():
print("---fixture2")
def test_a(fun):
print("--------------test_a")
class Test01:
def test_b(self, fun2):
print("--------------test_b")
@pytest.mark.usefixtures('fun2','fun')
def test_c(self):
print("--------------test_c")
运行结果:
先调用fun_zsq_2 , 然后调用 fun_zsq_1
- 可以多个装饰器,先执行的放底层,后执行的放上层
示例二:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : zsc
# @wx :M_haynes
import pytest
@pytest.fixture()
def fun():
print("---fixture")
@pytest.fixture()
def fun2():
print("---fixture2")
def test_a(fun):
print("--------------test_a")
@pytest.mark.usefixtures('fun')
@pytest.mark.usefixtures('fun2')
class Test01:
def test_b(self):
print("--------------test_b")
def test_c(self):
print("--------------test_c")
运行结果:
示例三:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : zsc
# @wx :M_haynes
import pytest
@pytest.fixture()
def fun():
print("---fixture")
@pytest.fixture()
def fun2():
print("---fixture2")
def test_a(fun):
print("--------------test_a")
class Test01:
def test_b(self):
print("--------------test_b")
@pytest.mark.usefixtures('fun')
def test_c(self, fun2):
print("--------------test_c")
结果: 同时有装饰器和引用,装饰器先执行
测试类上加装饰器
类中所有测试用例都会调用该fixture
示例一:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : zsc
# @wx :M_haynes
import pytest
@pytest.fixture()
def fun_zsq_1():
print("--------------------- 添加装饰器")
@pytest.fixture()
def fun_zsq_2():
print("-------------------- 添加装饰器2")
def test_zsq_1(fun_zsq_1):
print("-------------- test_zaq_1")
class Test001:
def test_zsq_2(self, fun_zsq_2):
print("--------------------- test_zaq_2")
@pytest.mark.usefixtures("fun_zsq_2", "fun_zsq_1")
def test_dd(self):
print("--------------------- test_dd")
结果: 同时有装饰器和引用,装饰器先执行
示例二:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : zsc
# @wx :M_haynes
import pytest
@pytest.fixture()
def fun_zsq_1():
print("--------------------- 添加装饰器")
@pytest.fixture()
def fun_zsq_2():
print("-------------------- 添加装饰器2")
@pytest.mark.usefixtures('fun_zsq_2')
class Test01:
def test_b(self):
print("--------------test_b")
@pytest.mark.usefixtures('fun_zsq_1')
def test_c(self):
print("--------------test_c")
结果: 方法和类上都有装饰器,方法上装饰器先执行
总结:
@pytest.mark.usefixtures('fun2')
@pytest.mark.usefixtures('fun')
等价于:
@pytest.mark.usefixtures('fun','fun2')
自动适配: fixture 设置autouse=True
注意: 影响作用域内所有用例
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : zsc
# @wx :M_haynes
import pytest
@pytest.fixture()
def fun():
print("---fixture")
@pytest.fixture(autouse=True)
def fun2():
print("---fixture2")
def test_a():
print("--------------test_a")
class Test01:
def test_b(self):
print("--------------test_b")
def test_c(self):
print("--------------test_c")
结果:每个测试用例都执行了fun_zd_1、fun_zd_2
fixture嵌套:
注意:不能用@pytest.mark.usefixtures
示例: 另个fixture, fun依赖 login
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : zsc
# @wx :M_haynes
import pytest
@pytest.fixture()
def login():
print("---登录")
@pytest.fixture()
def fun(login):
print("---fun")
# 下面写法报错
# @pytest.fixture()
# @pytest.mark.usefixtures(login)
# def fun():
# print("---fun")
# @pytest.mark.usefixtures(fun) # 报错
def test_a(fun):
print("--------------test_a")
结果:
本文由mdnice多平台发布