本文详细讲解了Pytest框架之fixture,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
pytest作为python语言的测试框架,它的fixture有2种实现方式。
-
一种是xunit-style,跟unittest框架的机制非常相似,即setup/teardown系列
-
一种是它自己的fixture机制,以@pytest.fixture装饰器来申明。
fixture区别于unnitest的传统单元测试(setup/teardown)有显著改进:
1.有独立的命名,并通过声明它们从测试函数、模块、类或整个项目中的使用来激活。
2.按模块化的方式实现,每个fixture都可以互相调用。
3.fixture的范围从简单的单元测试到复杂的功能测试,可以对fixture配置参数,或者跨函数function,类class,模块module或整个测试session范围。
fixture的功能
fixture是pytest特有的功能,用以在测试执行前和执行后进行必要的准备和清理工作。使用pytest.fixture标识,定义在函数前面。在你编写测试函数的时候,你可以将此函数名称做为传入参数,pytest将会以依赖注入方式,将该函数的返回值作为测试函数的传入参数。
主要的目的是为了提供一种可靠和可重复性的手段去运行那些最基本的测试内容。
从功能上看来,与setup、teardown相似,但是优势明显:
命名方式灵活,不局限于setup和teardown这几个命名
conftest.py 配置里可以实现数据共享,不需要import就能自动找到一些配置
scope="module" 每一个.py文件调用一次
scope="session" 可以实现多个.py跨文件使用一个session来完成多个用例
特点及优势
1、命令灵活:对于setup.teardown,可以不起这两个名字

2、数据共享:在conftest.py配置里写的方法可以实现数据共享,不需要import导入,可以跨文件共享
3、scope的层次及神奇的yield组合相当于各种setup和teardown
4、实现参数化
基本用法
@pytest.fixture()
import pytest
@pytest.fixture()
def login():
print("完成登录操作")
def test_search():
print("搜索功能,此方法不需要完成登录即可执行")
def test_cart(login):
print("加入购物车,需要完成登录才可以")
fixture在自动化中的应用--作用域
@pytest.fixture(scope='module')
取值 |
范围 |
说明 |
function |
函数级 |
每个函数或方法都会调用 |
class |
类级别 |
每个测试类只运行一次 |
module |
模块级别 |
每一个.py文件只调用一次 |
package |
包级 |
没一个python包至调用一次 |
session |
会话级 |
每次会话只需要运行一次,会话内所有方法及类、模块都共享这个方法 |
pytest的fixture实现方式:fixture机制
通过@pytest.fixture装饰器来定义fixture。一个函数被@pytest.fixture装饰,那么这个函数就是fixture。
使用fixture时,分为二个部分:fixture定义、fixture调用。
除此之外,还有fixture的共享机制,嵌套调用机制。
1、定义fixture。
1)fixture通过函数实现。
2)使用@pytest.fixture进行装饰
import pytest
@pytest.fixture
def init():
pass
3)前置准备工作代码和后置清理工作代码,都写在一个函数里面。
4)通过yeild关键字,区分前置代码和后置代码 。yeild之前的代码为前置代码,yeild之后的代码为后置代码
在实际应用场景当中,可以只有前置准备工作代码,也可以只有后置清理工作代码。
import pytest
@pytest.fixture
def init():
print("用例执行之前,执行的代码") # 前置代码
yield
print("用例执行之后,执行的代码") # 后置代码
@pytest.fixture
def init2():
print("用例执行之前,执行的代码") # 只有用例执行之前的前置准备代码
@pytest.fixture
def init3():
yield
print("用例执行之后,执行的代码") # 只有用例执行之后的后置清理代码
5)fixture有4个作用域:测试会话(session)、测试模块(module)、测试类(class)、测试用例(function)
测试会话:pytest执行测试用例的整个过程,称为会话。
比如pytest收集到了100条用例并执行完成,这个过程称为测试会话。
设置fixture的作用域:通过@pytest.fixture(scope=作用域)来设置。默认情况下,scope=function
import pytest
# 没有设置scope,默认为测试函数级别。即调用此fixture的测试类/模块/函数下,每个测试函数都会执行一次这个fixture
@pytest.fixture
def init():
print("用例执行之前,执行的代码") # 前置代码
yield
print("用例执行之后,执行的代码") # 后置代码
# 设置scope为class。调用此fixture的测试类下,只执行一次这个fixture.
@pytest.fixture(scope="class")
def init2():
print("用例执行之前,执行的代码") # 只有用例执行之前的前置准备代码
# 设置scope为session。autouse表示自动使用。
# 那么在pytest收集用例后,开始执行用例之前会自动化执行这个fixture当中的前置代码,
# 当所有用例执行完成之后,自动化执行这个fixture的后置代码。
@pytest.fixture(scope="session",autouse=True)
def init3():
yield
print("用例执行之后,执行的代码") # 只有用例执行之后的后置清理代
6)fixture的返回值设置:yeild 返回值
当测试用例当中,要使用fixture里生成的数据时,则需要fixture返回数据。
若有数据返回则:yeild 返回值
import pytest
from selenium import webdriver
from time import sleep
# 设置scope为class。调用此fixture的测试类下,只执行一次这个fixture.
@pytest.fixture(scope="class")
def init2():
print("==== 测试类下,执行所有用例之前,执行的代码 ====")
driver = webdriver.Chrome()
yield driver # 返回driver对象
print("==== 测试类下,执行所有用例之后,执行的代码 ====")
driver.quit()
2、调用fixture
在fixture定义好之后,可以明确:
-
1)fixture处理了哪些前置准备工作、哪些后置清理工作
-
2)fixture作用在哪个范围(是测试函数?还是测试类?还是测试会话?还是测试模块?)
在以上2点都定下来了之后,接下来就是,在测试用例当中,根据需要调用不同的fixture。
调用方法有2种:
-
1、在测试用例/测试类上面加上:@pytest.mark.usefixture("fixture的函数名字")
-
2、将fixture函数名,作为测试用例函数的参数。
第2种用法,主要是用参数来接收fixture的返回值,以便在测试用例中使用。
第一种方式案例如下:
第二种方式案例如下:
3、fixture嵌套
fixture不但支持共享 ,还支持嵌套使用。
嵌套使用即:一个fixture,可以做另外一个fixture的参数。
如下图所示:名为init2的fixture,可以作为init的参数。
并且,init当中,将init2的返回值,同样返回。
当在用例当中,调用init时,init会自动去调用init2。
下图案例中,init2为class级作用域,init为function级作用域。
fixture的执行顺序如下:
-
init2的后置代码
-
init的后置代码
-
init的前置代码
-
init2的前置代码
到此这篇关于Pytest框架之fixture的文章就介绍到这了。
最后感谢每一个认真阅读我文章的人!作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,坚持几天便放弃的感受的话,在这里我给大家分享一些软件测试的学习资源,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,希望能给你前进的路上带来帮助。如果你用得到的话可以直接拿走:
软件测试资料领取:[内部资源] 想拿年薪40W+的软件测试人员,这份资料必须领取~
软件测试面试刷题工具领取:软件测试面试刷题【800道面试题+答案免费刷】
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!