基于python+unittest实现接口自动化测试

news2024/11/18 3:32:00

简介

本文通过从Postman获取基本的接口测试Code简单的接口测试入手,一步步调整优化接口调用,以及增加基本的结果判断,讲解Python自带的Unittest框架调用,期望各位可以通过本文对接口自动化测试有一个大致的了解。

为什么要做接口自动化测试?

在当前互联网产品迭代频繁的背景下,回归测试的时间越来越少,很难在每个迭代都对所有功能做完整回归。但接口自动化测试因其实现简单、维护成本低,容易提高覆盖率等特点,越来越受重视。

为什么要自己写框架呢?

使用Postman调试通过过直接可以获取接口测试的基本代码,结合使用requets + unittest很容易实现接口自动化测试的封装,而且requests的api已经非常人性化,非常简单,但通过封装以后(特别是针对公司内特定接口),可以进一步提高脚本编写效率。

同时,在这我准备了一份软件测试视频教程(含接口、自动化、性能等),需要的可以直接在下方观看,或者直接关注VX公众号:互联网杂货铺这份测试文档资料也打包在里面啦,免费领取!

软件测试视频教程观看处:

【B站最系统自动化测试教程】整整400集,从入门到项目实战,只需18天,手把手带你进阶自动化测试!!!

一个现有的简单接口例子

下面使用requests + unittest测试一个查询接口

接口信息如下

请求信息:

Method:POST

URL:api/match/image/getjson

Request:

{
"category": "image",
"offset": "0",
"limit": "30",
"sourceId": "0",
"metaTitle": "",
"metaId": "0",
"classify": "unclassify",
"startTime": "",
"endTime": "",
"createStart": "",
"createEnd": "",
"sourceType": "",
"isTracking": "true",
"metaGroup": "",
"companyId": "0",
"lastDays": "1",
"author": ""
}

 Response示例:

