当前位置:   article > 正文

Pytest夹具装置(fixture)-下篇_python 简单夹具,2024年最新软件测试面试宝典pdf_夹具 python

夹具 python

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注软件测试)
img

正文

@pytest.fixture(scope=“class”)
def my_name():
dic = {“name”:“清安”}
print(“你猜我叫什么?”)
yield dic[‘name’]
print(f"我叫{dic[‘name’]}")

“”“test_b.py”“”
class TestA:
def test1_get_name(self,my_name):
print(f"{class.name}",my_name)

def test2_get_name(self,my_name):
print(f"{class.name}",my_name)

class TestB:
def test1_get_name(self,my_name):
print(f"{class.name}",my_name)

def test2_get_name(self, my_name):
print(f"{class.name}", my_name)

test_b.py::TestA::test1_get_name 你猜我叫什么?
TestA 清安
PASSED
test_b.py::TestA::test2_get_name TestA 清安
PASSED我叫清安

test_b.py::TestB::test1_get_name 你猜我叫什么?
TestB 清安
PASSED
test_b.py::TestB::test2_get_name TestB 清安
PASSED我叫清安

可以看到,夹具直接作用到了类,并没有直接作用到每个测试用例,仅仅只是将值给到了每一个用例。这也是class与默认function的区别。以此类推,根据上述的文字描述,可以尝试module以及更高层的。:::

fixture销毁方式

我们把 fixture 后置处理又叫作 fixture 的销毁,fixture 的销毁有两种方

1、yield

前面写过一部分关于yield的代码。也在迭代器与生成器中讲过。此处不做多的讲解。它与return近似而不同于return。那么它如何具有销毁的作用呢,或者说,怎么样让它可以帮助我们达到销毁的一个作用

“”“conftest.py”“”
@pytest.fixture(scope=“function”)
def user():
print(“create success!”)
yield “清安”
print(“delete success!”)

模拟一下添加一个用户以及删除用户的功能,print处可以写sql语句以及各种语句。那么调用后呢?

def test_user(user):
print(user)
“”"
test_b.py::test_user create success!
清安
PASSED delete success!
“”"

看到了吗,先成功后,然后自动销毁,也就是删除的操作。

2、 addfinalizer

addfinalizer要比yield复杂一些。大致作用是一样的。

“”“conftest.py”“”
@pytest.fixture(scope=“function”)
def user(request):
print(“create success!”)
def clear():
print(“delete success!”)
request.addfinalizer(clear)
return ‘清安’

def test_user(user):
print(user)
“”"
test_b.py::test_user create success!
清安
PASSEDdelete success!
“”"

两种方式的实现效果,我们可以认为是一样,无论哪一种方式,均遵循以下规则

  1. 用例如果发生异常,不影响前后置动作的执行
  2. 如果前置动作失败,那么后置动作不会执行 :::

fixture标志传参-marker

“”“conftest.py”“”
import pytest

@pytest.fixture()
def user_name(request):
maker = request.node.get_closest_marker(“name”)
if maker is not None:
data = maker.args[0]
else:
data = None
return data

“”“test_b.py”“”
@pytest.mark.name(“清安”)
def test_get_user(user_name):
print(user_name)
assert user_name == ‘清安’
“”"
test_b.py::test_get_user 清安
PASSED
“”"

这样的方式会有一个warning提示,说没有注册。问题不大。这样的方式其实就是通过mark标记后,通过request进行参数获取,并返回值,测试用例这边通过夹具机制获取到值。比较新的知识点就是获取值的方式了。

fixture参数化

“”“conftest.py”“”

import pytest

datas = (‘清安’,‘拾贰’,‘詹姆斯’)
@pytest.fixture(params=datas,ids=[1,2,3])
def user_name(request):
print(“user_name参数:”,request.param)
return request.param

“”“test_b.py”“”
def test_user(user_name):
print(“我是:”,user_name)
“”"
test_b.py::test_user[1] user_name参数: 清安
我是: 清安
PASSED
test_b.py::test_user[2] user_name参数: 拾贰
我是: 拾贰
PASSED
test_b.py::test_user[3] user_name参数: 詹姆斯
我是: 詹姆斯
PASSED
“”"

