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

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

参数化测试

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

import unittest
class TestMyAPI(unittest.TestCase):@classmethoddef 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
  • 1

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

from ddt import ddt, data
@ddt
class TestMyAPI(unittest.TestCase):@classmethoddef 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):@classmethoddef 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:@staticmethoddef 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}"@staticmethoddef 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}"@staticmethoddef 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响应中是否存在一组指定的键。

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

 

最后我邀请你进入我们的【软件测试学习交流群:1007119548】, 大家可以一起探讨交流软件测试,共同学习软件测试技术、面试等软件测试方方面面,还会有免费直播课,收获更多测试技巧,我们一起进阶Python自动化测试/测试开发,走向高薪之路

作为一个软件测试的过来人,我想尽自己最大的努力,帮助每一个伙伴都能顺利找到工作。所以我整理了下面这份资源,现在免费分享给大家,有需要的小伙伴可以关注【公众号:程序员雨果】自提!

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

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

相关文章

2024年最新腾讯云轻量4核8G12M服务器CPU内存性价比如何?

4核8G服务器支持多少人同时在线访问?阿腾云的4核8G服务器可以支持20个访客同时访问,关于4核8G服务器承载量并发数qps计算测评,云服务器上运行程序效率不同支持人数在线人数不同,公网带宽也是影响4核8G服务器并发数的一大因素&…

时序分析深入必学的时序模型详细讲解

目录 一、前言 二、时序建模 2.1 反相器 2.2 线性时序模型 2.3 非线性时序模型 三、时序模块 3.1 组合单元 3.2 时序单元 3.3 同步检查:setup和hold 3.4 异步检查:recovery和removal 3.5 脉冲宽度检查Pulse width check 3.6 传输时延 3.7 …

微信小程序配置文件

目录 小程序配置文件 1. 配置文件介绍 2. 全局配置 2.1 pages 2.2 window 2.3 tabBar 3. 页面配置 4. 项目配置文件 5. 支持使用 sass/less 6. sitemap.json 小程序配置文件 1. 配置文件介绍 JSON是一种轻量级的数据格式,常用于前后端数据的交互&#xf…

LDRA Testbed软件静态分析_软件质量度量

系列文章目录 LDRA Testbed软件静态分析_操作指南 LDRA Testbed软件静态分析_自动提取静态分析数据生成文档 LDRA Testbed软件静态分析_Jenkins持续集成_(1)自动进行静态分析的环境搭建 LDRA Testbed软件静态分析_Jenkins持续集成_(2)配置邮件自动发送静态分析结果 LDRA Testb…

typescript映射类型

ts映射类型简介 TypeScript中的映射类型(Mapped Type)是一种高级类型,它允许我们基于现有类型创建新的类型,同时对新类型的每个属性应用一个转换函数。通过使用映射类型,我们可以方便地对对象的属性进行批量操作&…

typescript 索引签名类型

ts索引类型简介 在TypeScript中,索引签名类型(Index Signature Type)是一种特殊的类型,它定义了对象中键的类型以及相应的值的类型。通过使用索引签名类型,我们可以表示一个对象,该对象的键可以是任意类型…

python3 flask 实现对config.yaml文件的内容的增删改查,并重启服务

config.yaml配置文件内容 功能就是userpass下的用户名和密码做增删改查,并重启hy2服务 auth:type: userpassuserpass:csdn: csdnlisten: :443 masquerade:proxy:rewriteHost: trueurl: https://www.bing.com/type: proxy tls:cert: /root/hyst*****马赛克******er…

【算法2-1】前缀和、差分与离散化

一、【P3406】海底高铁(差分贪心)​​​​​​ 由于本题涉及到线路问题,需要统计Uim途径每条线路的次数,而且Uim每次的轨迹都是很长一段路径,所以需要使用一个合理的数据结构来维护区间的变化,首先想到线段…

正交匹配追踪算法(Orthogonal Matching Pursuit)实现过程及Python模拟

正交匹配追踪(Orthogonal Matching Pursuit,OMP)是一种用于寻找稀疏信号的贪婪算法,用于求解压缩感知问题中的稀疏近似问题。在压缩感知的背景下,通常我们有一个欠定的线性系统Ax y,其中A是一个已知的测量…

