接口测试进阶之数据模板
大家好久不见了。今天的文章将介绍jinja2模板在接口测试数据上的应用。
这几个月我在想,进阶系列要怎么写。
毕竟很多情况下,我觉得写技术文章和做培训一样,都会有两个结果:
1.是需要这些知识的人看不懂。
2.是看得懂的人不需要这些知识。
而我的进阶系列是希望写给即将跨入测试开发这条路的人和刚进入这条路还没有形成成自己的知识体系的人。当初我刚开始转型的时候就很希望有这种资料来引导一下我。。。如果说之前的基础系列是给想转型测试开发的人打打基础,那进阶系列就是真正走出这一步时最需要的东西。按照我的观点,真正走上测试开发之路的标志应该是你能够:
1.独立学习一个新工具或库。
2.独立完成一个测试框架或工具。
3.独立集成一个持续集成测试系统。
如果连一个框架也写不出来,就别说测试开发了,写框架之类的是很简单的,难的是写得好。
总之,文章限于篇幅,只能说是写给有足够自学能力的人看的。之后可能会做一些live或视频之类来提供给更希望在有人引导下学习的人。
不管怎么样,进阶我想从接口测试开始写起。接口测试的需求还是挺大的。而且你能看到各大测试论坛或讨论区里无数的人在写自己的接口测试框架。但是,那些开源出来的框架大都有很大的问题,比如最严重的问题就是:过于复杂。你去下载一个的话,你会发现你压根搞不懂他们写这么多代码是要做什么。而且你会发现很多人喜欢把别人写过的东西用自己的方式再写一遍。当然他在写的时候提高了一定的开发能力,但对于读者来说,那就是灾难。
我写代码喜欢简单,我对于测试开发的第一要求就是简单。
今天讨论的问题,我用了15行代码来实现一个解决方案。
这个问题就是,怎样保存接口测试的测试数据。
很多测试框架选择把数据放在:Excel里,CSV里,YAML里,源代码里。
但这些都不是我想要的,Excel太笨重,CSV很土,YAML里太难调,源代码里太难读。
归根结底,要么不灵活,要么很难读。
接口测试的数据问题
这个问题也算是由来已久了。
现在很多各种各样的方法来解决:
写Excel里,CSV里,YAML里,源代码里,XML里,还有放在数据库里,放在各种各样的文件里。我想说的是,你在真正做一个工具时,这些都可以。关键是能应付你的项目需求。
这里我给出的是一个示例,也就是我怎样写一个测试框架的数据管理部分。当然,这个示例还是比较精致的。至少我再也不会选择把数据放到上面提过的那些东西里去。。。
那么我把数据放在哪里?json文件里。
先来看需求,假如有这么一个接口,
你要在HTTP请求的BODY要发送{"username":"user1","password":"password1"}这样一个json对象来表示你登录时使用的用户名密码。
那么直接把数据写在代码里的话,差不多就是这样:
import pytest
import requests
import jsondef test_login():url = "http://localhost:8000/login"data = json.loads({"username":"user1","password":"passowrd1"})r = requests.post(url=url, data=data)assert r.status_code == 200if __name__ == "__main__":pytest.main()
接下来的问题是很常见的数据驱动问题,如果你要测5个用户的登录。
他们的用户名密码依次是user1/password1,user2/password2,...user5/password5.
那么直接把数据写在代码里的话,大概就是这样:
注意这里我把http response code也写在测试数据里了,虽然他是预期结果。但预期结果也是数据的一部分。这个test方法里其实可以测一些返回值不是200的数据。
import pytest
import requests
import jsontestdata = [("user1", "password1", 200),("user2", "password2", 200),("user3", "password3", 200),("user4", "password4", 200),("user5", "password5", 200)
]@pytest.mark.parametrize("user,password,expected_response_code", testdata)
def test_login(user,password,expected_response_code):url = "http://localhost:8000/login"data = json.loads({"username":"{}".format(user),"password":"{}".format(password)})r = requests.post(url=url, data=data)assert r.status_code == expected_response_codeif __name__ == "__main__":pytest.main()
到这里为止,data = xxxx 这一行已经有点复杂了。
然后,一个真实请求的json里可能包含不止这么两个参数。
可以想象如果全写在代码里,你的测试用例文件会变得多么难读。。。
举个例子,github api里create repo可以包含14个参数,他给出的例子里用了7个参数,
长这样:
{"name": "Hello-World","description": "This is your first repository","homepage": "https://github.com","private": false,"has_issues": true,"has_projects": true,"has_wiki": true
}
如果这14个参数里有些不变,有些你要测也就是会变,你可以试一下直接写在代码里会形成怎样的一个测试用例文件。。接口的描述文档在这里Repositories | GitHub Developer Guide
可能到这里,大家都会想把数据驱动更进一步,把数据或者至少是一部分数据放到代码外吧。这就是那些excel,xml,yaml,各种数据源出现的原因了。这些都能用,也都能解决一定的问题。但是,就是不灵活。
然后这是一个网友遇到的实际问题:他测的接口要求当参数A的值为true时,才向服务器发送参数B,C和D,其他情况向服务器发送参数E和F。
我可以说上述各种数据源都做不到这种功能。你要么写两份数据,要么只能在代码里做分支。但这些,都在增加测试的复杂度,而我不想要复杂。
ok,现在我要解决这个问题。
测试数据中引入模板概念
模板其实对于python的web开发者来说是很熟悉的东西。Django,flask,各种web开发框架里,前端部分都在用模板解决问题。
通俗的说,模板就是在html里插入了一些特殊符号,让HTML里可以拿到服务器后台传上来的变量,更进一步可以根据这些变量的值来显示不同内容。
比如后台发现你是免费用户,就给你显示一堆广告,发现你是付费用户,这些广告就不显示了。
那么,我就想,对于测试数据,可不可以也这么搞?
显然是可以的
数据我划分成可变数据和不变数据两个部分。

