接口测试返回参数的自动化对比!

引言

在现代软件开发过程中,接口测试是验证系统功能正确性和稳定性的核心环节。接口返回参数的对比不仅是确保接口功能实现的手段,也是测试过程中常见且重要的任务。为了提高对比的效率和准确性,我们可以通过自动化手段实现这一过程。本文将介绍接口测试返回参数自动化对比的原理,展示如何使用 Python 和 MySQL 实现对比功能,并提供最佳实践的建议,帮助读者在实际项目中应用这些技术。

自动化对比的原理

接口测试返回参数的自动化对比涉及以下几个步骤:

  1. 提取和存储预期结果:在测试用例设计阶段,定义接口调用的预期返回结果,并将其存储在文件或数据库中。

  2. 执行接口调用:通过自动化测试脚本执行接口调用,获取实际的返回结果。

  3. 结果比对:将实际返回的结果与预期结果进行比对,以确认接口是否满足需求。

自动化对比的工作流程

  1. 准备测试数据:包括请求参数和预期返回结果。

  2. 执行测试用例:发送请求并接收响应。

  3. 对比实际返回的结果和预期结果:通过编写自动化脚本对比返回的参数。

  4. 记录对比结果:将对比结果存储到数据库中,并生成测试报告。

  5. 数据清理:在测试完成后对数据进行清理以维护数据库的健康状态。

数据库设计与实现

为了实现自动化对比,我们选择 MySQL 数据库来存储测试执行信息和对比结果。以下是数据库设计方案及其实现细节。

数据库表设计

1. 测试执行表

存储每次测试执行的信息。

CREATE TABLE test_execution (execution_id VARCHAR(36) PRIMARY KEY,test_case_id INT NOT NULL,execution_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,status VARCHAR(10) NOT NULL
);
2. 接口调用表

存储每次接口调用的信息。

CREATE TABLE api_call (call_id VARCHAR(36) PRIMARY KEY,execution_id VARCHAR(36),api_endpoint VARCHAR(255) NOT NULL,request_params JSON,response_data JSON,compare_result VARCHAR(10),FOREIGN KEY (execution_id) REFERENCES test_execution(execution_id)
);
3. 对比结果表

存储每次对比的详细信息。

CREATE TABLE compare_result (compare_id VARCHAR(36) PRIMARY KEY,call_id VARCHAR(36),field_name VARCHAR(255),expected_value TEXT,actual_value TEXT,match_result VARCHAR(10),FOREIGN KEY (call_id) REFERENCES api_call(call_id)
);

数据库操作示例

以下是插入测试执行记录、接口调用记录和对比结果记录的代码示例:

import mysql.connector
from uuid import uuid4# 数据库上下文管理器
class Database:def __enter__(self):self.connection = mysql.connector.connect(host="localhost",user="root",password="password",database="test_db")self.cursor = self.connection.cursor()return selfdef __exit__(self, exc_type, exc_value, traceback):self.connection.commit()self.cursor.close()self.connection.close()# 插入测试执行记录
def insert_test_execution(test_case_id):execution_id = str(uuid4())with Database() as db:db.cursor.execute("INSERT INTO test_execution (execution_id, test_case_id, status) VALUES (%s, %s, %s)",(execution_id, test_case_id, 'running'))return execution_id# 插入接口调用记录
def insert_api_call(execution_id, api_endpoint, request_params, response_data, compare_result):call_id = str(uuid4())with Database() as db:db.cursor.execute("INSERT INTO api_call (call_id, execution_id, api_endpoint, request_params, response_data, compare_result) VALUES (%s, %s, %s, %s, %s, %s)",(call_id, execution_id, api_endpoint, json.dumps(request_params), json.dumps(response_data), compare_result))return call_id# 插入对比结果记录
def insert_compare_result(call_id, field_name, expected_value, actual_value, match_result):compare_id = str(uuid4())with Database() as db:db.cursor.execute("INSERT INTO compare_result (compare_id, call_id, field_name, expected_value, actual_value, match_result) VALUES (%s, %s, %s, %s, %s, %s)",(compare_id, call_id, field_name, expected_value, actual_value, match_result))

动态参数的过滤

在接口测试中,动态参数(如时间戳、随机数等)可能会导致对比结果的不一致。为了提高对比的准确性,需要在对比过程中对这些动态参数进行过滤。

