[PPJ_12] Python接口测试项目实践(unittest
目录结构
一、API测试项目简介
二、项目API调试
1.浏览器调试API
2.Python IDE调试API
三、unittest用例封装(集成到unittest)
1.应用背景
2.用例设计
3.代码实现
四、测试报告生成
1.创建2个文件夹,存放:测试用例+测试报告
2.下载BSTestRunner.py,配置后放到python的Lib目录下
3.创建 run.py 模块,控制执行测试用例、生成测试报告
一、API测试项目简介
- 项目名称:天气API
- 项目来源:https://www.sojson.com/blog/305.html
-
接口URL:
http://t.weather.sojson.com/api/weather/city/+
city_code - 请求方式:GET
-
参数说明:
city_code
表示城市的Id码,由9为纯数字组成,拼接在以上接口URL的末尾,测试时不需要单独作为参数进行请求
各个城市的city_code码获取地址:http://cdn.sojson.com/_city.json
二、项目API调试
测试案例描述:本次以
广州
作为被测城市("city_code": "101280101"),请求对应城市的天气数据,请求正常情况下,预期将会返回:前一天(yesterday)、当天及未来4天(forecast),一共6天的广州天气数据
拼接成完整的接口URL:http://t.weather.sojson.com/api/weather/city/101280101
1.浏览器调试API
对以上拼接完成的接口URL,在浏览器调试发送请求,响应数据如下:
JSON解析工具①:浏览器自带F12-->Preview
JSON解析工具②:在线JSON校验格式化工具
JSON解析工具③:Json在线解析
2.Python IDE调试API
本次采用PyCharm进行执行Python代码
执行代码:
import requests
# 构造接口测试数据
base_url = 'http://t.weather.sojson.com/api/weather/city'
data = {'city_code':'101280101'} # 广州的城市Id码
# 发送请求
r = requests.get(base_url+'/'+data['city_code']) # 拼接接口URL
print(r.url)
print('------------------')
# 将返回结果转换为json类型
response_data = r.json()
# 从返回结果中获取(日期、信息、状态、城市)
print(response_data['date']) # 请求的当天日期
print(response_data['message']) # message信息
print(response_data['status']) # 响应状态码
print(response_data['cityInfo']['city']) # 请求的城市名称
print('------------------')
# 获取当天的天气
print(response_data['data']['forecast'][0]['date']) # 当天日期
print(response_data['data']['forecast'][0]['type']) # 天气状态
print(response_data['data']['forecast'][0]['high']) # 当天最高温
print(response_data['data']['forecast'][0]['low']) # 当天最低温
执行结果:
http://t.weather.sojson.com/api/weather/city/101280101
------------------
20181022
Success !
200
广州市
------------------
22日星期一
阴
高温 28.0℃
低温 21.0℃
三、unittest用例封装(集成到unittest)
1.应用背景
以上案例中的调试API,仅仅针对单个场景进了接口调用,而实际的接口测试工作中,需要对不同的参数场景进行测试,同时还需要设置断言、生成测试报告
2.用例设计
用例编号 | 测试场景 | 用例描述 | 预期结果 |
---|---|---|---|
01 | 正常参数 | 传入正常存在的city_code值进行测试 | "status":200 "message":"Success !" "city":"广州市" "cityId":与传参时的"city_code"值对应一致 |
02 | 错误参数 | 传入异常参数(如:字母) | "status":404 "message":"Request resource not found." |
03 | 异常参数 | 传入不存在的city_code值 | "status":403 "message":"no_city_id" |
04 | 不传参数 | 不传入任何city_code值(空) | "status":404 "message":"Request resource not found." |
3.代码实现
执行代码:
weather_api_unittest.py
import unittest
import requests
from time import sleep
# 构造WeatherTest类,继承unittest.TestCase
class WeatherTest(unittest.TestCase):
# 用例执行前的准备工作
def setUp(self):
self.url = 'http://t.weather.sojson.com/api/weather/city'
# 定义测试guangzhou天气的方法
def test_weather_guangzhou(self): # 用例方法需要以test开头,便于执行顺利
'''
Case01-正常存在的city_code值
'''
data = {'city_code':'101280101'}
r = requests.get(self.url+'/'+data['city_code']) # 拼接接口URL
result = r.json() # 将返回结果转换为json类型
# 设置断言
self.assertEqual(result['status'],200) # 状态码的值是数字,非字符串
self.assertEqual(result['message'],'Success !')
self.assertEqual(result['cityInfo']['city'],'广州市')
self.assertEqual(result['cityInfo']['cityId'],'101280101')
sleep(3) # 控制请求的间隔时间,防止过快请求而IP受限制
def test_weather_param_error(self):
'''
Case02-错误的city_code值
'''
data = {'city_code':'666abc'}
r = requests.get(self.url+'/'+data['city_code'])
result = r.json()
self.assertEqual(result['message'],'Request resource not found.')
self.assertEqual(result['status'],404)
sleep(3)
def test_weather_param_non_existent(self):
'''
Case03-不存在的city_code值
'''
data = {'city_code':'123456789'}
r = requests.get(self.url+'/'+data['city_code'])
result = r.json()
self.assertEqual(result['message'],'no_city_id')
self.assertEqual(result['status'],403)
sleep(3)
def test_weather_no_param(self):
'''
Case04-不传入任何city_code值(空)
'''
data = {'city_code':''}
r = requests.get(self.url+'/'+data['city_code'])
result = r.json()
self.assertEqual(result['message'],'Request resource not found.')
self.assertEqual(result['status'],404)
sleep(3)
# 调试WeatherTest类
if __name__ == '__main__':
unittest.main()
执行结果:
四、测试报告生成
1.创建2个文件夹,存放:测试用例+测试报告
/test_case/:存放测试用例
/reports/:存放测试报告
2.下载BSTestRunner.py,配置后放到python的Lib目录下
下载传送门:https://github.com/easonhan007/HTMLTestRunner
为了符合报告易用性,可能需要修改所下载的BSTestRunner.py
文件,具体可参看 ==> [Py_19]单元测试(UnitTest)之Web测试应用实战、测试报告生成
适用于Python3.x的模块需要修改以上下载的部分代码:
- 94行:引入的名称从
import StringIO
--->import io
- 539行:
self.outputBuffer = StringIO.StringIO()
--->self.outputBuffer = io.StringIO()
- 631行:
print >>sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)
--->print (sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime))
- 642行;
if not rmap.has_key(cls):
--->if not cls in rmap:
- 766行:
uo = o.decode('latin-1')
--->uo = o
- 772行:
ue = e.decode('latin-1')
--->ue = e
存放路径:
将以上修改完成的HTMLTestRunner模块存放在Python3.x路径下Lib目录里面即可
3.创建 run.py 模块,控制执行测试用例、生成测试报告
在 /test_case/ 和 /reports/ 同级目录下新建 run.py 文件,作为控制执行本次测试用例和生成测试报告的脚本
执行代码:
run.py
import unittest
from BSTestRunner import BSTestRunner
import time
# 指定测试用例 & 测试报告的存放路径
testcase_dir = './test_case'
report_dir = './reports'
# 加载测试用例
discover = unittest.defaultTestLoader.discover(testcase_dir,pattern='weather_api_unittest.py')
# 定义测试报告的文件格式
now = time.strftime("%y-%m-%d %H_%M_%S") # 对时间格式化
report_name = report_dir+'/'+now+'_test_report.html' # 报告的名称规则
# 运行测试用例,并生成测试报告
with open(report_name,'wb') as f:
runner = BSTestRunner(stream=f,title="Weather API Test Report",description="China City Weather Test Report")
runner.run(discover)
执行结果:
代码运行完成,无异常提示,此时在 /reports/ 目录下已生成一个.html格式的测试报告,如下: