【Django 2021年最新版教程35】python+request+unittest 对Django接口进行测试
一、测试对象
对于接口类函数,即被GET、POST调用的函数
二、步骤
1. 使用request发送GET、POST请求
请提前安装requests模块
pip install requests
2. 使用unittest作单元测试
3. 使用.json()解析返回值
三、规则
1. 被测代码的一个python文件对应一个unittest测试文件
2. 每个unittest测试文件中可以包含多个类
3. 每个类对应一个被测函数
4. 每个类可以包含多个测试用例函数
5. 每个测试用例函数对应一个测试用例
四、举例
1. 对于仅仅渲染展示页面的函数
比如
def admin_booking_history(request):return render(request, './adminWeb/booking_history.html')
只需判断请求状态是否为200即可判断成功
import requests
import unittest"""被测代码的一个python文件对应一个unittest测试文件,当前测试adminWeb里views.py""""""一个接口一个类,当前测试admin_booking_history接口"""
class admin_booking_history(unittest.TestCase):def setUp(self):self.url = "http://127.0.0.1:8000/adminweb/bookinghistory"self.headers = {'Content-Type': 'application/x-www-form-urlencoded'}"""测试用例1:测试是否能够正常访问页面"""def test_get(self):res = requests.get(self.url)# 请求成功self.assertEqual(res.status_code,200)if __name__ == '__main__':unittest.main()
2. 对于同时渲染数据和展示页面的函数
比如下面的函数读取了context渲染到html页面上
# 设置展示信息页面
def admin_setting_display_info(request):system_configurations = SystemConfiguration.objects.filter(Q(configuration_name='days_showed_at_most_one_time'))context = {}for system_configuration in system_configurations:temp = model_to_dict(system_configuration)print(temp)context[temp['configuration_name']] = temp['configuration_value']print(context)return render(request, './adminWeb/setting_display_info.html', context)
我们应该将数据和展示分离,也就是说,展示页面只展示,数据通过另外一个接口提供,即数据可以通过在html页面里使用ajax加载。这样就可以分开测试了
3. 需要POST提交的函数
比如
# 保存设置展示信息
@csrf_exempt
def admin_save_display_info(request):days_showed_at_most_one_time = request.POST.get('days_showed_at_most_one_time', None)if days_showed_at_most_one_time is None or days_showed_at_most_one_time == '':return_json = {}return_json['code'] = 1return_json['msg'] = '必须传递days_showed_at_most_one_time参数'return_json['data'] = {}return HttpResponse(json.dumps(return_json), content_type='application/json')defaults = dict()defaults['configuration_name'] = 'days_showed_at_most_one_time'defaults['configuration_value'] = days_showed_at_most_one_timeresult_days_showed_at_most_one_time = SystemConfiguration.objects.update_or_create(defaults=defaults,configuration_name='days_showed_at_most_one_time')print(result_days_showed_at_most_one_time)# update_or_create返回值为元组: (object, created),# object为新建或者更新的对象,# created为一个布尔值,表示是新建还是更新,True为新建,False为更新context = {}context['result_days_showed_at_most_one_time'] = json.dumps(result_days_showed_at_most_one_time[1])print(context)return_json = {}return_json['code'] = 0return_json['msg'] = '修改成功'return_json['data'] = contextreturn HttpResponse(json.dumps(return_json), content_type='application/json')
测试函数为
import requests
import unittest"""被测代码的一个python文件对应一个unittest测试文件,当前测试adminWeb里views.py""""""一个接口一个类,当前测试admin_save_display_info接口"""
class admin_save_display_info(unittest.TestCase):def setUp(self):self.url = "http://127.0.0.1:8000/adminweb/save_display_info"self.headers = {'Content-Type': 'application/x-www-form-urlencoded'}"""测试用例1:必填参数为空"""def test_params_null(self):json ={}res = requests.post(self.url, headers=self.headers, data=json)data = res.json()# print(data)self.assertEqual(res.status_code, 200)self.assertEqual(data["code"], 1, data["msg"])"""测试用例2:是否保存成功"""def test_save(self):#body接口参数body = {"days_showed_at_most_one_time": 9}res = requests.post(self.url, data=body, headers=self.headers)data = res.json()# print(data)self.assertEqual(res.status_code, 200)self.assertEqual(data["code"], 0, data["msg"])if __name__ == '__main__':unittest.main()
4. 有的接口需要在用户登陆的情况下测试
比如测试下面的接口,其中读取了session信息
# 保存用户的预约信息
@csrf_exempt
def save_booking(request):# 校验是否已经登陆if request.session.get('is_login') is None:return_json = {}return_json['code'] = 2return_json['msg'] = '必须先实名登陆'return_json['data'] = {}return HttpResponse(json.dumps(return_json), content_type='application/json')selected_date_id = request.POST.get('selected_date_id', None)if selected_date_id is None or selected_date_id == '':return_json = {}return_json['code'] = 1return_json['msg'] = '必须传递selected_date_id参数'return_json['data'] = {}return HttpResponse(json.dumps(return_json), content_type='application/json')# 查询出该时间段的详情date = EveryDayBookingInfo.objects.filter(id=selected_date_id).first()selected_date = model_to_dict(date)print(selected_date)# 如果可预约人数小于等于0,则表示已经被预约完了if selected_date['remain_number'] <= 0:return_json = {}return_json['code'] = 3return_json['msg'] = '该时间段已经被预约完了'return_json['data'] = {}return HttpResponse(json.dumps(return_json), content_type='application/json')# TODO# 此处省略了校验该用户是否重复预约,同学们可以自己补充# 若该时间段没有被预约完,则扣减1update_result = EveryDayBookingInfo.objects.filter(id=selected_date_id).update(remain_number=(selected_date['remain_number']-1))# 将预约记录保存到数据库中add_result = BookingRecord.objects.create(user_id=request.session.get('user_id'),username=request.session.get('username'), datetime_id=selected_date['id'],datetime_start=selected_date['datetime_start'],datetime_end=selected_date['datetime_end'],submit_datetime=datetime.datetime.now(), is_main_order=1, main_order_id=0,status=1)result = {}result['update_result'] = update_resultresult['add_result'] = add_result.id# TODO# 此处省略了处理同行人的代码return_json = {}return_json['code'] = 0return_json['msg'] = '保存成功'return_json['data'] = resultreturn HttpResponse(json.dumps(return_json), content_type='application/json')
解决方案
现在浏览器正常登陆,获取sessionid
将sessionid放入到测试函数的headers中
import requests
import unittest"""被测代码的一个python文件对应一个unittest测试文件,当前测试adminWeb里views.py""""""一个接口一个类,当前测试save_booking接口"""
class save_booking(unittest.TestCase):def setUp(self):self.url = "http://127.0.0.1:8000/userweb/save_booking""""测试用例1:用户未登陆"""def test_unlogin(self):self.headers = {'Content-Type': 'application/x-www-form-urlencoded'}body ={}res = requests.post(self.url, data=body, headers=self.headers)data = res.json()# print(data)self.assertEqual(res.status_code, 200)self.assertEqual(data["code"], 2, data["msg"])"""测试用例2:用户未已登陆的情况下,未传递必要参数"""def test_login_and_params_null(self):self.headers = {'Content-Type': 'application/x-www-form-urlencoded','Cookie': "sessionid=rcyydgtytt9olvgpusdo66eygzatpomx"}body ={# "selected_date_id": 54}res = requests.post(self.url, data=body, headers=self.headers)data = res.json()print(data)self.assertEqual(res.status_code, 200)self.assertEqual(data["code"], 1, data["msg"])if __name__ == '__main__':unittest.main()
五、实操
新建一个测试文件
测试代码
import requests
import unittest"""被测代码的一个python文件对应一个unittest测试文件,当前测试adminWeb里views.py""""""一个接口一个类,当前测试admin_booking_history接口"""
class admin_booking_history(unittest.TestCase):def setUp(self):self.url = "http://127.0.0.1:8000/adminweb/bookinghistory"self.headers = {'Content-Type': 'application/x-www-form-urlencoded'}"""测试用例1:测试是否能够正常访问页面"""def test_get(self):res = requests.get(self.url)# 请求成功self.assertEqual(res.status_code,200)"""一个接口一个类,当前测试admin_save_display_info接口"""
class admin_save_display_info(unittest.TestCase):def setUp(self):self.url = "http://127.0.0.1:8000/adminweb/save_display_info"self.headers = {'Content-Type': 'application/x-www-form-urlencoded'}"""测试用例1:必填参数为空"""def test_params_null(self):json ={}res = requests.post(self.url, headers=self.headers, data=json)data = res.json()# print(data)self.assertEqual(res.status_code, 200)self.assertEqual(data["code"], 1, data["msg"])"""测试用例2:是否保存成功"""def test_save(self):#body接口参数body = {"days_showed_at_most_one_time": 9}res = requests.post(self.url, data=body, headers=self.headers)data = res.json()# print(data)self.assertEqual(res.status_code, 200)self.assertEqual(data["code"], 0, data["msg"])"""一个接口一个类,当前测试save_booking接口"""
class save_booking(unittest.TestCase):def setUp(self):self.url = "http://127.0.0.1:8000/userweb/save_booking""""测试用例1:用户未登陆"""def test_unlogin(self):self.headers = {'Content-Type': 'application/x-www-form-urlencoded'}body ={}res = requests.post(self.url, data=body, headers=self.headers)data = res.json()# print(data)self.assertEqual(res.status_code, 200)self.assertEqual(data["code"], 2, data["msg"])"""测试用例2:用户未已登陆的情况下,未传递必要参数"""def test_login_and_params_null(self):self.headers = {'Content-Type': 'application/x-www-form-urlencoded','Cookie': "sessionid=rcyydgtytt9olvgpusdo66eygzatpomx"}body ={# "selected_date_id": 54}res = requests.post(self.url, data=body, headers=self.headers)data = res.json()print(data)self.assertEqual(res.status_code, 200)self.assertEqual(data["code"], 1, data["msg"])if __name__ == '__main__':unittest.main()
运行结果
六、更多情况请参考下面的文章和代码示例
stduy《python+request+unittest 接口测试练习》
https://www.cnblogs.com/gaoyuanyuan/p/9837771.html
import requests
import unittest
"""嘉宾查询接口"""
class GuestQuery(unittest.TestCase):def setUp(self):self.url="http://127.0.0.1: 8000/api/get_event_list/""""使用错误的请求方式post 进行测试"""def test_method_post(self):res = requests.post(self.url)data = res.json()self.assertEqual(data["status"],"100" )self.assertEqual(data["message"],"请求方法错误")"""使用get正确查询"""def test_method_get(self):res = requests.get(self.url)data = res.json()# print(data)self.assertEqual(res.status_code,200)self.assertEqual(data["status"],"110)")self.assertEqual(data["message"],"查询成功")"""嘉宾添加接口"""
class GuestAdd(unittest.TestCase):def setUp(self):self.url = "http://127.0.0.1: 8000/api/add_event/"self.headers = {'Content-Type': 'application/json'}"""使用错误的请求方法get 进行测试"""def test_get_guest(self):res = requests.get(self.url)data = res.json()self.assertEqual(res.status_code,200)self.assertEqual(data["status"],"404" )self.assertEqual(data["message"],"请求方法错误")"""必填参数为空"""def test_add_guest_params_null(self):json ={}res = requests.post(self.url,json,self.headers)data = res.json()print(data)self.assertEqual(res.status_code, 200)self.assertEqual(data["status"],"10020" )self.assertEqual(data["message"],"parameter null")"""必填参数 值为空"""def test_add_guest_params_value_null(self):json = {"event_id": "","realname": "","phone": "","email": "","sign": ""}res = requests.post(self.url,json,self.headers)data = res.json()print(data)self.assertEqual(res.status_code, 200)self.assertEqual(data["status"],"10021" )self.assertEqual(data["message"],"parameter error")"""发布会id为不存在"""def test_add_guest_event_id(self):json = {"event_id": 88888,"realname": "张三","phone": "15210001000","email": "152100@qq.com","sign": "0"}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(res.status_code, 200)self.assertEqual(data["status"],"10022" )self.assertEqual(data["message"],"event id null")"""发布会id为非整型"""def test_add_guest_event_id(self):json = {"event_id": "123","realname": "张三","phone": "15210001000","email": "152100@qq.com","sign": "0"}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(res.status_code, 200)self.assertEqual(data["status"],"10023" )self.assertEqual(data["message"],"event status is not available")"""发布会id已经达到limit人数"""def test_add_guest_event_id(self):json = {"event_id": "1","realname": "张三","phone": "15210001000","email": "152100@qq.com","sign": "0"}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(res.status_code, 200)self.assertEqual(data["status"],"10024" )self.assertEqual(data["message"],"event number is full")"""发布会已近结束"""def test_add_guest_event_id(self):json = {"event_id": "10","realname": "张三","phone": "15210001000","email": "152100@qq.com","sign": "0"}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(res.status_code, 200)self.assertEqual(data["status"],"10025" )self.assertEqual(data["message"],"event has started")"""S使用已签到的手机号再次进行签到"""def test_add_guest_event_id(self):json = {"event_id": "10","realname": "张三","phone": "15210001000","email": "152100@qq.com","sign": "0"}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(res.status_code, 200)self.assertEqual(data["status"],"10026" )self.assertEqual(data["message"],"'the event guest phone number repeat")"""使用未签到的手机进行签到"""def test_add_guest_event_id(self):json = {"event_id": "10","realname": "张三","phone": "15210001001","email": "152100@qq.com","sign": "0"}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(res.status_code, 200)self.assertEqual(data["status"],"200" )self.assertEqual(data["message"],"'add guest success")class Sign(unittest.TestCase):def setUp(self):self.url = "http://127.0.0.1: 8000/api/sign/"self.headers = {'Content-Type': 'application/json'}"""使用错误的请求方法"""def test_method_get(self):res = requests.get(self.url)data = res.json()self.assertEqual(data["status"],"404" )self.assertEqual(data["message"],"请求方法错误")"""请求参数为空"""def test_method_get(self):json = {}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(data["status"],"10020" )self.assertEqual(data["message"],"parameter is null")"""请求参数 值为空"""def test_method_get(self):json = {"eid":"","phone":""}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(data["status"],"10021" )self.assertEqual(data["message"],"parameter error")"""发布会id不存在"""def test_method_get(self):json = {"eid":9999,"phone":"15210001000"}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(data["status"],"10022" )self.assertEqual(data["message"],"event id null")"""发布会状态是关闭的"""def test_method_get(self):json = {"eid":1,"phone":"15210001000"}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(data["status"],"10023" )self.assertEqual(data["message"],"event status is not available")"""当前时间大于发布会时间,发布会已经开始了"""def test_method_get(self):json = {"eid":1,"phone":"15210001000"}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(data["status"],"10024" )self.assertEqual(data["message"],"event has started")"""使用嘉宾表不存在的手机号测试"""def test_method_get(self):json = {"eid":1,"phone":"1521888888"}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(data["status"],"10025" )self.assertEqual(data["message"],"user phone null")"""使用其他发布会手机号测试"""def test_method_get(self):json = {"eid":2,"phone":"1521888888"}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(data["status"],"10026" )self.assertEqual(data["message"],"user did not participate in the conference")"""使用已签到的手机号测试"""def test_method_get(self):json = {"eid":1,"phone":"15210001000"}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(data["status"],"10027" )self.assertEqual(data["message"],"user has sign in")"""正常签到"""def test_method_get(self):json = {"eid":1,"phone":"15210001001"}res = requests.post(self.url,json,self.headers)data = res.json()self.assertEqual(data["status"],"200" )self.assertEqual(data["message"],"sign success")if __name__ == '__main__':unittest.main()
【Django 2021年最新版教程35】python+request+unittest 对Django接口进行测试相关推荐
- python+requests+unittest+HTMLTestRunner构建接口自动化测试框架(四)测试用例执行
python+requests+unittest+HTMLTestRunner构建接口自动化测试框架(一)了解基础框架,读取配置文件 python+requests+unittest+HTMLTest ...
- 接口自动化环境搭建-Python Request + Unittest
文章目录 前言 一.前期准备 二.搭建环境 1. 创建项目目录 2. 创建一个cases目录,管理所有的case 3. 找一个测试接口,编写测试脚本 4. 抽离公共方法 - 发送请求 5. 抽离测试数 ...
- 使用python第三方库Parameterized进行接口参数化测试
说明:使用python自带的unittest单元测试框架进行接口参数化测试时,因unittest不具备参数化测试,所以需要借助Parameterized第三库进行测试. 一.Parameterized ...
- 系统学习Python——单元测试unittest:命令行执行测试
分类目录:<系统学习Python>总目录 相关文章: · 单元测试unittest:框架结构 · 单元测试unittest:测试固件 · 单元测试unittest:编写测试用例 · 单元测 ...
- Python Request POST 上传文件 Multipart/form-data
项目场景: 我的第一个博客:使用python request模块向服务器接口上传图片 问题描述 某app上传图片接口的包 原因分析: 问题的关键词:请求头 Content-Type:multipart ...
- Python入门(二十六)测试(一)
测试(一) 1.概述 2.测试函数 2.1 单元测试和测试用例 2.2 可通过的测试 2.3 未通过的测试 2.4 测试未通过怎办 2.5 添加新测试 1.概述 编写函数或类时,还可为其编写测试.通过 ...
- Django Python:完整的BUNDLE + Django真实项目2021
Django和python Bundle:从学习python的所有基础知识到高级python再到UI设计TKINTER,然后是Django 你会学到: 学习编程的基础知识 学习Python编程语言 学 ...
- 自学网python教程视频-Python爬虫之Django视频教程
Django是一个开放源代码的Web应用框架,由Python写成.采用了MVC的框架模式,即模型M,视图V和控制器C. 它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CM ...
- 如何自学python到做项目-django教程如何自学
Django教程是讲解Django框架学习方法和步骤的,可以理解为教材,是供初学者或者程序员学习和提升技术的. 下面介绍下Django教程所包含的内容以及学Django所需要的必备技能. 学Djang ...
- Django 优秀资源大全项目资源非 Python 包工具贡献
Awesome Django 介绍 Awesome-Django 是由 Roberto Rosario 发起和维护的 Django 资源列表.该列表收集了大量 Django 相关的优秀应用.项目等资源 ...
最新文章
- Java8学习之旅2---基于Lambda的JDBC编程
- Linux总线驱动-02: struct bus_type 结构体
- hibernate merge saveorupdate save lock
- echarts折线图背景线_echarts设置折线线条颜色和折线点颜色的实例
- 一张图看懂微软Power BI系列组件
- Ruby,Python和Java中的Web服务
- 宝塔可以修改服务器内存限制吗,宝塔内存使用率很高的解决方法 cpu过高这样做!...
- Java运行机制和运行过程基础知识
- 【英语学习】【WOTD】scrumptious 释义/词源/示例
- 5G/NR 学习笔记 - RAR随机接入过程
- Qt之QFileIconProvider
- 【精通内核】CPU控制并发原理CPU中断控制内核解析
- Java Wed学习总结
- ResourceExhaustedError
- 腾讯通RTX拓展功能
- eclipse中找不到jar包中的类与函数java.lang.ClassNotFoundException让jar包全局可用
- 淘宝直播弹幕API接口协议
- FOC——2.RC吸收电路笔记
- 董明珠用 3.1 亿的带货成绩,刷新了许多人对直播电商的认知
- 论文笔记(十七):Brax — A Differentiable Physics Engine for Large Scale Rigid Body Simulation
热门文章
- 实战:配置内网DNS实现内部域名解析
- Android重力感应实现方式简介
- [SDOI2009] HH去散步 (矩阵乘法)
- [HAOI2010]计数(组合数学)(数位DP)
- python使用sax实现xml解析
- bzoj 3208 花神的秒题计划I
- 孙鑫VC学习笔记:第十三讲 (五) 保存可串行化的类对象 如何获取文档与视类指针
- 拓端tecdat|R语言非线性回归nls探索分析河流阶段性流量数据和评级曲线、流量预测可视化
- 拓端tecdat|R语言蒙特卡洛方法:方差分量的Metropolis Hastings(M-H)、吉布斯Gibbs采样比较分析
- JUC与JVM并发编程学习笔记02