本文通过从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上实现。