动态参数过滤的实现

以下是动态参数过滤的示例代码,过滤掉返回结果中的动态字段:

import requests
import json# 动态参数过滤函数
def filter_dynamic_params(response_data: dict, exclude_keys: list) -> dict:"""过滤动态参数,排除不需要对比的字段。"""return {k: v for k, v in response_data.items() if k not in exclude_keys}# 动态参数列表
dynamic_params = ['timestamp', 'token', 'session_id']# 执行接口调用并对比结果
def call_and_compare(execution_id, url, params, expected_response):response = requests.post(url, json=params)actual_response = response.json()filtered_response = filter_dynamic_params(actual_response, dynamic_params)filtered_expected_response = filter_dynamic_params(expected_response, dynamic_params)compare_result = 'match' if filtered_expected_response == filtered_response else 'mismatch'call_id = insert_api_call(execution_id, url, params, filtered_response, compare_result)for key in filtered_expected_response:if key in filtered_response:match_result = 'match' if filtered_expected_response[key] == filtered_response[key] else 'mismatch'insert_compare_result(call_id, key, filtered_expected_response[key], filtered_response[key], match_result)# 测试用例
def test_interface():execution_id = insert_test_execution(1)url = "http://api.example.com/login"params = {"username": "test", "password": "test"}expected_response = {"status": "success", "timestamp": "ignore"}call_and_compare(execution_id, url, params, expected_response)# 更新测试执行状态with Database() as db:db.cursor.execute("UPDATE test_execution SET status = %s WHERE execution_id = %s", ('completed', execution_id))if __name__ == "__main__":test_interface()

集成对比结果的报告内容

在测试执行完成后,我们可以生成一个对比结果报告,以展示测试的执行情况和结果。

生成报告的代码示例
from jinja2 import Template# 生成对比结果报告
def generate_report(execution_id):with Database() as db:db.cursor.execute("""SELECT a.api_endpoint, a.request_params, a.response_data, a.compare_result, c.field_name, c.expected_value, c.actual_value, c.match_resultFROM api_call aJOIN compare_result c ON a.call_id = c.call_idWHERE a.execution_id = %s""", (execution_id,))results = db.cursor.fetchall()# Jinja2 模板template_str = """<!DOCTYPE html><html><head><title>测试对比结果报告</title></head><body><h1>测试对比结果报告</h1><p><strong>测试执行ID:</strong>{{ execution_id }}</p><table border="1"><tr><th>接口地址</th><th>请求参数</th><th>返回数据</th><th>对比结果</th><th>字段名称</th><th>预期值</th><th>实际值</th><th>匹配结果</th></tr>{% for row in results %}<tr><td>{{ row.api_endpoint }}</td><td>{{ row.request_params }}</td><td>{{ row.response_data }}</td><td>{{ row.compare_result }}</td><td>{{ row.field_name }}</td><td>{{ row.expected_value }}</td><td>{{ row.actual_value }}</td><td>{{ row.match_result }}</td></tr>{% endfor %}</table></body></html>"""template = Template(template_str)html_report = template.render(execution_id=execution_id, results=results)# 保存报告到文件with open(f'report_{execution_id}.html', 'w') as f:f.write(html_report)

对比数据的清理

测试完成后,需要对比数据进行清理,以保持数据库的健康状态。以下是手动和自动数据清理的示例代码。

手动清理数据
def manual_cleanup(execution_id):with Database() as db:db.cursor.execute("DELETE FROM compare_result WHERE call_id IN (SELECT call_id FROM api_call WHERE execution_id = %s)", (execution_id,))db.cursor.execute("DELETE FROM api_call WHERE execution_id = %s", (execution_id,))db.cursor.execute("DELETE FROM test_execution WHERE execution_id = %s", (execution_id,))
自动清理数据
import schedule
import time# 自动清理任务
def auto_cleanup():with Database() as db:db.cursor.execute("""DELETE FROM compare_result WHERE compare_id IN (SELECT compare_id FROM compare_resultWHERE compare_id NOT IN (SELECT compare_id FROM api_call WHERE execution_id IN (SELECT execution_id FROM test_execution WHERE status = 'completed')))""")db.cursor.execute("""DELETE FROM api_call WHERE call_id IN (SELECT call_id FROM api_callWHERE call_id NOT IN (SELECT call_id FROM compare_result))""")db.cursor.execute("""DELETE FROM test_execution WHERE status = 'completed' AND execution_id NOT IN (SELECT execution_id FROM api_call)""")# 设置定时任务
schedule.every().day.at("00:00").do(auto_cleanup)while True:schedule.run_pending()time.sleep(1)

