操作系统: windows
IDE: Pycharm
前后端分离的项目,后端现在已经实现了增删改查,怎么样进行测试呢?
难道要等前端做完,将项目整合好再进行测试吗?
答: 不用,可以使用request库构造API请求,发送给服务端进行测试。
首先先来看和前端集成。
和前端集成:
前后端分离的产品,最终前端和后端系统会集成在一起成为一个完整的系统。
部署到生产环境运行的架构往往比较复杂,先来看看开发环境下, 前后端分离的架构如何简单集成。
前端环境其实就是一些前端的代码和资源文件,包括 js文件、html文件、css文件还有图片视频文件等。前端的资源都是一些静态资源。
注意: 实际生产环境中,并不会通过Django来获取前端的静态资源,Django只有在开发模式(setting.py中DEBUG = True)中才会服务静态文件,是开发时使用的一种临时方案 ,性能很低,这是方便我们调试程序用的。正式部署web服务的时候应该采用其它方法,比如Nginx等。
现在下载好前端部分的文件,放到根目录中:
接下来我们配置 Django 静态文件服务:
打开 Django_test/urls.py 文件,修改一下:
from django.contrib import admin
from django.urls import path, include
# static 静态文件服务
# Django路由匹配是按次序来的,前面的没有匹配到就匹配static,从/z_dist目录下找
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('sales/', include('sales.urls')),
path('api/mgr/', include('mgr.urls'))
] + static("/", document_root="./z_dist")
现在启动服务,打开浏览器输入网址:127.0.0.1:8080/mgr/index.html
出现管理员界面(这里不知道为什么用火狐出不来 -=)
这时候按F12并刷新,可以看到请求的url,请求根据我们设计的那样,路由到api/mgr
,然后到customer的dispatcher
方法,再根据action的值判断由哪个函数进行处理……
然后也可以看到请求的response的内容也正是我们数据库中的内容:
在网页上添加一个客户,功能没问题,也确实添加到数据库中了:
经过测试,删除修改功能也都正常,后端通过接口实现了需要的功能,后端一切遵循接口来实现。
实现登录:
首先查看API接口文档
请求消息:
POST /api/mgr/signin HTTP/1.1
Content-Type: application/x-www-form-urlencoded
请求参数:
http 请求消息 body 中 参数以 格式 x-www-form-urlencoded
存储
需要携带如下参数:
- username 用户名
- password 密码
响应消息:
HTTP/1.1 200 OK
Content-Type: application/json
响应内容:
http 响应消息 body 中, 数据以json格式存储,
如果登录成功,返回如下
{
"ret": 0
}
ret 为 0 表示登录成功
如果登录失败,返回失败的原因,示例如下
{
"ret": 1,
"msg": "用户名或者密码错误"
}
ret 不为 0 表示登录失败, msg字段描述登录失败的原因
补充:
API接口消息体常见的就3种格式:
- x-www-form-urlencoded格式
- json格式
- xml(用的少)
x-www-form-urlencoded格式就类似于这种:username=admin&password=123456
参数名和参数值用等号,然后不同参数名用&连接,如果参数里面有&
,那为了转义,要用Unicode的编码
在mgr目录下创建一个sign_in_out.py,用来处理管理员的登录和登出的API请求。
数据库中的密码是加密过的,并非明文显示,因此就把请求参数里面的用户名、密码取出来, 把密码加密之后和数据库中记录的用户名密码进行比对,和数据库中记录的一致就认为是认证通过,否则就是不通过。
Django中有个内置app 名为 django.contrib.auth
,缺省包含在项目Installed App设置中。这个app的models定义中包含了一张用户表,名为 auth_user 。在执行 migrate 创建数据库表时,auth_user表已经创建好了。
django.contrib.auth
这个app已经做好了登录验证功能:authenticate
,只需要使用这个app库里面的方法就可以了。
Django的相关文档
mgr/sign_in_out.py:
from django.http import JsonResponse
from django.contrib.auth import authenticate, login, logout
# 登录处理
def signin(request):
# 从HTTP POST 请求中获取用户名、密码参数,操作类似于字典,get(名字)就能获取值
userName = request.POST.get('username')
passWord = request.POST.get('password')
# 使用Django.contrib.auth 库里面的方法校验用户名、密码
user = authenticate(username=userName, password=passWord)
# 如果能找到用户,并且密码正确
if user is not None:
if user.is_active:
if user.is_superuser:
# login把当前用户设置为登录状态,也是auth库中的
login(request, user)
# 在session中存入用户类型,数据库中有Django_session这张表,存储每次登录的信息
request.session['usertype'] = 'mgr'
return JsonResponse({'ret': 0})
else:
return JsonResponse({'ret': 1, 'msg': '请使用管理员账户登录'})
else:
return JsonResponse({'ret': 0, 'msg': '用户已经被禁用'})
# 否则就是用户名、密码有误
else:
return JsonResponse({'ret': 1, 'msg': '用户名或者密码错误'})
# 登出处理
def signout(request):
# 使用登出方法 把session中的数据改为登出的状态
logout(request)
return JsonResponse({'ret': 0})
浏览器登陆登录页面的url是 127.0.0.1/mgr/sign.html
根据接口,管理员登录的API 路径是 /api/mgr/signin
我们已经在总路由文件 urls.py中添加了如下路由记录:
# 凡是 url 以 api/mgr 开头的,
# 都根据 mgr.urls 里面的 子路由表进行路由
path('api/mgr/', include('mgr.urls')),
在mgr\urls.py 里添加如下内容:
from django.urls import path
from mgr import sign_in_out
urlpatterns = [
path('signin', sign_in_out.signin),
path('signout', sign_in_out.signout),
]
这样就表示:
如果有HTTP请求 url是 /api/mgr/signin 就由 sign_in_out.py 里面的signin 函数处理,
如果有HTTP请求 url是 /api/mgr/signout 就由 sign_in_out.py 里面的signout 函数处理。
测试代码:
前面的测试是前端人员已经开发好了前端部分,然后集成,再进行测试。然而事实上工作进度的不同,可能后端已经完成了但前端没有完成,那有没有办法后端进行独立的测试呢?
测试也就是通过API接口传数据,发送HTTP请求,我们可以使用测试工具,例如postman,也可以使用 requests库构建登录请求HTTP消息, 并且检查响应,看看是否能登录成功。
点击这里参考一下白月黑羽教程requests库的使用
注意: 测试的过程中服务器的服务要一直在跑才行
在根目录下创建一个tests文件夹,用于测试
在tests下创建一个tc001.py,测试一下列出客户信息的功能:
tests\tc001.py:
# 测试列出客户信息
import requests, pprint
response = requests.get('http://127.0.0.1:8080/api/mgr/customers?action=list_customer')
pprint.pprint(response.json())
控制台返回的信息可以看出,测试是成功的
测试登录功能:
# 测试管理员登录
import requests, pprint
# payload 就是定义好的,要放到消息体中的参数
# http请求消息体中参数格式 x-www-form-urlencoded,就构建一个字典
payload = {
'username': 'cwtnice',
'password': '12345678'
}
# post方法,并填入data参数后,会自动把payload按照x-www-form-urlencoded格式填入消息体,发送给服务端
response = requests.post('http://127.0.0.1:8080/api/mgr/signin', data=payload)
# json()方法把json字符串变为python的字典对象
pprint.pprint(response.json())
注意: 参数在消息体中,用data=
,要是参数在url中,用params=
ret的值为0表示成功,如果密码不正确也会返回对应的错误信息。
注意,如果报requests.exceptions.InvalidSchema: No connection adapters were found for 'xxxx'
错了,需要在加上http://