热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

fixture和fixture参数化精简自动化测试代码

一、前言 Pytest测试框架中的fixture,可以将自动化测试用例中的前置、后置部分分离出来放入其中,然后在写测试用例的时候只需要写测试逻辑相关的代码,提高代码的复用性,同时也

一、前言

  Pytest测试框架中的fixture,可以将自动化测试用例中的前置、后置部分分离出来放入其中,然后在写测试用例的时候只需要写测试逻辑相关的代码,提高代码的复用性,同时也有利于代码的维护。

  本文重点介绍的是fixture参数化,关于fixture的基础知识可以查看这个链接:https://www.cnblogs.com/zdx20/p/14948134.html


二、测试场景介绍

  我们以下面App自动化测试,订酒店的测试场景为例,来说明:

  上图中有三个测试场景:

   1、编辑姓名;

   2、编辑手机号;

   3、编辑身份证。

  这三个场景主要的测试逻辑都在酒店的编辑订单页,通过fixture参数化功能可以很好的精简测试代码。

 三、fixture和fixture参数化

     1、按照上面的流程编写自动化测试用例:

import pytest
login_data = [{"user_name": "xiaowang", "pwd": 123456, "date": 1, "name": "小王"}]
@pytest.mark.parametrize("test_data", login_data)
def test_hotel(test_data):
# 登录App
print("\n" + "1、登录App, 账号和密码是:", test_data["user_name"], test_data["pwd"])
# 酒店首页选择入住日期
print("2、酒店首页选择日期:{}号".format(test_data["date"]))
# 酒店列表选择酒店
print("3、选择想要预订的酒店和房型")
# 编辑酒店页面,输入入住人姓名
print("4、输入入住人姓名:", test_data["name"])
# 断言下单结果
print("5、恭喜,酒店预订成功了!!!")

  上面的用例就是没有使用前置/后置分离代码,虽然可以完成UI自动化测试的一个测试场景任务,但是后续用例多了维护会非常头疼,而且不具有扩展性。

  2、fixture的前置、后置

  在每条用例中都需要登录App,然后执行测试过程,最后断言测试结果。我们可以将登录,和测试结果断言剥离出来放在fixture当中,这样同类型的测试场景就可以直接调用。

import pytest
hotel_data = [{"date": 1, "name": "小王"}]
@pytest.fixture()
def fix_login():
# 登录App
print("\n" + "1、前置条件--登录App, 账号和密码是:", "xiaowang", 123456)
yield
# 断言下单结果
print("5、后置条件--恭喜,酒店预订成功了!!!")
@pytest.mark.parametrize("test_data", hotel_data) # 测试数据的参数化
def test_hotel(test_data, fix_login):
# 酒店首页选择入住日期
print("2、酒店首页选择日期:{}号".format(test_data["date"]))
# 酒店列表选择酒店
print("3、选择想要预订的酒店和房型")
# 编辑酒店页面,输入入住人姓名
print("4、输入入住人姓名:", test_data["name"])

 执行结果如下:

 1、前置条件--登录App, 账号和密码是: xiaowang 123456
 2、酒店首页选择日期:1号
 3、选择想要预订的酒店和房型
 4、输入入住人姓名: 小王
 5、后置条件--恭喜,酒店预订成功了!!!

  上面的测试用例方法中,测试数据是通过@pytest.mark.parametrize()传入的,有几组测试数据就会生成几条测试用例,详细的使用方法可以查看“前言”部分提到的链接。

  3、fixture参数化

  通过fixture我们将用例的前置和后置条件摘出来了,但是前置条件登录的数据是固定的,通用性不强,需要将fixture的测试数据也参数化。

  fixture参数化传参的方法与用例的传参是一样的,也是使用@pytest.mark.parametrize()传入,但是需要加一个参数:indirect=True,指定将参数传入fixture测试夹具中。fixture测试夹具的方法中使用request接受传入的参数,然后通过request.param使用具体的数据。

import pytest
login_data = [{"user_name": "xiaowang", "pwd": 1234}, {"user_name": "zhaosi", "pwd": 6789}]
test_data = [{"date": 1, "name": "小王"}]
@pytest.fixture()
def fix_login(request):
# 接收传入的数据
test_info = request.param
# 登录App
print("\n" + "1、前置条件--登录App, 账号和密码是:", test_info["user_name"], test_info["pwd"])
yield
# 断言下单结果
print("5、后置条件--恭喜,酒店预订成功了!!!")
@pytest.mark.parametrize("fix_login", login_data, indirect=True) # fixture测试夹具的参数化
@pytest.mark.parametrize("test_info", test_data) # 测试用例的参数化
def test_hotel(test_info, fix_login):
# 酒店首页选择入住日期
print("2、酒店首页选择日期:{}号".format(test_info["date"]))
# 酒店列表选择酒店
print("3、选择想要预订的酒店和房型")
# 编辑酒店页面,输入入住人姓名
print("4、输入入住人姓名:", test_info["name"])

  上面登录的前置条件中,传入了两组账号、密码数据,那么在执行用例时,同一个用例场景会分别使用两个账号测试一遍。

  同时等到两个执行结果:

     fixture参数化,需要注意接收参数的标识符,用例中调用测试夹具的标识符,以及测试夹具的方法名要一致。

   现在测试场景只写了一个:编辑姓名,后面的编辑手机号、编辑身份证号两个场景,直接套用现有的测试用例即可。

  4、拆分多个fixture

  前面提到我们需要测试的三个酒店场景,前面几个步骤“酒店首页”、“酒店列表页”都是一样的,而且后续还有其他用例也需要用到“酒店首页”或者“酒店列表页”,因此我们需要不同页面的前置条件来满足不同测试场景,这就有了很多个测试夹具,不利于代码的维护。我们可以按照一个页面一个前置夹具的方法来细分测试场景,写用例时按照顺序去调用即可。