结论

在本文中,我们详细探讨了接口测试返回参数的自动化对比方法,包括动态参数的过滤、对比结果的报告生成以及对比数据的清理。通过合理的工具和技术手段,可以显著提高接口测试的效率和效果。希望本文提供的实践经验和代码示例能帮助从事接口测试的技术人员在实际项目中更好地应用自动化对比技术,提高测试的质量和效率。

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

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

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

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

相关文章

WGCLOUD登录页面支持输入验证码吗

支持的 v3.5.3版本开始&#xff0c;WGCLOUD支持在登录页面配置输入验证码&#xff0c;我们可以根据自己的场景需要&#xff0c;配置是否在登录页面显示验证码&#xff0c;如下说明 登录页面添加验证码说明 - WGCLOUD

[超级详细系列]ubuntu22.04配置深度学习环境(显卡驱动+CUDA+cuDNN+Pytorch)--[3]安装cuDNN与Pytorch

本次配置过程的三篇博文分享分别为为&#xff1a; [超级详细系列]ubuntu22.04配置深度学习环境(显卡驱动CUDAcuDNNPytorch)--[1]安装显卡驱动 [超级详细系列]ubuntu22.04配置深度学习环境(显卡驱动CUDAcuDNNPytorch)--[2]安装Anaconda与CUDA [超级详细系列]ubuntu22.04配置深…

Web学习day04

mybatis 目录 mybatis 文章目录 一、查询 1.1结果映射 1.2多条件查询 1.3模糊查询 二、XML 书写规范 三、动态SQL 四、配置文件 4.1settings标签 4.2mappers标签 4.3environments标签 五、案例 5.1数据表 5.2实现类 5.3mapper实现 5.4工具类实现 5.5XML动态…

Python应用 | 基于flask-restful+AntDesignVue实现的一套图书管理系统

本文将分享个人自主开发的一套图书管理系统&#xff0c;后端基于Python语言&#xff0c;采用flask-restful开发后端接口&#xff0c;前端采用VueAntDesignVue实现。对其他类似系统的实现&#xff0c;比如学生管理系统等也有一定的参考作用。有问题欢迎留言讨论~ 关注公众号&am…

记一下blender曲线阵列

先说一下如何正常使用这个 这一次我是用来贴瓷砖 随便创建一个mesh 然后添加一个阵列修改器&#xff0c;然后再给他添加一个curve修改器&#xff0c;使用constant offset去偏移他 这里有个小细节 我第一次创建的curve 我选取之后&#xff0c;死活无法沿着曲线阵列&#xff…

.快速幂.

按位与&#xff08;Bitwise AND&#xff09;是一种二进制运算&#xff0c;它逐位对两个数的二进制表示进行运算。对于每一位&#xff0c;只有两个相应的位都为1时&#xff0c;结果位才为1&#xff1b;否则&#xff0c;结果位为0。如&#xff1a;十进制9 & 5转化为二进制&am…

ActiveMQ-CVE-2023-46604

Apache ActiveMQ OpenWire 协议反序列化命令执行漏洞 OpenWire协议在ActiveMQ中被用于多语言客户端与服务端通信。在Apache ActvieMQ5.18.2版本以及以前&#xff0c;OpenWire协议通信过程中存在一处反序列化漏洞&#xff0c;该漏洞可以允许具有网络访问权限的远程攻击者通过操作…

opencv 中如何通过欧式距离估算实际距离(厘米)

1&#xff1a;这个方法个人测试觉得是正确的&#xff0c;误差较小&#xff0c;目前满足我当前的需求&#xff0c;如果方法不对&#xff0c;请大家评论&#xff0c;完善。 2&#xff1a;确保拍摄的参照物是垂直的&#xff0c;如果不垂直&#xff0c;就会有误差&#xff0c;不垂…

低代码商城构建专家:Mall-Cook

Mall-Cook&#xff1a;用Mall-Cook&#xff0c;让电商创新触手可及- 精选真开源&#xff0c;释放新价值。 概览 Mall-Cook是一个面向未来的商城低代码开发平台&#xff0c;它通过提供直观的可视化界面&#xff0c;让开发者和商家能够快速构建和部署跨平台的电商解决方案。这个…