比如一个HTTP请求要发送{"username":"xxxx","password":"xxxx"}
这个数据里除了xxxx以外,全是不变部分。至少不会经常不停的变。那么不变部分直接写死在json文件里。
而可变部分在json文件里用模板语法代替,这个json文件看上会是这样的:
{"username":{{user.username}},"password":{{user.password}}}
这里{{user.username}}和{{user.password}}就是可变部分。不直接写死他们的值。而是,用模板的变量代替。
这个变量就是{{user}},这个变量有两个属性,一个username一个password,之后我们再在测试用例里把这个变量传递给模板,就可以渲染出真正的测试数据。也就是说,这个可变部分,真正写,我写在测试用例的代码里面。
源代码说好了一共只有15行:
读取和渲染模板的类
from jinja2 import Environment, FileSystemLoader
import jsonclass JsonTemplateReader():def __init__(self):self.env = Environment(loader=FileSystemLoader('.'))def get_data(self, test_name, **kwargs):template = self.env.get_template(test_name + ".json")return json.loads(template.render(**kwargs))
给pytest用的fixture
import pytest
from core.data_reader import JsonTemplateReader@pytest.fixture(scope="function")
def json_template(request):def _to_read_the_template_by_test_name(**kwargs):return JsonTemplateReader().get_data(request.function.__name__, **kwargs)return _to_read_the_template_by_test_name
在这里我的设计思想是这样的,针对单个接口的测试(我把接口测试分为针对单个接口的测试和针对用户场景的端到端测试):
一个测试方法,对应一个json文件。
比如"test_user_login"这个方法,对应"test_user_login.json"这个文件,根据测试方法名去识别对应的json文件名。这里的json模板具有jinja2模板的所有功能,也就是说,可以根据后台传入的数据,来做if判断。可以实现用同一份数据,在某个参数值为TRUE和FALSE时传不同的数据给服务器。这里的所谓后台,其实就是指我们在测试用例里传给json模板的数据值。这部分数据也是我前面说的可变数据。
好,关于if else的具体例子我就略了,相信读者理解了模板和相关的库后可以很容易写出来。我会在后期慢慢把例子加在我这个github的samples目录里。现在已经加了最基本的测试数据模板渲染例子。
另外我的库里使用hug来编写测试用的rest api,代码极其简单,强烈推荐这个库给大家。
比如这样,就实现了一个get的api和一个post的api,每个接口3行代码,毕竟搞python就是要搞一些简单的东西来用嘛。
import hug@hug.get()
def hello():return "hello"@hug.post()
def post_a_user(user):return {"your_input":user+"X"}
最后: 为了回馈铁杆粉丝们,我给大家整理了完整的软件测试视频学习教程,朋友们如果需要可以自行免费领取 【保证100%免费】

