『德不孤』Pytest框架|『德不孤』Pytest框架 — 12、Pytest中Fixture装饰器(二)


目录

  • 5、addfinalizer关键字
  • 6、带返回值的Fixture
  • 7、Fixture实现参数化
    • (1)params参数的使用
    • (2)进阶使用
  • 8、@pytest.mark.usefixtures()的使用

5、addfinalizer关键字 yield是当用例执行完之后,会执行yield后面的代码,但用例不能有return返回值。
addfinalizer实现功能跟yield一样,但是用例可以return参数,传给后面用例。
示例1:
import pytest@pytest.fixture() def login(request): # request是Pytest中的一个关键字,固定写法。 # 步骤1:正常编写前置用例 print("打开APP") print("输入账号,密码,进行登录") username = '小明'# 步骤3:定义用例执行后要执行的代码,封装到一个函数中 def closeApp(): # 这个closeApp函数命是自定义的 print("关闭APP")# 步骤4:执行上面封装的代码。 # 通过request关键字,结束上面的函数。 request.addfinalizer(closeApp)# 终结函数 # 步骤2:返回参数给测试用例。 # 返回参数可以是变量,对象,表达式,常量值。 return usernamedef test_add_cart(login):# 步骤3 print("添加购物车--需要登录") # 这里需要注意: 如果要使用fixture方法返回的数据, # 就直接填写fixture方法名称。 # 返回参数的名称和可以和fixture方法的名称相同。 print(f"登陆者:{login}") def test_add_address(login):# 步骤3 print("添加收货地址--需要登录") print(f"登陆者:{login}")if __name__ == '__main__': pytest.main()""" 执行结果:test_01.py::test_add_cart 打开APP 输入账号,密码,进行登录 添加购物车--需要登录 登陆者:小明 PASSED关闭APPtest_01.py::test_add_address 打开APP 输入账号,密码,进行登录 添加收货地址--需要登录 登陆者:小明 PASSED关闭APP """

示例2:
# 示例一个selenium自动化关闭开启关闭浏览器的操作。 import time import pytest from selenium import webdriver@pytest.fixture() def driver(request):# request是Pytest中的一个关键字,固定写法。 # 步骤1:创建浏览器驱动对象 driver = webdriver.Firefox()# 步骤3:定义用例执行后要执行的代码,封装到一个函数中 def end():# 这个end函数命是自定义的 driver.quit()# 步骤4:执行上面封装的代码。 # 通过request关键字,结束上面的函数。 request.addfinalizer(end)# 终结函数# 步骤2:返回浏览器驱动对象,给测试用例 # 返回参数可以是变量,对象,表达式,常量值。 # 返回参数的名称和可以和fixture方法的名称相同。 return driverdef test_baidu(driver): """打开百度""" driver.get("http://www.baidu.com") time.sleep(3)def test_163(driver): """打开网易""" driver.get("http://www.163.com") time.sleep(3)if __name__ == '__main__': pytest.main()

示例3:
使用yield也可以返回数据。(这种方式好神奇)
import pytest@pytest.fixture() def login(request): print("打开APP") print("输入账号,密码,进行登录") username = '小明' yield username print("关闭APP")def test_add_cart(login):# 步骤3 print("添加购物车--需要登录") print(f"登陆者:{login}")def test_add_address(login):# 步骤3 print("添加收货地址--需要登录") print(f"登陆者:{login}")if __name__ == '__main__': pytest.main()""" 执行结果: test_01.py::test_add_cart 打开APP 输入账号,密码,进行登录 添加购物车--需要登录 登陆者:小明 PASSED关闭APPtest_01.py::test_add_address 打开APP 输入账号,密码,进行登录 添加收货地址--需要登录 登陆者:小明 PASSED关闭APP """

总结:returnyield都表示返回的意思,但是return的后面不能有代码,yield的后面可以接代码。
6、带返回值的Fixture 上面例子是带返回值并且还要实现teardown()后置函数的Fixture写法。
这里就是单纯的说明带返回值的Fixture。
我们可以选择让Fixture返回我们需要的东西,如果Fixture需要配置一些数据,读个文件,或者连接一个数据库,那么你可以让Fixture返回这些数据或资源。
示例:
""" 1.学习目标 掌握带返回值的fixture 2.操作步骤 2.1 编写带返回值fixture 2.2 使用测试用例调用 3.需求 """ import pytest# 编写fixture @pytest.fixture() def data(): print("准备好的测试数据") return 3 # 返回数据def test_data(data): print("执行用例步骤") print(f"得到参数{data}")# 可以使用在用例步骤中 assert data =https://www.it610.com/article/= 3# 使用在断言中""" 执行结果:test_01.py::test_data 准备好的测试数据 执行用例步骤 得到参数3 PASSED """