信奥一本通:2022:【例4.7】最小n值

这个题目的难点在于他让你输入1 2 3&#xff0c;不等的数&#xff0c;意思就是你不知道循环要执行几次&#xff0c;用户输入几次就是几次&#xff0c;那就只有这样写 while (cin >> num) #include <iostream> # include <iomanip> using namespace std;…

第三百五十九回

文章目录 1. 概念介绍2. 使用方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 013pickers2.gif 我们在上一章回中介绍了"如何实现Numberpicker"相关的内容&#xff0c;本章回中将介绍wheelChoose组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念…

学习鸿蒙基础(4)

1.条件渲染 ArkTS提供了渲染控制的能力。条件渲染可根据应用的不同状态&#xff0c;使用if、else和else if渲染对应状态下的UI内容。 当if、else if后跟随的状态判断中使用的状态变量值变化时&#xff0c;条件渲染语句会进行更新。。 Entry Component struct PageIfElse {Stat…

【C++杂货铺】模板

&#x1f308;前言&#x1f308; 欢迎观看本期【C杂货铺】&#xff0c;本期内容将讲解模板的初阶&#xff0c;即了解模板&#xff0c;熟练掌握模板的使用方法&#xff0c;了解模板的工作原理等内容。 &#x1f4c1; 函数模板 &#x1f4c2; 概念 函数模板代表了一个函数家族&am…

如何在Windows系统中检测和结束运行中的程序(任务管理器显示运行程序可能有bug)

如何在Windows系统中检测和结束运行中的程序 在Windows系统的日常使用和管理过程中&#xff0c;我们经常需要检测某个程序是否正在运行&#xff0c;并在必要时结束它。本文将详细介绍如何在Windows系统中检测运行中的程序&#xff0c;并提供多种方法来结束这些程序。 检测运行…

通俗易懂的双亲委派机制

当你超过别人一点点&#xff0c;别人会嫉妒你&#xff1b;当你超过别人一大截&#xff0c;别人就会羡慕你 据说给我点关注的都成了大佬&#xff0c;点关注的我都会私发一份好东西 ​​​​你得先知道 在介绍双亲委派机制的时候&#xff0c;不得不提ClassLoader&#xff08;类…

Java字符串转整数的超简单方法!

推荐阅读 智能化校园&#xff1a;深入探讨云端管理系统设计与实现&#xff08;一&#xff09; 智能化校园&#xff1a;深入探讨云端管理系统设计与实现&#xff08;二&#xff09; 问题描述 当你把一个字符串值和一个整数加在一起而不进行任何形式的转换时会发生什么呢&#…

聚合支付,聚合系统,聚合程序或将成为主流

支付市场的变化对用户、代理商和运营商产生了重大影响。 随着政策监管的日益严格&#xff0c;支付行业逐渐朝着标准化和合理化的方向发展&#xff0c;日益增强其安全性。在这个背景下&#xff0c;聚合平台已经成为未来支付行业发展的重要趋势。特别是在“一机一码”政策实施后&…

前端进度条组件NProgress

nprogress 安装 npm install --save nprogress使用 import NProgress from nprogress // 引入nprogress插件 import nprogress/nprogress.css // 这个nprogress样式必须引入// axios请求拦截器 axios.interceptors.request.use(config > {NProgress.start() // 设置加载进…

【学习心得】编程小白该如何学好C语言(✨新手推荐阅读)

前言 对于刚刚踏入编程领域的小白来说&#xff0c;C语言可能是一个既神秘又充满挑战的领域。但只要你掌握了正确的学习方法&#xff0c;C语言的学习之旅也可以是充满乐趣和成就感的。 一、明确学习目标 对于初学者来说&#xff0c;明确学习目标是学好C语言的第一步。一个清晰…

BIG DATA —— 大数据时代

大数据时代 [英] 维克托 迈尔 — 舍恩伯格 肯尼斯 库克耶 ◎ 著 盛杨燕 周涛◎译 《大数据时代》是国外大数据研究的先河之作&#xff0c;本书作者维克托迈尔舍恩伯格被誉为“大数据商业应用第一人”&#xff0c;他在书中前瞻性地指出&#xff0c;大数据带来的信息…