在contest.py中ids参数处也可以写成列表推导式:ids=[i for i in range(1,4)]。ids就是一个标志,起一个提示的作用,告诉你用例运行到了第几个参数,也可称之为取别名。此处的传参不难理解,主要还是通过request进行,也就是代码中的request.param。:::warning

  1. fixture 可以通过设计 params,让依赖该 fixture 的用例迭代执行
  2. params 数据可以为[列表],(元组),{集合},{字典}
  3. params 数据要 fixture 中通过固定 request 变量来接收
    :::

参数化夹具与标记的结合使用

import pytest

@pytest.fixture(params=[0,1,2,pytest.param(3,marks=pytest.mark.skip)])
def user_data(request):
return request.param

def test_user(user_data):
print(user_data)
“”"
test_a.py::test_user[0] 0
PASSED
test_a.py::test_user[1] 1
PASSED
test_a.py::test_user[2] 2
PASSED
test_a.py::test_user[3] SKIPPED (unconditional skip)
“”"

看到了吗,这样的方式,可以帮助你更好的参数化与实现想要的功能。

fixture工厂模式

工厂模式有助于在单个测试中多次需要夹具结果的情况下。夹具不直接返回数据,而是返回一个生成数据的函数。然后可以在测试中多次调用此函数。简单的说就是便于重复造轮子。 例如,我想在一个测试用例里面重复注册多个用户:

“”“conftest.py”“”
import pytest

@pytest.fixture()
def user_func():
def use_func(name):
return {“name”:name}
return use_func

“”“test_b.py”“”
def test_user(user_func):
user1 = user_func(“清安”)
user2 = user_func(“拾贰”)
user3 = user_func(“安安”)
print(“注册用户:”,user1[‘name’],user2[‘name’],user3[‘name’])
“”"
test_b.py::test_user 注册用户: 清安 拾贰 安安
“”"

看着没感觉?那改一改改成有断言的:

pytest-assume插件

简单的说就是即使断言失败了,不影响后续代码的运行。接上述:

def test_user(user_func):
user1 = user_func(“清安”)
# assert user1
pytest.assume(user1)
user2 = user_func(“拾贰”)
# assert user2 == ‘11’
pytest.assume(user2 == ‘11’)
user3 = user_func(“安安”)
# assert user2
pytest.assume(user3)
print(“注册用户:”,user1[‘name’],user2[‘name’],user3[‘name’])

assume_________

E               AssertionError: assert False

…\venv\lib\site-packages\six.py:718: FailedAssumption
注册用户: 清安 拾贰 安安
=============================== short test summary info ======================== 
PASSED test_a.py::test_my_fruit_in_basket
============================== 1 failed, 1 passed in 0.18s =====================
assert_____
E       AssertionError: assert {‘name’: ‘拾贰’} == ‘11’

test_b.py:116: AssertionError
=============================== short test summary info =====================
PASSED test_a.py::test_my_fruit_in_basket
============================= 1 failed, 1 passed in 0.15s ====================

看到了吗,assert失败后是不会继续运行后续的代码,而assume插件是可以跑的。上述只是一个小示例,也可以运用到每个测试用例中。

模块化:使用fixture中的fixture

除了在测试函数中使用fixture之外,fixture函数还可以使用其他fixture本身。这有助于夹具的模块化设计,并允许在许多项目中重复使用特定于框架的装置。::: 这跟上述中的夹具并不局限于1个有些类似,不过用法上有些不同:

“”“contest.py”“”
import pytest

class Create:
def init(self,name):
self.name = name

@pytest.fixture(scope=‘module’)
def create(Str=‘清安’):
print(“CREATE SUCCESS”)
return Create(Str)

“”“test_a.py”“”
import pytest

class Delete:
def init(self,name):
self.name = name

@pytest.fixture(scope=‘module’)
def delete(create):
print(“DELETE SUCCESS”)
return Delete(create)

def test_user(delete):
assert delete.name
print(“SUCCESS”)

test_a.py::test_user CREATE SUCCESS
DELETE SUCCESS
SUCCESS
PASSED

注意上述代码,fixture中使用fixture,添加一个用户,随后删除。此处不局限于与module,也可以是是class亦或者session。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/672683
推荐阅读
相关标签