Pytest中夹具

本文详细介绍了pytest中的前后置夹具(setup_class,teardown_class,setup_method,teardown_method,setup_function,teardown_function)的使用,以及如何通过fixture进行自定义并管理测试环境,包括作用域的选择和登录状态的保持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.pytest前后置(夹具)

作用:在用例执行之前和用例执行完之后,需要做的准备工作以及收尾工作,主要用于固定测试环境,以及清理回收
资源。
一般情况用例的定义有三种形式

class TestDemo:
	# 类夹具:执行类中的用例之前操作
	def setup_class(self):
		print("类夹具执行之前输出的内容")
	def test_3(self):
		print("我是用例3")
	# 一般用例脚本都使用实例方法,不建议使用类方法
	@classmethod
	def test_4(cls):
		print("我是用例4")
	# 类夹具:执行类中的用例之后操作
	def teardown_class(self):
		print("类夹具执行之后输出的内容")
  • 方法
class Demo_001:
	# 定义方法级别的夹具
	def setup_method(self):
		print("方法用例执行之前的操作")
	def teardown_method(self):
		print("方法用例执行之后的操作")
	@pytest.mark.run(order=2)
	def test_3(self):
		print("我是用例300")
	@classmethod
	def test_4(cls):
		print("我是用例400")
	def test_5(self):
		print("500")
	def test_6(self):
		print("600")
  • 函数
def test_1():
	print("我是用例1")
def test_2():
	print("我是用例2")
def test_3():
	print("我是用例3")
def test_4():
	print("我是用例4")
# 使用函数级别的夹具
def setup_function():
	print("函数用例之前的操作")
def teardown_function():
	print("函数用例之后的操作")

模块级别的夹具
setup_module
teardown_module

当用例包中第一个用例开始执行出发前置,最后一个用例执行完毕之后执行后置

总结:

  • 如果需要固定测试环境,可以针对不同类型的用例使用不同的夹具进行固化测试环境(前后置)
  • 类,方法,函数并不一定非得前后置一起使用,可以只有前置或者只有后置也可以进行使用

2.pytest自定义夹具

使用fixture灵活调度固定的测试环境
fixture基本介绍

  • 是pytest当中的一个装饰器
  • @pytest.fixture(scope=“夹具的作用域”, params=“参数化”,autouse=“自动使用” )
  • 通过fixture创建自定义的夹具
# 作用域:如果是function,针对当前模块所有的方法及函数自动调用
@pytest.fixture(scope="function", autouse=True)
def go_shop():
	print("使用自动保持登录的id")
	yield
	print("保持登录号的用户id")
  • 手动调用以及自动调用的区别及使用
import time
import pytest
# @pytest.mark.skip(reason="版本原因跳过该用例")
def test_1(go_shop):
	print("我是用例1")
@pytest.mark.skipif(3 < 2, reason="反例不执行")
def test_2(go_shop):
	# time.sleep(5)
	print("我是用例2")
	# print(1/0)
class TestDemo:
# 类夹具:执行类中的用例之前操作
	def setup_class(self):
		print("类夹具执行之前输出的内容")
	def test_3(self,go_shop):
		print("我是用例3")
	# 一般用例脚本都使用实例方法,不建议使用类方法
	@classmethod
	def test_4(cls):
		print("我是用例4")
	# 类夹具:执行类中的用例之后操作
	def teardown_class(self):
		print("类夹具执行之后输出的内容")
# 作用域:如果是function,针对当前模块所有的方法及函数自动调用
# 如果使用默认的不进行自动调用的状态,那么可以进行手动使用
# 使用手动调用自定义夹具可以在需要执行的用例函数里面添加一个形参:fixture夹具名字
@pytest.fixture(scope="function", autouse=False)
def go_shop():
	print("使用自动保持登录的id")
	yield
	print("保持登录号的用户id")

fixture作用域:

  • function:针对函数和方法
    方法或者函数执行之前及之后的前后置
  • calss:针对类
    类执行之前及之后的前后置
  • module:针对模块
    当前模块第一个用例执行之前及最后一个用例执行之后的前后置
  • session:针对整个包
    当用例包中第一个用例开始执行出发前置,最后一个用例执行完毕之后执行后置

3.fixture进行集中管理

整个项目中会定义一个模块:conftest.py专门用来放置自定义的fixture,文件名固定不能做修改。
不需要进行导包,就可以进行使用,不管是在根目录还是用例目录,以及模块目录都会被指定的作用域进行调用触发。
执行顺序:从最外面往最里面执行,从上到下,如果是同一个conftest.py模块那么会按照ASCII编码进行调用

4.使用测试框架管理用例