微信小程序如何实现登陆和注册功能?

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

服务器提交记录有Merge branch消除

背景&#xff1a;在共同开发分支release上&#xff0c;你提交了commit&#xff0c;push到服务器上时&#xff0c;发现有人先比你push了&#xff0c;所以你得先pull&#xff0c; 后再push&#xff0c;然而pull后自动产生了一个Merge branch的一个commit&#xff0c;这个commit本…

递归解决换零钱问题--回顾总结之递归的表达能力

前面为了保持叙述的流畅, 没有做太多的引申, 把总结推迟到了后面. 补上一些总结, 以防止出现 “下面呢? 下面没有了” 的尴尬. 方向性问题 虽然题目在一开始就暗示了这一点, 但首先, 我们还是要问, 它能用递归解决吗? 有点怀疑精神是好的, 既要低头走路, 更要抬头看路, 以防…

JDK14新特征最全详解

JDK 14一共发行了16个JEP(JDK Enhancement Proposals&#xff0c;JDK 增强提案)&#xff0c;筛选出JDK 14新特性。 - 343: 打包工具 (Incubator) - 345: G1的NUMA内存分配优化 - 349: JFR事件流 - 352: 非原子性的字节缓冲区映射 - 358: 友好的空指针异常 - 359: Records…

【JavaScript】解决 JavaScript 语言报错:Uncaught TypeError: XYZ is not iterable

文章目录 一、背景介绍常见场景 二、报错信息解析三、常见原因分析1. 对非数组类型使用 for...of 循环2. 对非可迭代对象使用扩展运算符3. 在 Promise.all 中传递非可迭代对象4. 使用解构赋值时&#xff0c;右侧值非可迭代 四、解决方案与预防措施1. 确保使用可迭代对象2. 使用…

各种Attention|即插即用|适用于YoloV5、V7、V8、V9、V10(一)

摘要 本文总结了各种注意力&#xff0c;即插即用&#xff0c;方便大家将注意力加到自己的论文中。 SE import torch from torch import nn class SEAttention(nn.Module): """ SENet&#xff08;Squeeze-and-Excitation Networks&#xff09;中的注意力…

C++进阶(while循环——函数应用)

知识点代码框架总结 输入n组数据 &#xff0c;对n组数据里面的每一组进行处理&#xff08;输出、求和 、运算、其他&#xff09; int n;//几组数据cin >> n;//2while(n--){//对每组数据进行处理}看到下面的样例&#xff0c;肌肉型反映出上面的框架//2// 1 2 3// 4 5 6若…

虚拟机:VMware功能,安装与使用

目录 一、虚拟机介绍 二、VMware 1.介绍 2.安装 &#xff08;1&#xff09;根据提示按步骤安装​编辑 &#xff08;2&#xff09;更改软件的安装地址​编辑 &#xff08;3&#xff09;根据自己的需求选择是否需要软件更新​编辑 &#xff08;4&#xff09;根据需求选择…

自动驾驶中的人机互相接管问题讨论

一、背景 人机接管&#xff08;human takeover&#xff09;是指在自动驾驶过程中&#xff0c;当系统遇到超出其处理能力或预设安全阈值的情况时&#xff0c;将控制权交还给驾驶员的过程。这一环节的设计直接关系到自动驾驶技术的实用性与安全性&#xff0c;是目前研究和实践中…

【SQL】MySQL事务的隔离级别和幻读、脏读和不可重复读

事务的隔离级别是数据库管理系统提供的一种功能&#xff0c;用于控制事务之间的相互影响程度。常见的隔离级别包括&#xff1a; 读未提交 (Read Uncommitted)&#xff1a;允许一个事务读取另一个事务未提交的数据。 读已提交 (Read Committed)&#xff1a;一个事务只能读取另一…

Python应用爬虫下载QQ音乐歌曲!

目录&#xff1a; 1.简介怎样实现下载QQ音乐的过程&#xff1b; 2.代码 1.下载QQ音乐的过程 首先我们先来到QQ音乐的官网&#xff1a; https://y.qq.com/&#xff0c;在搜索栏上输入一首歌曲的名称&#xff1b; 如我在上输入最美的期待&#xff0c;按回车来到这个画面 我们首…