{
"timestamp" : xxx,
"errorMsg" : "",
"data" : {
"config" : xxx
}

Postman测试方法

测试思路

1.获取Postman原始脚本

2.使用requests库模拟发送HTTP请求**

3.对原始脚本进行基础改造**

4.使用python标准库里unittest写测试case**

原始脚本实现

未优化

该代码只是简单的一次调用,而且返回的结果太多,很多返回信息暂时没用,示例代码如下:

import requests
 
url = "http://cpright.xinhua-news.cn/api/match/image/getjson"
 
querystring = {"category":"image","offset":"0","limit":"30","sourceId":"0","metaTitle":"","metaId":"0","classify":"unclassify","startTime":"","endTime":"","createStart":"","createEnd":"","sourceType":"","isTracking":"true","metaGroup":"","companyId":"0","lastDays":"1","author":""}
 
headers = {
    'cache-control': "no-cache",
    'postman-token': "e97a99b0-424b-b2a5-7602-22cd50223c15"
    }
 
response = requests.request("POST", url, headers=headers, params=querystring)
 
print(response.text)

优化 第一版

调整代码结构,输出结果Json出来,获取需要验证的response.status_code,以及获取结果校验需要用到的results['total']

#!/usr/bin/env python
#coding: utf-8
'''
unittest merchant backgroud interface
@author: zhang_jin
@version: 1.0
@see:http://www.python-requests.org/en/master/
'''
 
import unittest
import json
import traceback
import requests
 
 
url = "http://cpright.xinhua-news.cn/api/match/image/getjson"
 
querystring = {
    "category": "image",
    "offset": "0",
    "limit": "30",
    "sourceId": "0",
    "metaTitle": "",
    "metaId": "0",
    "classify": "unclassify",
    "startTime": "",
    "endTime": "",
    "createStart": "",
    "createEnd": "",
    "sourceType": "",
    "isTracking": "true",
    "metaGroup": "",
    "companyId": "0",
    "lastDays": "1",
    "author": ""
}
 
headers = {
    'cache-control': "no-cache",
    'postman-token': "e97a99b0-424b-b2a5-7602-22cd50223c15"
    }
 
#Post接口调用
response = requests.request("POST", url, headers=headers, params=querystring)
 
#对返回结果进行转义成json串
results = json.loads(response.text)
 
#获取http请求的status_code
print "Http code:",response.status_code
 
#获取结果中的total的值
print results['total']
#print(response.text)

优化 第二版

接口调用异常处理,增加try,except处理,对于返回response.status_code,返回200进行结果比对,不是200数据异常信息。

#!/usr/bin/env python
#coding: utf-8
'''
unittest merchant backgroud interface
@author: zhang_jin
@version: 1.0
@see:http://www.python-requests.org/en/master/
'''
 
import json
import traceback
import requests
 
 
url = "http://cpright.xinhua-news.cn/api/match/image/getjson"
 
querystring = {
    "category": "image",
    "offset": "0",
    "limit": "30",
    "sourceId": "0",
    "metaTitle": "",
    "metaId": "0",
    "classify": "unclassify",
    "startTime": "",
    "endTime": "",
    "createStart": "",
    "createEnd": "",
    "sourceType": "",
    "isTracking": "true",
    "metaGroup": "",
    "companyId": "0",
    "lastDays": "1",
    "author": ""
}
 
headers = {
    'cache-control': "no-cache",
    'postman-token': "e97a99b0-424b-b2a5-7602-22cd50223c15"
    }
 
 
try:
    #Post接口调用
    response = requests.request("POST", url, headers=headers, params=querystring)
 
    #对http返回值进行判断,对于200做基本校验
    if response.status_code == 200:
        results = json.loads(response.text)
        if results['total'] == 191:
            print "Success"
        else:
            print "Fail"
            print results['total']
    else:
        #对于http返回非200的code,输出相应的code
        raise Exception("http error info:%s" %response.status_code)
except:
    traceback.print_exc()

优化 第三版

1.该版本改动较大,引入config文件,单独封装结果校验模块,引入unittest模块,实现接口自动调用,并增加log处理模块;
2.对不同Post请求结果进行封装,不同接口分开调用;
3.测试用例的结果进行统计并最终输出

#!/usr/bin/env python
#coding: utf-8
'''
unittest interface
@author: zhang_jin
@version: 1.0
@see:http://www.python-requests.org/en/master/
'''
 
import unittest
import json
import traceback
import requests
import time
import result_statistics
import config as cf
from com_logger import  match_Logger
 
 
class MyTestSuite(unittest.TestCase):
    """docstring for MyTestSuite"""
    #@classmethod
    def sedUp(self):
        print "start..."
    #图片匹配统计
    def test_image_match_001(self):
        url = cf.URL1
 
        querystring = {
            "category": "image",
            "offset": "0",
            "limit": "30",
          "sourceId": "0",
          "metaTitle": "",
          "metaId": "0",
          "classify": "unclassify",
          "startTime": "",
          "endTime": "",
          "createStart": "",
          "createEnd": "",
          "sourceType": "",
          "isTracking": "true",
          "metaGroup": "",
          "companyId": "0",
          "lastDays": "1",
          "author": ""
        }
        headers = {
            'cache-control': "no-cache",
            'postman-token': "545a2e40-b120-2096-960c-54875be347be"
            }
 
 
        response = requests.request("POST", url, headers=headers, params=querystring)
        if response.status_code == 200:
            response.encoding = response.apparent_encoding
            results = json.loads(response.text)
            #预期结果与实际结果校验,调用result_statistics模块
            result_statistics.test_result(results,196)
        else:
            print "http error info:%s" %response.status_code
 
        #match_Logger.info("start image_query22222")
        #self.assertEqual(results['total'], 888)
 
        '''
        try:
            self.assertEqual(results['total'], 888)
        except:
            match_Logger.error(traceback.format_exc())
        #print results['total']
        '''
 
    #文字匹配数据统计
    def test_text_match_001(self):
 
        text_url = cf.URL2
 
        querystring = {
            "category": "text",
            "offset": "0",
            "limit": "30",
            "sourceId": "0",
            "metaTitle": "",
            "metaId": "0",
            "startTime": "2017-04-14",
            "endTime": "2017-04-15",
            "createStart": "",
            "createEnd": "",
            "sourceType": "",
            "isTracking": "true",
            "metaGroup": "",
            "companyId": "0",
            "lastDays": "0",
            "author": "",
            "content": ""
        }
        headers = {
            'cache-control': "no-cache",
            'postman-token': "ef3c29d8-1c88-062a-76d9-f2fbebf2536c"
            }
 
        response = requests.request("POST", text_url, headers=headers, params=querystring)
 
        if response.status_code == 200:
            response.encoding = response.apparent_encoding
            results = json.loads(response.text)
            #预期结果与实际结果校验,调用result_statistics模块
            result_statistics.test_result(results,190)
        else:
            print "http error info:%s" %response.status_code
 
        #print(response.text)
 
    def tearDown(self): 
        pass
 
if __name__ == '__main__':
    #image_match_Logger = ALogger('image_match', log_level='INFO')
 
    #构造测试集合
    suite=unittest.TestSuite()
    suite.addTest(MyTestSuite("test_image_match_001"))
    suite.addTest(MyTestSuite("test_text_match_001"))
 
    #执行测试
    runner = unittest.TextTestRunner()
    runner.run(suite)
    print "success case:",result_statistics.num_success
    print "fail case:",result_statistics.num_fail
    #unittest.main()

最终输出日志信息

Zj-Mac:unittest lazybone$ python image_test_3.py 
测试结果:通过
 
.测试结果:不通过 
错误信息: 期望返回值:190 实际返回值:4522
 
.
----------------------------------------------------------------------
Ran 2 tests in 0.889s
 
OK
success case: 1
fail case: 1

后续改进建议

1.unittest输出报告也可以推荐使用HTMLTestRunner(我目前是对结果统计进行了封装)

2.接口的继续封装,参数化,模块化

3.unittest单元测试框架实现参数化调用第三方模块引用(nose-parameterized)

4.持续集成运行环境、定时任务、触发运行、邮件发送等一系列功能均可以在Jenkins上实现。

PS:这里分享一套软件测试的自学教程合集。对于在测试行业发展的小伙伴们来说应该会很有帮助。除了基础入门的资源,博主也收集不少进阶自动化的资源,从理论到实战,知行合一才能真正的掌握。全套内容已经打包到网盘,内容总量接近500个G。如需要软件测试学习资料,关注公众号(互联网杂货铺),后台回复1,整理不易,给个关注点个赞吧,谢谢各位大佬!

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


 

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

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

相关文章

VMware虚拟机搭建+云平台购买搭建(阿里云+UCloud)【设置主机名以及主机名映射、配置免密登录、配置JDK】

本地虚拟机的搭建 一、准备网段 在VMware的虚拟网络编辑器中将VMnet8虚拟网卡的 网段设置为:192.168.88.0网关设置为:192.168.88.2 二、下载CentOS操作系统文件,并安装 三、克隆多台虚拟机 依照同样的方法,克隆出node2…

火狐,要完了!

在过去几年中,关于Firefox 浏览器的衰落有过不少讨论。目前来说,很多公共的以及私营的大型网站都缺乏对Firefox的适当支持。但是Firefox也多次试图“自救”,甚至就在不久前,Mozilla 通过官博发文,表示 Firefox 在 2023…

AWS KeyPair密钥格式转换PPK<>PEM

概述说明 PEM(Privacy Enhanced Mail)和PPK(Putty Private Key)都是与加密和安全相关的文件格式,通常用于存储私钥信息。它们在不同的上下文中使用,并且与不同的软件和协议相关联。 PEM(Priva…

基于SpringBoot的学生管理系统

基于SpringBoot的学生管理系统 文章目录 基于SpringBoot的学生管理系统 一.引言二.系统设计三.技术架构四.功能实现五.界面展示六.源码获取 一.引言 学生管理系统是一种用于管理学生信息、课程安排、成绩记录等学生相关数据的软件系统。它通过集中管理学生信息,提供…

Java Web应用小案例 - 实现用户登录功能

文章目录 一、使用纯JSP方式实现用户登录功能(一)项目概述(二)实现步骤1、创建Web项目2、创建登录页面 二、使用JSPServlet方式实现用户登录功能三、使用JSPServletDB方式实现用户登录功能 一、使用纯JSP方式实现用户登录功能 &a…

spring 的概述和入门

​ 我是南城余!阿里云开发者平台专家博士证书获得者! 欢迎关注我的博客!一同成长! 一名从事运维开发的worker,记录分享学习。 专注于AI,运维开发,windows Linux 系统领域的分享! …

ffmpeg格式转换 免费使用视频格式转换教程

下载安装 首先去官网下载ffmpeg的软件包https://ffmpeg.org/ 如果是windows可以在直接下载编译好的软件包 https://www.gyan.dev/ffmpeg/builds/ 进入解压后的目录,子目录bin中的ffmpeg.exe就是我们要使用的转换器 视频信息查看 打开cmd控制台,从…

Linux嵌入式配置USB鼠标支持+触摸板

在linux嵌入式中加入鼠标支持,首先在内核里面将mice驱动加入编译,这里用到的是usb所以还要有usb的支持,下载到板子上启动 1、定位鼠标 要用鼠标,首先要知道生成的鼠标设备是哪个,直接直接ls input目录,当…

HalconDotNe.HOperatorException:“HALCON error#1401:

Wrong number of values of control parameter 1in operator draw_rectangle2_mod错误提示参数值不对,是窗体hv_WindowHandle错了,窗体未创建。

【Linux系统编程】项目自动化构建工具make/Makefile

介绍: make和Makefile是用于编译和构建C/C程序的工具和文件。Makefile是一个文本文件,其中包含了编译和构建程序所需的规则和指令。它告诉make工具如何根据源代码文件生成可执行文件,里面保存的是依赖关系和依赖方法。make是一个命令行工具&a…

[ 蓝桥杯Web真题 ]-Markdown 文档解析

目录 介绍 准备 目标 规定 思路 补充知识 解法参考 介绍 Markdown 因为其简洁的语法大受欢迎,已经成为大家写博客或文档时必备的技能点,众多博客平台都提倡用户使用 Markdown 语法进行文章书写,然后再发布后,实时的将其转化…

如何入驻抖音本地生活服务商,门槛太高怎么办?

随着抖音本地生活服务市场的逐渐成熟,越来越多平台开始涉及本地生活服务领域,而本地生活服务商成了一个香窝窝,为了保护用户权益和平台生态,对入驻入驻抖音本地生活服务商的条件及审核也越来越严格,这让很多想成为抖音…

【Flink系列四】Window及Watermark

3.1、window 在 Flink 中 Window 可以将无限流切分成有限流,是处理有限流的核心组件,现在 Flink 中 Window 可以是时间驱动的(Time Window),也可以是数据驱动的(Count Window)。 Flink中的窗口…

CSS特效025:旋转的loading状态

CSS常用示例100专栏目录 本专栏记录的是经常使用的CSS示例与技巧,主要包含CSS布局,CSS特效,CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点,CSS特效主要是一些动画示例,CSS花边是描述了一些CSS…

idea安装包下载

idea安装教程 IDEA安装包链接:https://pan.baidu.com/s/15dEPF2hV3WPiFWMwGOsKWQ 提取码:kxl7 有激活部署的文档说明,下载自己看吧, 链接:https://pan.baidu.com/s/11yh8cz0R86Ngl7EJN8_5FA 提取码:mdg6

小知识点——Servlet

Servlet 是什么? Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。使用 Servlet,您可以收集来自网页表单的用户输入,呈…

2023滨海湾人工智能论坛举办,范向伟代表和鲸科技共同发起成立工业智能算法联盟

人工智能是新一轮科技革命和产业变革的重要驱动力量,算力算法产业也正迎来爆发式增长。12月7日,以“要素融合知识互联”为主题的2023滨海湾人工智能论坛在东莞滨海湾新区举行,本次活动由东莞市人民政府主办,东莞滨海湾新区管委会、…

【android开发-21】android中调用系统摄像头camera拍照和相册的用法详解

1,调用摄像头 在Android中,调用系统摄像头拍照需要使用Intent来启动Camera应用,并在应用中设置相应的权限。下面是一个简单的例子: // 创建一个Intent对象,指定要执行的动作是拍照 Intent intent new Intent(Medi…

循环结构中 break、continue、return 和exit() 的区别

循环结构中 break、continue、return 和exit() 的区别 文章目录 循环结构中 break、continue、return 和exit() 的区别一、break语句二、continue语句三、return 语句四、exit() 函数 说明:本文内容参考牟海军 著《C语言进阶: 重点、难点与疑点解析》&a…

MyBatis中的N+1问题,使用ResultSet来解决,需要存储过程【非常详细】

基础表sql 订单表 CREATE TABLE test_order (order_id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 订单id,order_name varchar(255) NOT NULL DEFAULT COMMENT 订单名字,PRIMARY KEY (order_id) ) ENGINEInnoDB AUTO_INCREMENT3 DEFAULT CHARSETutf8mb4 COMMENT订单表;INS…