conftest和fixture的使用与介绍
fixture的介绍
fixture是在pytest框架中的一种特殊函数,用于处理某种级别的前置操作和后置操作,通常用于设置测试环境,准备测试数据,执行清理操作,fixture函数可以设置参数,并运行通过参数进行配置和参数化。
工作原理
pytest在执行测试用例前,会先检查该测试用例是否关联了fixture函数。
如果存在关联的fixture函数,Pytest会按照一定的顺序执行这些fixture函数。
当fixture函数执行完毕后,pytest才会执行测试用例。
在测试用例执行完毕后,pytest会再次执行相应的后置fixture函数,进行清理操作。
实操练习
创建和配置fixture
import pytest
@pytest.fixture
def my_fixture():
#这里填写fixture函数的逻辑
return a
在pytest测试用例中使用参数化语法@pytest.mark.parametrize
或直接在测试用例通过函数名进行引用
import pytest
def test_example(my_fixture):
#这里编写测试用例的逻辑
a=my_fixture
#此处相当于执行fixture方法,(通过方法名调用)然后获取返回值
结合conftest使用fixture
Conftest.py是Pytest中的一个特殊文件,用于存放全局的fixture和钩子函数。通过将fixture定义在conftest.py文件,我们可以实现全局共享和复用。同时,我们还可以再conftest.py中对fixture进行参数化,实现更灵活配置。
conftest.py文件中定义fixture的方式和在普通Python文件汇总定义的方式相同。例如:
import pytest
@pytest.fixture(scope='session')
#session级别是作用范围内所有测试用例都是用同一个fixture结果
def shared_fixture():
#在这里编写全局fixture函数的逻辑
driver = webdriver.chrome()
return driver
conftest辐射范围内引用全局的fixture函数
import pytest
from conftest import shared_fixture#引用全局fixture函数
def test_example(shared_fixture):#使用全局fixture函数作为参数
#编写测试用例逻辑
conftest使用fixture进行文件夹级别的函数复用
import pytest
from demo_of_feature.calculator import Calculator
@pytest.fixture(scope="session",autouse=True)
def my_fixture_of_init_calculator():
print("session 级别初始化")
ca = Calculator(10)
yield ca
#当所有调用这个夹具的用例都执行完毕后,才开始执行yield后面的雨具
print("session 级别回收")
实战演习
文件结构
-demo_of_feature 文件夹
- calculator.py 功能文件
- conftest.py conftest文件
- test_calculator.py 测试用例文件
- test_calculator1.py 测试用例文件2
calculator.py文件
import random
class Calculator:
def __init__(self,t):
random_int = random.randrange(1, 10) # 生成1到10之间的随机整数
print(random_int)
self.add_num=t+random_int
def calculator_add(self,add_num1,add_num2):
return add_num1+add_num2+self.add_num
conftest.py文件
import pytest
from demo_of_feature.calculator import Calculator
@pytest.fixture(scope="session",autouse=True)
def my_fixture_of_init_calculator():
print("session 级别初始化")
ca = Calculator(10)
yield ca
#当所有调用这个夹具的用例都执行完毕后,才开始执行yield后面的雨具
print("session 级别回收")
test_calculator.py文件
def test_Calculator(my_fixture_of_init_calculator):
print(my_fixture_of_init_calculator.calculator_add(1, 2))
test_calculator1.py文件
def test_Calculator1(my_fixture_of_init_calculator):
print(my_fixture_of_init_calculator.calculator_add(1, 2))
执行结果与解析
执行:右键点击所在文件夹,执行测试
测试结果:
============================= test session starts =============================
collecting ... collected 2 items
test_calculator.py::test_Calculator session 级别初始化
8
PASSED [ 50%]21
test_calculator1.py::test_Calculator1 PASSED [100%]21
session 级别回收
============================== 2 passed in 0.52s ==============================
解析:
在这里面已知每一次功能用例的初始化都会输出一个值,而通过结果可知,这个功能用例的初始化操作只执行了一次,而分明有两个测试用例调用了fixture函数来获取实例对象。而fixture的层级为session
即:session的复用级别是文件夹层级,这个东西在首次调用时,会执行一遍,然后在第二次调用时(层级符合复用要求)便不再执行方法过程,而是直接使用首次产生的结果。
yield关键字的使用:这个与return同样是返回值,但是不同的是,这个返回值后并不会马上关闭fixture函数,而是会等待所有调用这个fixture函数的测试用例执行完毕后执行一遍。
复用:fixture函数在指定复用层级里会标记管辖范围里的分组条件,如过符合分组条件,则当该分组的测试用例调用fixture函数时,如果为该分组第一个调用,则为该分组执行一次fixture函数,如果非首次调用,则已经分配给该分组fixture结果,直接使用即可。
fixture的作用范围或分组标准:scope
- function函数 级别(范围窄)
- class类级别
- module模块级别
- session会话级别(范围大)
- function函数级别:分组标准:每个测试函数def只执行一次(感觉没有用处,因为fixture的调用单位即是函数,可以理解为不存在复用现象)
- class类级别:分组标准:每个测试类只执行一次,无论这个测试类里有多少个测试方法,都会被执行到并且共享fixture。即同一个类里面的所有方法如果调用fixture都会使用同一个fixture结果。
- module模块级别:分组标准:每个测试文件只执行一次,同一个测试文件里如果多个测试方法调用fixture方法,都会使用同一个fixture结果。
- session:层级和conftest的作用范围一致,即只要你能调用到这个层级的fixture,你们用的就是同一个fixture结果,是真正的全复用。
- 即官方给出的预设层级里并没有针对同一个文件夹里多个py文件进行单独复用的操作,即文件夹A和文件夹B里的东西调用fixture时,是调用同一个fixture结果。
报错找不到conftest里的夹具fixture
点击运行配置,将里面的工作路径选为根目录
因为,从pycharm中点击执行,是以当前py文件所在目录为起点,向下搜寻,自然搜索不到上面的conftest,即处于根目录的conftest,所以需要修改工作路径,设置为从根目录开始往下搜索