import pytest
login_data = [{"user_name": "xiaowang", "pwd": 1234}]
test_data = [{"date": 11, "name": "小王", "result_data": "通过"}]
@pytest.fixture()
def fix_login(request):
# 接收传入的数据
test_info = request.param
# 登录App
print("\n" + "1、前置条件--登录App, 账号和密码是:", test_info["user_name"], test_info["pwd"])
@pytest.fixture()
def home_page(request):
# 接收传入的数据
test_info = request.param
# 酒店首页选择入住日期
print("2、酒店首页选择日期:{}号".format(test_info["date"]))
@pytest.fixture()
def list_page():
# 酒店列表选择酒店
print("3、选择想要预订的酒店和房型")
@pytest.fixture()
def result(request):
yield
# 接收传入的数据
test_info = request.param
# 断言下单结果
print("5、后置条件--恭喜,酒店预订成功了,结果:{}!!!".format(test_info["result_data"]))
@pytest.mark.parametrize("result", test_data, indirect=True)
@pytest.mark.parametrize("home_page", test_data, indirect=True)
@pytest.mark.parametrize("fix_login", login_data, indirect=True)
@pytest.mark.parametrize("test_info", test_data)
def test_name(test_info, fix_login, home_page, list_page, result):
# 编辑酒店页面,输入入住人姓名
print("4、输入入住人姓名:", test_info["name"])

  执行结果如下:

  1、前置条件--登录App, 账号和密码是: xiaowang 1234
  2、酒店首页选择日期:11号
  3、选择想要预订的酒店和房型
  4、输入入住人姓名: 小王
  5、后置条件--恭喜,酒店预订成功了,结果:通过!!!

  ###注意:在测试用例方法中同时调用多个fixture夹具时,一定要按照测试逻辑顺序来,执行用例时会按照测试夹具调用先后顺序执行。

  4.1、fixture测试夹具添加顺序

  测试用例方法中调用测试夹具时需要注意先后顺序,不然测试逻辑会混乱。如果你不想在调用时出现这个问题,可以在编写多个测试夹具时,测试夹具之间按照逻辑先后顺序调用,这样在写用例时就不用考虑先后顺序问题,而且不需要传参的测试夹具不用调用也能执行。

 测试用例方法调用:


、fixture和fixture参数化

  1、fixture的params参数

  fixture测试夹具的参数化除了上面用到的@pytest.mark.parametrize(),还有一种是直接在测试夹具的fixture中传参,使用params=即可。

 

import pytest
login_data = [{"user_name": "xiaowang", "pwd": 1234}, {"user_name": "zhaosi", "pwd": 6789}]
test_data = [{"date": 1, "name": "小王"}]
@pytest.fixture(params=login_data) # fixture测试夹具的参数化
def fix_login(request):
# 接收传入的数据
test_info = request.param
# 登录App
print("\n" + "1、前置条件--登录App, 账号和密码是:", test_info["user_name"], test_info["pwd"])
yield
# 断言下单结果
print("5、后置条件--恭喜,酒店预订成功了!!!")
@pytest.mark.parametrize("test_info", test_data) # 测试用例的参数化
def test_hotel(test_info, fix_login):
# 酒店首页选择入住日期
print("2、酒店首页选择日期:{}号".format(test_info["date"]))
# 酒店列表选择酒店
print("3、选择想要预订的酒店和房型")
# 编辑酒店页面,输入入住人姓名
print("4、输入入住人姓名:", test_info["name"])

 

  fixture的参数化就介绍到这里。



推荐阅读
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了如何使用python从列表中删除所有的零,并将结果以列表形式输出,同时提供了示例格式。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • 这篇文章主要介绍了Python拼接字符串的七种方式,包括使用%、format()、join()、f-string等方法。每种方法都有其特点和限制,通过本文的介绍可以帮助读者更好地理解和运用字符串拼接的技巧。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • RouterOS 5.16软路由安装图解教程
    本文介绍了如何安装RouterOS 5.16软路由系统,包括系统要求、安装步骤和登录方式。同时提供了详细的图解教程,方便读者进行操作。 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
author-avatar
比刀郎还冲动啊
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有