说明:Fixture装饰类中,也可以实现数据的准备。
7、Fixture实现参数化 Fixture修饰的函数可以通过添加params参数来实现参数化。(实际工作中,不常用此方式)
(1)params参数的使用
request代表Fixture的调用状态,request.param作为返回值供测试使用。
示例:
""" 1.学习目标 掌握带参数化fixture编写 2.操作步骤 @pytest.fixture(params=[列表格式数据]) request是pytest中内置关键字""" import pytest# 编写fixture,带参数 data = https://www.it610.com/article/[666, 888, 1000]# request会接收到params=data的参数 # 然后request.param(固定写法)每次传递一个参数 @pytest.fixture(params=data) def need_data(request): return request.paramdef test_data(need_data): print(f"测试数据:{need_data}") assert 666 == need_dataif __name__ == '__main__': pytest.main()""" test_01.py::test_data[666] 测试数据:666 PASSED test_01.py::test_data[888] 测试数据:888 FAILED test_01.py::test_data[1000] 测试数据:1000 FAILED """

说明:上面的例子,通过assert简单判断下拿到的request.param值,有没有在原来的参数列表中。实际上就相当于遍历了一遍参数列表,们可以看到测试方法被调用了3次。
(2)进阶使用
参数是一个元组列表格式的数据。
""" 1.学习目标 掌握带参数化fixture编写 2.操作步骤 @pytest.fixture(params=[列表格式数据]) request是pytest中内置关键字 3.需求 4.总结 1.pytest fixture 主要是用来完成测试用例执行前后操作 例如:测试前后对数据库连接/断开; 打开/关闭浏览器APP 2.fixture还可以用来准备测试数据 带参数fixture 有返回值fixture(在实际工作中返回数据比较灵活,推荐使用) 3.fixture中的参数 scope: 确定fixture作用范围 默认function,class,module,session autouse:当值true时,相当于setup name: 对fixture重命名 """ import pytest# 编写fixture,带参数 @pytest.fixture(params=[("孙悟空", 666), ("猪八戒", 777), ("沙和尚", 888)]) def need_data(request): return request.paramdef test_data(need_data): print(f"测试人物:{need_data[0]}") print(f"测试分数:{need_data[1]}")if __name__ == '__main__': pytest.main()""" 执行结果:测试人物:孙悟空 测试分数:666 PASSED测试人物:猪八戒 测试分数:777 PASSED测试人物:沙和尚 测试分数:888 PASSED """

总结:params参数支持的格式。
  • 列表[]
  • 元组()
  • 元素列表[(),(),()]
  • 字典列表[{},{},{}],提示:只能取{}整体。
  • 字典元祖({},{},{}),提示:只能取{}整体。
8、@pytest.mark.usefixtures()的使用 @pytest.mark.usefixtures("fixturename")装饰类也是一种调用Fixture的方式。
@pytest.mark.usefixtures("fixturename")装饰类可以装饰模块、类、函数、方法。
usefixtures与传fixture区别:
如果Fixture有返回值,则不能用@pytest.mark.usefixtures("fixturename")装饰器修饰用例。
如果Fixture没有返回值,用@pytest.mark.usefixtures("fixturename")装饰器和@pytest.fixture()装饰器作用一样。
【『德不孤』Pytest框架|『德不孤』Pytest框架 — 12、Pytest中Fixture装饰器(二)】示例:
import pytest# 步骤1 @pytest.fixture() def login(): print("打开APP") print("输入账号,密码,进行登录") yield# 当用例执行完成后,执行yield后的代码 print("关闭APP")# 方式一: def test_add_cart(login): print("添加购物车--需要登录")# 方式二:就是把fixture方法传入usefixtures装饰器中 @pytest.mark.usefixtures("login") def test_add_address():# print("添加收货地址--需要登录")if __name__ == '__main__': pytest.main()""" 执行结果:test_01.py::test_add_cart 打开APP 输入账号,密码,进行登录 添加购物车--需要登录 PASSED关闭APPtest_01.py::test_add_address 打开APP 输入账号,密码,进行登录 添加收货地址--需要登录 PASSED关闭APP """

    推荐阅读