为了更加方便管理和使用用例的执行,那么会把用例定义成函数或者方法通过pytest进行管理
用例当中如果出现相同的代码需要进行独立封装,减少代码的冗余以及提高代码复用率
对用例需要进行测试环境的固定(前后置处理)

@pytest.fixture
def driver():
	print("用例开始执行,获取驱动")
	driver = Chrome()
	yield driver
	print("用例执行完毕,关闭驱动")
	driver.quit()

5.保持登录状态

通过fixture夹具,把需要登录成功之后的投标流程用例进行区分
完成前台登录的前置任务(保持登录状态)

# 完成前台登录的前置任务(保持登录状态)
@pytest.fixture
def user_driver():
	driver = Chrome()
	driver.get("http://47.107.116.139/fangwei/")
	driver.maximize_window()
	# 1.实例化一个页面对象
	rece_page = ReceptionLoginPage(driver)
	# 2.通过对象调用实例方法用例脚本执行结果返回断言
	msg = rece_page.login("admin", "msjy123")
	print(msg)
	return driver

def test_user_deal_ok(user_driver):
	# 支付流程用例
	rece_page = ReceptionLoginPage(user_driver)
	msg = rece_page.pay(10000, "msjy123")
	print(msg)
	assert msg == "投标成功!"
	# //*[@id="fanwe_success_box"]/table/tbody/tr/td[2]/div[2]

def test_user_deal_fail(user_driver):
	# 支付流程用例
	rece_page = ReceptionLoginPage(user_driver)
	msg = rece_page.pay(10000, "9988")
	print(msg)
	assert msg == "支付密码错误"
	# //*[@id="fanwe_error_box"]/table/tbody/tr/td[2]/div[2]

由于正例及反例元素定位值会发生变化,所以采用手写xpath方式进行元素定位
通过元素id以开头为参照进行定位

# - 获取提示信息断言实际结果
# text_pay_msg = (By.XPATH, '//*[@id="fanwe_success_box"]/table/tbody/tr/td[2]/div[2]')
text_pay_msg = (By.XPATH, '//*[starts-with(@id,"fanwe_")]/table/tbody/tr/td[2]/div[2]')
# 点击确定按钮关闭实际结果
btn_pay_ok = (By.XPATH, '//*[startswith(@
id,"fanwe_")]/table/tbody/tr/td[2]/div[3]/input[1]')
# //*[@id="fanwe_error_box"]/table/tbody/tr/td[2]/div[3]/input[1]
### 使用 Pytest 测试夹具 (Fixture) 测试夹具在自动化测试框架中扮演着重要角色,特别是在 Pytest 中。通过定义一次性的设置和清理操作,可以减少重复代码并提高可维护性。 #### 定义基本 Fixture 可以在 `conftest.py` 文件或测试文件内定义 fixture 函数来创建共享资源: ```python import pytest @pytest.fixture def first(): """返回固定的用户名""" return "yoyo" ``` 上述函数会在任何标记为依赖它的测试案例之前自动调用,并传递参数给这些测试案例[^1]。 #### 应用于多个测试模块中的 Fixture 当有多个测试文件都需要相同的 setup/teardown 功能时,可以把 fixture 放置在一个项目的根目录下的 `conftest.py` 文件里,这样所有子包内的测试都能访问到这个 fixture 而无需重新导入。 对于 `test_fixture11.py` 和 `test_fixture12.py` 这两个例子来说,在这两个文件里的测试都接收到了由 `first()` 提供的数据作为输入参数。 ```python # test_fixture11.py import pytest def test_1(first): '''用例传fixture''' print("测试账号:%s" % first) assert first == "yoyo" if __name__ == "__main__": pytest.main(["-s", "test_fixture11.py"]) # test_fixture12.py import pytest def test_2(first): '''用例传fixture''' print("测试账号:%s" % first) assert first == "yoyo" if __name__ == "__main__": pytest.main(["-s", "test_fixture12.py"]) ``` #### 参数化 Fixtures 如果希望同一个 fixture 可以为不同的测试提供不同版本的结果,则可以通过 `@pytest.mark.parametrize` 来实现这一点[^3]。 例如下面的例子展示了如何让 wallet fixture 接受多种初始金额的情况: ```python import pytest @pytest.fixture(scope="module") def wallet(request): balance = request.param yield {"balance": balance} @pytest.mark.parametrize('wallet', [(10,), (20,)], indirect=True) def test_wallet(wallet): print(f'Wallet Balance is {wallet["balance"]}') assert isinstance(wallet['balance'], int) ``` 在这个例子中,`indirect=True` 表明 parametrize 的值应该被当作 fixture 函数的参数处理而不是直接传递给测试函数本身。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值