Python接口测试实践—参数化测试、数据驱动测试和断言的使用

news2024/9/24 20:34:31

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快

在Python接口测试实践中,参数化测试、数据驱动测试和断言是常用的技术手段。

参数化测试

参数化测试是指将测试用例中的某些部分(如输入数据或配置)作为参数传递给测试函数,以便于复用和减少代码重复。 例如,使用unittest库进行参数化测试:

import unittest
class TestMyAPI(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.base_url = "http://example.com/api"
    def test_get_user(self, user_id):
        url = f"{self.base_url}/users/{user_id}"
        response = requests.get(url)
        self.assertEqual(response.status_code, 200)  # 断言状态码为200
if __name__ == "__main__":
    suite = unittest.TestSuite()
    for user_id in [1, 2, 3]:
        suite.addTest(TestMyAPI("test_get_user", user_id=user_id))
    runner = unittest.TextTestRunner()
    runner.run(suite)

在这个例子中,我们为test_get_user方法添加了参数user_id,并在主程序中通过循环为不同的用户ID创建并运行测试用例。

在参数使用的过程中,要注意到python深拷贝浅拷贝在接口自动化里的使用

在Python的接口自动化测试中,深拷贝和浅拷贝的概念主要应用于数据处理和对象复制的场景。以下是在接口自动化中可能使用深拷贝和浅拷贝的一些情况:

  • 配置和参数管理:

在进行接口测试时,我们经常需要处理各种配置信息和输入参数。

如果这些数据结构包含嵌套的对象(如字典、列表或其他自定义类实例),那么在修改或扩展这些数据时,可能会涉及到对象的复制操作。

  • 测试数据准备:

在进行数据驱动测试时,我们需要为不同的测试用例准备不同的输入数据。

使用深拷贝或浅拷贝可以创建原始数据结构的副本,以避免对原始数据的修改影响到其他测试用例。

  • 响应结果验证:

在接收和处理接口返回的结果时,我们通常会对结果进行断言验证。

如果需要保存原始响应结果以便后续分析或调试,使用深拷贝可以确保在后续操作中不会意外修改原始响应数据。

  • 复用和共享对象:

在编写可复用的测试函数或类时,可能会涉及到对象的共享和复制。

使用深拷贝或浅拷贝可以根据需求创建独立的对象副本,以避免不同测试之间的数据冲突。

深拷贝和浅拷贝的主要区别在于复制对象时是否复制了引用的对象:

  • 浅拷贝(shallow copy):只复制了对象的第一层引用,对于嵌套的对象,只会创建新的引用,而不复制其内容。这意味着如果修改了浅拷贝后的嵌套对象,会影响到原始对象。
  • 深拷贝(deep copy):不仅复制了对象本身,还递归地复制了所有嵌套的对象。因此,修改深拷贝后的对象不会影响到原始对象。

在接口自动化测试中,具体使用深拷贝还是浅拷贝取决于具体的测试场景和需求。例如,如果你希望完全隔离测试数据或响应结果,避免相互影响,那么应该使用深拷贝。而如果数据结构比较简单,或者不需要保持原始数据的完整性,那么浅拷贝可能就足够了。

在Python中,可以使用copy模块提供的copy()函数进行浅拷贝,使用deepcopy()函数进行深拷贝。以下是一个简单的例子:

import copy
# 假设我们有一个包含嵌套字典的响应结果
response_data = {
    "user": {
        "id": 1,
        "name": "Alice"
    },
    "items": [{"id": 1, "name": "Item 1"}]
}
# 使用浅拷贝
copied_data1 = copy.copy(response_data)
# 使用深拷贝
copied_data2 = copy.deepcopy(response_data)
# 修改复制后的数据
copied_data1["user"]["name"] = "Bob"
copied_data2["user"]["name"] = "Charlie"
# 浅拷贝会改变原始数据
print(response_data)  # 输出:{'user': {'id': 1, 'name': 'Bob'}, 'items': [{'id': 1, 'name': 'Item 1'}]}
# 深拷贝不会改变原始数据
print(response_data)  # 输出:{'user': {'id': 1, 'name': 'Alice'}, 'items': [{'id': 1, 'name': 'Item 1'}]}

数据驱动测试

数据驱动测试是一种测试方法,其中测试数据是从外部数据源(如文件、数据库或列表)获取的,而不是硬编码在测试代码中。 使用unittest库结合ddt库进行数据驱动测试: 首先安装ddt库:

pip install ddt

然后在测试代码中使用@data装饰器:


from ddt import ddt, data
@ddt
class TestMyAPI(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.base_url = "http://example.com/api"
    @data((1, 200), (2, 200), (999, 404))  # 测试数据元组,每个元组包含(user_id, expected_status_code)
    def test_get_user(self, user_id, expected_status_code):
        url = f"{self.base_url}/users/{user_id}"
        response = requests.get(url)
        self.assertEqual(response.status_code, expected_status_code)
if __name__ == "__main__":
    unittest.main()

在这个例子中,我们使用@data装饰器定义了一个包含多个测试数据元组的列表,每个元组代表一次测试用例。

在Python的接口自动化测试中,@data装饰器通常与ddt(Data-Driven Tests)库一起使用,以实现数据驱动的测试。以下是在接口自动化中@data装饰器的一些其他使用方式:

  • 多场景测试:

@data装饰器可以用来定义多个测试数据集,每个数据集代表一个特定的测试场景。

这使得测试代码更具可读性和可维护性,因为每个测试场景都在单独的数据集中清晰地定义。

  • 边界值分析:

在接口测试中,经常需要对输入参数进行边界值分析,以确保系统在极端情况下也能正确工作。

使用@data装饰器,可以方便地定义一组包含边界值和特殊值的数据集,对这些情况进行测试。

  • 异常和错误处理测试:

通过使用@data装饰器提供不同的输入数据,可以测试接口在接收到无效或错误数据时的处理能力。

这包括测试错误消息的返回、状态码的正确性以及系统的稳健性。

  • 性能和负载测试数据准备:

在进行性能和负载测试时,可能需要生成大量不同的请求参数和数据组合。

使用@data装饰器可以轻松地创建这些测试数据集,并在测试脚本中复用。

  • 配置和环境切换:

如果你的接口自动化测试需要在不同的环境(如开发、测试、生产)或者不同的配置下运行,可以使用@data装饰器来定义不同的环境或配置参数。

这样可以在同一个测试函数中处理多种情况,而不需要为每个环境或配置编写单独的测试。

以下是一个使用@data装饰器进行多场景测试的例子:

from ddt import ddt, data
@ddt
class TestMyAPI(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.base_url = "http://example.com/api"
    @data(
        ({"username": "Alice", "password": "password123"}, 200),
        ({"username": "Bob", "password": "invalid_password"}, 401),
        ({"username": "", "password": ""}, 400),
        ({"username": None, "password": None}, 400),
    )
    def test_login(self, login_data, expected_status_code):
        url = f"{self.base_url}/login"
        response = requests.post(url, json=login_data)
        self.assertEqual(response.status_code, expected_status_code)

在这个例子中,我们使用@data装饰器定义了四个测试数据集,每个数据集包含一个登录请求的数据字典和一个预期的HTTP状态码。测试函数test_login会针对每个数据集执行一次,从而覆盖多种登录场景,包括正常登录、无效密码、空输入和无效类型的数据。

断言的使用

断言是在测试代码中用来验证实际结果是否符合预期的一种机制。如果断言失败,测试也将失败,并提供有关失败原因的信息。 Python的unittest库提供了多种断言方法,如:

assertEqual(a, b): 验证a和b是否相等。
assertTrue(x): 验证x是否为真。
assertFalse(x): 验证x是否为假。
assertIn(item, container): 验证item是否在container中。
assertIsInstance(obj, classinfo): 验证obj是否为classinfo类的实例。

在上面的测试示例中,我们使用了assertEqual来验证HTTP响应的状态码是否为预期值。

通过结合使用参数化测试、数据驱动测试和断言,你可以更有效地编写和维护Python接口测试代码,提高测试覆盖率和代码复用性。

在Python中,我们可以封装断言以提高测试代码的可读性和可维护性。以下是一个简单的断言封装示例:

class CustomAssertions:
    @staticmethod
    def assert_status_code(response, expected_status_code):
        assert response.status_code == expected_status_code, f"Expected status code {expected_status_code}, got {response.status_code}"
    @staticmethod
    def assert_json_contains(response, key, value):
        json_data = response.json()
        assert key in json_data, f"Key '{key}' not found in JSON response"
        assert json_data[key] == value, f"Value of key '{key}' is {json_data[key]}, expected {value}"
    @staticmethod
    def assert_json_keys_exist(response, keys):
        json_data = response.json()
        for key in keys:
            assert key in json_data, f"Key '{key}' not found in JSON response"
    # 添加更多自定义断言方法...

# 使用示例

from unittest import TestCase
import requests
class MyTestCase(TestCase):
    def test_my_api(self):
        response = requests.get("http://example.com/api")
        CustomAssertions.assert_status_code(response, 200)
        CustomAssertions.assert_json_contains(response, "name", "John Doe")
        CustomAssertions.assert_json_keys_exist(response, ["name", "email", "age"])

在这个例子中,我们创建了一个名为CustomAssertions的类,其中包含了一些静态方法,每个方法都是一个封装好的断言。这些断言方法包括:

  • assert_status_code: 断言HTTP响应的状态码是否为预期值。
  • assert_json_contains: 断言JSON响应中是否存在指定的键,并且该键的值等于预期值。
  • assert_json_keys_exist: 断言JSON响应中是否存在一组指定的键。

在测试用例中,我们可以直接调用这些封装好的断言方法,使得测试代码更加清晰和简洁。当然,你还可以根据实际需求添加更多的自定义断言方法。这样的封装方式也有助于在多个测试用例中复用相同的断言逻辑,提高代码的复用性。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2161354.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯算法之暴力

暴力 1.十进制数转换成罗马数字 2.判断给出的罗马数字是否正确 小知识 %(模除): % 符号用作模除(或取模)运算符。模除运算是一种数学运算,它返回两个数相除的余数。 具体来说,如果 a 和 b 是…

初识 C++ ( 1 )

引言:大家都说c是c的升级语言。我不懂这句话的含义后来看过解释才懂。 一、面向过程语言和面向对象语言 我们都知道C语言是面向过程语言,而C是面向对象语言,说C和C的区别,也就是在比较面向过程和面向对象的区别。 1.面向过程和面向…

自然语言处理实战项目:从理论到实现

一、引言 自然语言处理(NLP)是计算机科学、人工智能和语言学交叉的领域,旨在让计算机能够理解、处理和生成人类语言。随着互联网的飞速发展,大量的文本数据被产生,这为自然语言处理技术的发展提供了丰富的素材&#xf…

【动态规划】(五)动态规划——子序列问题

动态规划——子序列问题 子序列问题☆ 最长递增子序列(离散)最长连续递增序列(连续)最大子序和(连续)最长重复子数组(连续)☆ 最长公共子序列(离散-编辑距离过渡&#xf…

【驱动】修改USB转串口设备的属性,如:Serial

1、查看串口信息 在Windows上,设备管理窗口中查看设备号 2、修改串口号工具 例如使用:CH34xSerCfg.exe 使用步骤:恢复默认值 - -> 修改 Serial String(或者Product String等属性)–> 写入配置 3、查看设备节点 在linux上使用lsub查看新增的设备信息,如下这个…

python多线程开发的具体示例

用一个具体的示例,展示如何使用 ThreadPoolExecutor 和 asyncio 来并行运行多个任务,并输出结果。 代码: import asyncio import time from concurrent.futures import ThreadPoolExecutorclass WorkJob:def __init__(self, job_id):self.j…

报表做着太费劲?为你介绍四款好用的免费报表工具

1. 山海鲸可视化 介绍: 山海鲸可视化是一款免费的国产可视化报表软件,与许多其他宣传免费的软件不同,山海鲸的报表功能完全免费并且没有任何限制,就连网站管理后台这个功能也是免费的。同时山海鲸可视化还提供了种类丰富的可视化…

11.安卓逆向-安卓开发基础-api服务接口设计2

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于:图灵Python学院 本人写的内容纯属胡编乱造,全都是合成造假,仅仅只是为了娱乐,请不要盲目相信。 工…

云手机推荐:五款热门云手机测评!

在云手机市场中,各个品牌层出不穷,让人难以选择。为了帮助你更好地找到适合的云手机应用,我们整理了五款最受欢迎的云手机进行测评。2024年,哪款云手机是你的不二之选?且慢下结论,看看这五款云手机的真实表…

【深度学习】深度卷积神经网络(AlexNet)

在 LeNet 提出后,卷积神经网络在计算机视觉和机器学习领域中很有名气,但并未起到主导作用。 这是因为 LeNet 在更大、更真实的数据集上训练的性能和可行性还有待研究。 事实上,在 20 世纪 90 年代到 2012 年之间的大部分时间里,…

Windows系统的Tomcat日志路径配置

文章目录 引言I Windows系统的Tomcat日志路径配置配置常规日志路径访问日志路径配置,修改server.xmlII 日志文件切割:以分隔割tomcat 的 catalina.out 文件为例子通过Linux系统自带的切割工具logrotate来进行切割引言 需求:C盘空间不足,处理日志文件,tomcat日志迁移到D盘…

中国科学院云南天文台博士招生目录

中国科学院云南天文台是专业基础研究与应用研究结合的综合性天文研究机构(其前身是1938年中央研究院天文研究所在昆明东郊凤凰山创建的凤凰山天文台),总部在云南省昆明市,设有两个观测站(丽江高美古天文观测站和澄江抚…

Boruta 的库的初识

我在一个kaggle比赛时间预测中发现Boruta我并不熟悉与是我学习了一下 Boruta 的工作原理: 影子特征(Shadow Features): Boruta 首先创建一组影子特征,这些影子特征是通过随机打乱原始特征的值生成的。影子特征的目的是作为对照组…

【完结】【PCL实现点云分割】ROS深度相机实践指南(下):pcl::BoundaryEstimation实现3D点云轮廓检测的原理(论文解读)和代码实现

前言 本教程使用PCL对ROS深度相机捕获到的画面进行操场上锥桶的分割 上:[csdn 博客] 【PCL实现点云分割】ROS深度相机实践指南(上):PCL库初识和ROS-PCL数据类型转换中:[csdn 博客] 【PCL实现点云分割】ROS深度相机实践指南(中):Pl…

电梯节能 引领趋势

电梯,之前对我们来说,就是让我们省时省力的工具,谁知电梯也可加装【节能设备】。 电梯节能评估,节电率达20%-50%。 电梯节能(电梯回馈装置)通常电梯在轻载上行,重载下行和平层停梯状态下&#…

监控和维护 Linux 系统的健康状态:从服务启动故障到操作系统查询

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119qq.com] &#x1f4f1…

rar文件怎么打开?这几款软件压缩和查看很方便!

在这个数字化信息爆炸的时代,我们每天都会接触到各种各样的文件,其中RAR格式文件以其高压缩率和良好的文件保护特性,成为了许多人分享和存储大文件的首选。然而,面对这样一个看似“神秘”的文件格式,不少朋友可能会感到…

Stable Diffusion绘画 | 来训练属于自己的模型:配置完成,炼丹启动

前言 效率设置-优化器 优化器可以分为4类: 第一类 AdamW :梯度下降算法,结合自适应学习率,既可以快速收敛,又可以避免 Loss值 震荡 AdamW8bit:能降低显存占用,并略微加快训练速度&#xff0…

Mysql—主从复制的slave添加及延迟回放

MySQL 主从复制是什么? ​ MySQL 主从复制是指数据可以从一个 MySQL 数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,…

国产分布式数据库-tidb单机部署文档

tidb单机部署文档 1、创建用户 #创建用户 useradd tidb #设置密码 passwd tidb2、配置免密码登录 编辑/etc/sudoers文件,文末加入: tidb ALL(ALL) NOPASSWD:ALL如果想要控制某个用户(或某个组用户)只能执行root权限中的一部分命令, 或者允许某些用户使用sudo时…