接口测试进阶之数据模板
大家好久不见了。今天的文章将介绍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…...

git如何撤销commit(未push)
文章目录 前言undo commitreset current branch to here Undo Commit,Revert Commit,Drop Commit的区别 是否删除对代码的修改是否删除Commit记录是否会新增Commit记录Undo Commit不会未Push会,已Push不会不会Revert Commit会不会会Drop Com…...

Vue数组与字符串互转
一、数组转换成字符串的方法 join() var arr [A, B, C]; var str arr.join(、); console.log(str); // 输出 A、B、C toString() var arr [A, B, C]; var str arr.toString(); console.log(str); // 输出 A, B, C JSON.stringify() var arr [A, B, C]; var str JSO…...

Java编程实现遍历两个MAC地址之间所有MAC的方法
Java编程实现遍历两个MAC地址之间所有MAC的方法 本文实例讲述了java编程实现遍历两个MAC地址之间所有MAC的方法。分享给大家供大http://家参考,具体如下: 在对发放的设备进行后台管理时,很多时候会用到设备MAC这个字段,它可以标识唯一一个设备。然而在数…...

用AXIS2发布WebService的方法
Axis2+tomcat6.0 实现webService 服务端发布与客户端的调用。 Aixs2开发webService的方法有很多,在此只介绍一种比较简单的实现方法。 第一步:首先要下载开发所需要的jar包 下载:axis2-1.6.1-war.zip http://www.apache.org/dist//axis/axis2/java/core/1.6.1/ 下载…...

嵌入式学习_Day 003
程序功能介绍 c #include <stdio.h> int main() {char c,ll;printf("please enter a capital letter:");cgetchar();getchar();if (c>A&& c<Z) {llc32;printf("Lowercase letter output:%c\n",ll);printf("ASCII value:%d\n"…...

常用的数据结构 JAVA
目录 1、线性表2、栈:3、队列: 1、线性表 List<Object> narnat new ArrayList<>();ArrayList:动态数组 1、可以嵌套使用 2、add(x)添加元素x,remove(index)删除某个位置的元素 3、注意list是指向性的,…...

基于机器视觉工具箱和形态学处理的视频中目标形状检测算法matlab仿真
目录 1.算法理论概述 2.部分核心程序 3.算法运行软件版本 4.算法运行效果图预览 5.算法完整程序工程 1.算法理论概述 目标形状检测是计算机视觉领域的重要任务之一,旨在从视频序列中自动检测和识别特定目标的形状。本文介绍一种基于机器视觉工具箱和形态学处理…...

小白入门:sentence-transformer 提取embedding模型转onnx
文章目录 序言原理讲解哪些部分可转onnx 代码区0. 安装依赖1. 路径配置2. 测试数据3. 准备工作3.1迁移保存目标文件 4. model转onnx-gpu5. 测试一下是否出错以及速度5.1 测试速度是否OK5.2测试结果是否OK 6. tar 这些文件 序言 本文适合小白入门,以自己训练的句子e…...

数据库应用:Redis持久化
目录 一、理论 1.Redis 高可用 2.Redis持久化 3.RDB持久化 4.AOF持久化(支持秒级写入) 5.RDB和AOF的优缺点 6.RDB和AOF对比 7.Redis性能管理 8.Redis的优化 二、实验 1.RDB持久化 2.AOF持久化 3.Redis性能管理 4.Redis的优化 三、总结 一、…...

js版计算比亚迪行驶里程连续12个月计算不超3万公里改进版带echar
<!DOCTYPE html> <html lang"zh-CN" style"height: 100%"> <head> <meta charset"utf-8" /> <title>连续12个月不超3万公里计算LIGUANGHUA</title> <style> .clocks { …...