全套资料获取方式:点击下方小卡片自行领取即可

相关文章:
接口测试进阶之数据模板
大家好久不见了。今天的文章将介绍jinja2模板在接口测试数据上的应用。 这几个月我在想,进阶系列要怎么写。 毕竟很多情况下,我觉得写技术文章和做培训一样,都会有两个结果: 1.是需要这些知识的人看不懂。 2.是看得懂的人不需要…...
Java中使用MySQL详解
1. 简介 在Java开发中,与数据库的交互是常见且重要的一部分。MySQL是一个广泛使用的关系型数据库管理系统,而Java作为一种强大的编程语言,提供了丰富的API和工具,使得与MySQL数据库的结合应用更加便捷和高效。 本篇博客将详细介…...
Docker安装Elasticsearch相关软件安装
Docker安装Elasticsearch相关软件安装 本文将介绍通过 Docker 的方式安装 Elasticsearch 相关的软件。 1、Docker安装Elasticsearch 1.1 搜索镜像 $ docker search elasticsearch $ docker search elasticsearch:7.12.11.2 拉取镜像 $ docker pull elasticsearch:7.12.11.…...
Ubuntu的安装与部分配置
该教程使用的虚拟机是virtuabox,镜像源的版本是ubuntu20.04.5桌面版 可通过下面的链接在Ubuntu官网下载:Alternative downloads | Ubuntu 也可直接通过下面的链接进入百度网盘下载【有Ubuntu20.04.5与hadoop3.3.2以及jdk1.8.0_162,该篇需要使…...
为什么 Splashtop 是更好用的 iOS 远程桌面应用
全球远程桌面软件市场最近达到19.2亿美元,表明使用任意设备实现随处远程控制越来越受欢迎。 近年来,企业的运营方式发生了重大改变,远程桌面软件已成为广泛使用的解决方案。Splashtop 是目前最好用的远程桌面工具之一,安全可靠且…...
[SQL挖掘机] - 字符串函数 - lower
介绍: lower函数是mysql中的一个字符串函数,其作用是将给定的字符串转换为小写形式。它接受一个字符串作为参数,并返回一个新的字符串,其中所有的字母字符均被转换为小写形式。 使用lower函数可以帮助我们在字符串处理中实现标准化和规范化…...
什么是Koala?
Koala 介绍 koala 是一个前端预处理器语言图形编译工具,支持 Less、Sass、Compass、CoffeeScript,帮助 web 开发者更高效地使用它们进行开发。跨平台运行,完美兼容 windows、linux、mac。 关键特性 多语言支持 支持 Less、Sass、CoffeeSc…...
阿里巴巴前端开发规范
前言 规范的目的是为了编写高质量的代码,让你的团队成员每天的心情都是愉悦的,大家在一起是快乐的。 现在软件架构的复杂性需要协同开发完成,如何高效地协同呢?无规矩不成方圆,无规范难以协同,比如…...
opencv-19 图像色彩空间转换函数cv2.cvtColor()
cv2.cvtColor() 函数是 OpenCV 中用于图像颜色空间转换的函数。它允许你将图像从一个色彩空间转换为另一个色彩空间。在 Python 中,你可以使用这个函数来实现不同色彩空间之间的转换。 函数的基本语法为: cv2.cvtColor(src, code[, dst[, dstCn]])参数…...
SpringCloudAlibaba微服务实战系列(二)Nacos配置中心
SpringCloudAlibaba Nacos配置中心 在java代码中或者在配置文件中写配置,是最不雅的,意味着每次修改配置都需要重新打包或者替换class文件。若放在远程的配置文件中,每次修改了配置后只需要重启一次服务即可。话不多说,直接干货拉…...
【Kafka源码走读】Admin接口的客户端与服务端的连接流程
注:本文对应的kafka的源码的版本是trunk分支。写这篇文章的主要目的是当作自己阅读源码之后的笔记,写的有点凌乱,还望大佬们海涵,多谢! 最近在写一个Web版的kafka客户端工具,然后查看Kafka官网,…...
Windows API遍历桌面上所有文件
要获取桌面上的图标,可以使用Windows API中的Shell API。以下是遍历桌面上所有文件的示例代码: #include <Windows.h> #include <ShlObj.h> #include <iostream> #include <vector> using namespace std;int main() {// 获取桌…...
【MySQL】基本查询(插入查询结果、聚合函数、分组查询)
目录 一、插入查询结果二、聚合函数三、分组查询(group by & having)四、SQL查询的执行顺序五、OJ练习 一、插入查询结果 语法: INSERT INTO table_name [(column [, column ...])] SELECT ...案例:删除表中重复数据 --创建…...
【Go语言】Golang保姆级入门教程 Go初学者介绍chapter1
Golang 开山篇 Golang的学习方向 区块链研发工程师: 去中心化 虚拟货币 金融 Go服务器端、游戏软件工程师 : C C 处理日志 数据打包 文件系统 数据处理 很厉害 处理大并发 Golang分布式、云计算软件工程师:盛大云 cdn 京东 消息推送 分布式文…...
mysql 自增长键值增量设置
参考文章 MySQL中auto_increment的初值和增量值设置_auto_increment怎么设置_linda公馆的博客-CSDN博客 其中关键语句 show VARIABLES like %auto_increment% set auto_increment_increment4; set auto_increment_offset2;...
【pytho】request五种种请求处理为空和非空处理以及上传excel,上传图片处理
一、python中请求处理 request.args获取的是个字典,所以可以通过get方式获取请求参数和值 request.form获取的也是个字典,所以也可以通过get方式获取请求的form参数和值 request.data,使用过JavaScript,api调用方式进行掺入jso…...
【全面解析】Windows 如何使用 SSH 密钥远程连接 Linux 服务器
创建密钥 创建 linux 服务器端的终端中执行命令 ssh-keygen,之后一直按Enter即可,这样会在将在 ~/.ssh/ 路径下生成公钥(id_rsa.pub)和私钥(id_rsa) 注意:也可以在 windows 端生成密钥,只需要保证公钥在服务器端,私钥…...
解锁新技能《基于logback的纯java版本SDK实现》
开源SDK: <!--Java通用日志组件SDK--> <dependency><groupId>io.github.mingyang66</groupId><artifactId>oceansky-logger</artifactId><version>4.3.6</version> </dependency> <!-- Java基于logback的…...
你需要知道的云原生架构体系内容
云原生(Cloud-Native)的概念在国内提及的越来越多,但大部分人对云原生的认识仅限于容器、微服务、DevOps等内容,把容器、微服务、 DevOps就等同于云原生,这显然是不对的。CNCF从其自身的角度定义了云原生技术ÿ…...
安全渗透--正则表达式
什么是正则表达式? 正则表达式是一组由字母和符号组成的特殊文本,它可以用来从文本中找出满足你想要的格式的句子。 一个正则表达式是一种从左到右匹配主体字符串的模式。 “Regular expression”这个词比较拗口,我们常使用缩写的术语“regex…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...
密码学基础——SM4算法
博客主页:christine-rr-CSDN博客 专栏主页:密码学 📌 【今日更新】📌 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 编辑…...
客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践
01技术背景与业务挑战 某短视频点播企业深耕国内用户市场,但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大,传统架构已较难满足当前企业发展的需求,企业面临着三重挑战: ① 业务:国内用户访问海外服…...
