请求接口
在Cypress中发起HTTP请求需要用到cy.request(),其语法如下
cy.request(url)
cy.request(url, body)
cy.request(method,url)
cy.request(method,url,body)
cy.request(options)
- url是接口地址,同样可以结合cypress.json的baseUrl配置进行使用
- body是请求体
- method是请求方法,默认情况是GET,还可以是POST、PUT、DELETE等
- options是可选项,可以用来改变cy.request()的默认行为
| 参数 | 默认值 | 描述 |
|---|---|---|
| log | True | 在命令日志中显示命令 |
| url | null | 请求的url |
| method | GET | 请求中使用的HTTP方法 |
| auth | null | 添加鉴权标头 |
| body | null | 随请求发送的请求体 |
| failOnStatusCode | true | 返回值不是2XX或3XX的时候,是否直接返回失败 |
| form | false | 是否将body的值转换为url encoded并设置x-www=form-urlencoded标头 |
| gzip | true | 是否接受gzip编码 |
| headers | null | 要发送的额外请求头 |
| qs | null | 把查询参数追加到请求的url之后 |
| retryOnStatusCodeFailure | false | statusCode引发的失败是否自动重试,设置为true,则重试4次 |
| retryOnNetworkFailure | null | 网络问题引发的失败是否自动重试,设置为true,则重试4次 |
| timeout | responseTimeout | 默认timeout时间,可在cypress.json中配置 |
GET请求
//默认访问方式
cy.request('http://www.davieyang.com')
//options方式
cy.request({
method:GET,
url:'http://wwww.davieyang.com'
})
断言返回值
cy.request('http://www.davieyang.com').as('comments')
cy.get('@comments').shnould((response)=>{
expect(response.body).to.hava.length(500)
expcet(response).to.have.property('headers')
expect(response).to.have.property('duration')
})
POST请求
cy.request({
method:'POST',
url:'/login',
failOnStatusCode:false,
form:true,
body:{
username,
password
}
}).then((res)=>{
expcet(res.status).to.be.equal(200)
})
接口鉴权
基于表单的认证(Cookie&Session)
通常情况下基于表单的认证采用Cookie和Session来维持会话状态,当用户登录后,服务端为用户创建一个Session并保存,然后服务端向客户端返回带有SessionID的Cookie,客户端保存此Cookie并在接下来的请求中都带上这个Cookie,之后服务端再收到来自客户端的请求,便将客户端发送的SessionID跟自己保存的SessionID进行对比完成鉴权
对于这种情况,只需要在beforeEach中进行登陆即可,Cypress会通过cypress-session-cookie自动保存Cookie信息,在后续的测试(it)中用户状态将自动保存,直接可以访问鉴权认证的资源
describe('基于表单的认证', function(){
beforeEach(function(){
//login()是自定义的,放在support/commands.js中
cy.login('username', 'password')
})
it('访问需要鉴权才能访问的资源',function(){
cy.visit('/dashboard')
cy.get('h1').should('contain', 'davieyang')
})
})
在之后的需要鉴权的请求中则如下写法所示
request.post('http://xxxx.xxxx.com/xxapi',{
'auth':{
'user':'username',
'pass':'password',
'sendImmediately':'false'
}
})
基于JWT(Json Web Token)的认证
JWT由三个部分组成
- Header:它是一个Json对象,用来描述JWT的元数据(包括声明加密的算法)
- PayLoad:它也是一个Json对象,用来存放实际需要传递的数据,JWT规定了7个官方字段可以选择,当然也可以定义私有字段
- Signature:它是一个签证信息,用来防止数据篡改
base64UrlEncode(header)+"."+base64UrlEncode(payload)+256bit-secret
服务端将base64加密后的Header和Payload以及签证信息拼成字符串,中间用"."隔开,就是JWT,其鉴权的方式是当用户登录成功后,后端服务器生成JWT,并将JWT返回给客户端,客户端将JWT保存在localStorage/sessionStorage中,并在后续每一次请求中将此JWT放在HTTP请求头的Authorization中一起发送,后端收到这种请求后进行验证完成鉴权
describe('基于jwt的认证', function(){
beforeEach(function(){
cy.request('POST', 'http://www.davieyang.com',{
username:'davieyang',
password:'davieyang',
}).then((res)=>{
//获取jwt token并存入localStorage中
window.localStorage.setitem('jwt', res.data.token)
//获取refresh token并存入localStorage中
window.localStorage.setitem('refreshToken', res.data.refreshToken)
})
})
it('访问需要鉴权后才能访问的资源', function(){
cy.visit('/dashboard')
cy.get('h1').should('contain', 'davieyang')
})
})
在后续的请求中如下代码所示
cy.window().then((window)=>{
cy.requet({
method:'POST',
url:'xxxxx.com',
//获取auth
auth:{bearer:window.localStorage.getitem('jwt')},
}).then((reponse)=>{
expect(response.status).to.be.equal(200)
})
})
代码示例
在integration下新建testAPI.js,并写入如下内容
///<reference types="cypress"/>
describe('使用接口直接测试', function(){
const username='davie.yang'
const password = 'davieyang'
it('接口测试', function(){
cy.request({
method:'POST',
url:'login',
form:true,
body:{
username,
password
},
})
cy.request({
method:'GET',
url:'/dashboard'
})
.its('body')
.should('contain', 'davie.yang')
cy.request('/admin')
.its('body')
.should('include', '<h1>Admin</h1>')
})
})
在package.json文件的scripts模块中添加如下内容
"script":{
"aptTest":"../../node_modules/.bin/cypress run --spec './cypress/integration/testAPI.js'"
}
然后运用命令yarn aipTest即可
使用Cypress执行接口测试无需安装其他依赖,并且如果使用交互模式执行的话,还可以在到接口的详细请求信息
本文介绍如何使用Cypress进行HTTP请求的接口测试,包括GET、POST请求的发起及响应断言,还介绍了两种接口鉴权方式:基于表单的认证(Cookie&Session)和基于JWT的认证。
1844





