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

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

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

为什么要自己写框架呢?

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

一个现有的简单接口例子

下面使用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上实现。

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

​​​软件测试面试文档

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

在这里插入图片描述

在这里插入图片描述

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