Cypress系列(101)- intercept() 命令详解
如果想从头学起Cypress,可以看下面的系列文章哦
https://www.cnblogs.com/poloyy/category/1768839.html
作用
使用该命令在网络层管理 HTTP 请求的行为
包含以下功能
- 对任何类型的 HTTP 请求进行 stub 或 spy
- 在 HTTP 请求发送到目标服务器前,可以修改 HTTP 请求 body、headers、URL(类似抓包工具对请求进行打断点然后修改)
- 动态或静态地对 HTTP 请求的响应进行 stub
- 接收 HTTP 响应后可对 HTTP 响应 body、headers、status、code 进行修改(类似抓包工具对响应进行打断点然后修改)
- 在所有阶段都可以完全访问所有 HTTP 请求
相较于 cy.route() 的不同
cy.route() 命令详解:https://www.cnblogs.com/poloyy/p/13852941.html
- 可以拦截所有类型的网络请求,包括 Fetch API,页面加载,XMLHttpRequest,资源加载等
- 不需要在使用前调用 cy.server() ,实际上 cy.server() 根本不影响 cy.intercept()
- 默认情况下没有将请求方法设置为 GET
语法格式
cy.intercept(url, routeHandler?)
cy.intercept(method, url, routeHandler?)
cy.intercept(routeMatcher, routeHandler?)
url
要匹配的请求 URL ,可以是字符串也可以是正则表达式
cy.intercept('http://example.com/widgets')
cy.intercept('http://example.com/widgets', { fixture: 'widgets.json' })
没有指定请求方法的话,可以匹配任意类型的请求方法
method
请求方法
cy.intercept('POST', 'http://example.com/widgets', {
statusCode: 200,
body: 'it worked!'
})
routeMatcher
- 它是一个对象
- 用于匹配此路由将处理哪些传入的 HTTP 请求
- 所有对象属性都是可选的,不是必填的
- 设置的所有属性必须与路由匹配才能处理请求
- 如果将字符串传递给任何属性,则将使用 minimatch 将与请求进行全局匹配
它有以下属性
{
/**
* 与 HTTP Basic身份验证中使用的用户名和密码匹配
*/
auth?: { username: string | RegExp, password: string | RegExp } /**
* 与请求上的 HTTP Headers 匹配
*/
headers?: {
[name: string]: string | RegExp
} /**
* 与请求上的 hostname 匹配
*/
hostname?: string | RegExp /**
* If 'true', 只有 https 的请求会被匹配
* If 'false', 只有 http 的请求会被匹配
*/
https?: boolean /**
* 与请求上的 method 请求方法匹配
* 默认 '*', 匹配全部类型的 method
*/
method?: string | RegExp /**
* 主机名后的路径, 包括了 ? 后面的查询参数
* www.baidu.com/s?wd=2
*/
path?: string | RegExp /**
* 和 path 一样, 不过不管 ? 后面的查询参数
* www.baidu.com/s
*/
pathname?: string | RegExp /**
* 与指定的端口匹配, 或者传递多个端口组成的数组, 其中一个匹配上就行了
*/
port?: number | number[] /**
* 与请求路径 ? 后面跟的查询参数匹配上
* wd=2
*/
query?: {
[key: string]: string | RegExp
} /**
* 完整的请求 url
* http://www.baidu.com/s?wd=2
*/
url?: string | RegExp
}
routeHandler
- routeHandler 定义了如果请求和 routeMatcher 匹配将对请求进行的指定的处理
- 可接受的数据类型:string、object、Function、StaticResponse
StaticResponse
- 相当于一个自定义响应体对象
- 可以自定义 Response headers、HTTP 状态码、Response body 等
- 详细栗子将在后面展开讲解
StaticResponse 对象的属性
{
/**
* 将 fixture 文件作为响应主体, 以 cypress/fixtures 为根目录
*/
fixture?: string
/**
* 将字符串或 JSON 对象作为响应主体
*/
body?: string | object | object[]
/**
* 响应 headers
* @default {}
*/
headers?: { [key: string]: string }
/**
* 响应状态码
* @default 200
*/
statusCode?: number
/**
* 如果 true, Cypress 将破坏网络连接, 并且不发送任何响应
* 主要用于模拟无法访问的服务器
* 请勿与其他选项结合使用
*/
forceNetworkError?: boolean
/**
* 发送响应前要延迟的毫秒数
*/
delayMs?: number
/**
* 以多少 kbps 发送响应体
*/
throttleKbps?: number
}
string
- 如果传递一个字符串,这个值相当于响应 body 的值
- 等价于 StaticResponse 对象 { body: "foo" }
object
- 如果传递了没有 StaticResponse 密钥的对象,则它将作为 JSON 响应 Body 发送
- 例如, {foo:'bar'} 等价于 StaticResponse 对象 {body:{foo:'bar'}}
function
- 如果传递了一个回调函数,当一个请求匹配上了该路由将会自动调用这个函数
- 函数第一个参数是请求对象
- 在回调函数内部,可以修改外发请求、发送响应、访问实际响应
- 详细栗子将在后面展开讲解
命令返回结果
- 返回 null
- 可以链接 as() 进行别名,但不可链接其他命令
- 可以使用 cy.wait() 等待 cy.intercept() 路由匹配上请求,这将会产生一个对象,包含匹配上的请求/响应相关信息
实际栗子的前置准备
Cypress 官方项目的下载地址:https://github.com/cypress-io/cypress-example-kitchensink
下载好后进入下图项目文件夹
启动项目
npm start
通过 URL 路由匹配请求的栗子
测试代码
等价于 route() 的测试代码
注: route() 未来将会被弃用
运行结果
登录请求匹配上了路由
Console 查看 cy.wait() 返回的对象
最重要的当然是 request 和 response 两个属性
通过 RouteMatcher 路由匹配请求的栗子
测试代码
断言请求体和响应状态码
运行结果
Console 查看 cy.wait() 返回的对象
另一种断言方式
// 断言匹配此路由的请求接收到包含【username】的请求 body
cy.wait('@login3').its('request.body').should('have.property', 'username') // 断言匹配此路由的请求接收到 HTTP 状态码为 500
cy.wait('@login3').its('response.statusCode').should('eq', 200) // 断言匹配此路由的请求接收到包含【redirect】的请求 body
cy.wait('@login3').its('response.body').should('have.property', 'redirect')
不过这样的话只能每次写一条不能同时三条都写,所以还是建议像代码图一样,先 .then() 再进行断言
自定义不同类型的响应体的各种栗子
自定义一个纯字符串的响应体
测试代码
运行结果
接口响应
自定义一个 JSON 的响应体
测试代码
会从cypress安装目录/fixtures 下读取对应的数据文件,它会变成响应 body 的数据
test.json 数据文件
运行结果
接口响应
自定义一个 StaticResponse 的响应体
测试代码
自定义了响应body、statusCode,还有返回响应的延时时间
运行结果
延时生效了
body 和 statusCode 变成自定义的数据了
拦截请求的栗子
前置操作
beforeEach(() => {
cy.visit('http://localhost:7079/login')
})
断言请求的栗子
测试代码
运行结果
Console 查看打印结果
可以看到回调函数只有一个参数,就是 request 参数
重点
回调函数内不能包含 cy.**() 的命令,如果包含会报错
简单来说就是
cy.type() 命令执行完后会返回一个 promise 对象,同时又会调用回调函数,而回调函数内又调用了 cy.get() 返回了一个 promise 对象,Cypress 会将这种情况当做测试失败处理
将请求传递给下一个路由处理程序
前言
意思就是一个请求可以同时匹配上多个路由
测试代码
运行结果
一个登录请求匹配成功了两个路由,且回调函数会按匹配的顺序执行
总结
回调函数的参数就是一个请求对象,它其实可以调用以下方法
{
/**
* 销毁该请求并返回网络错误的响应
*/
destroy(): void /**
* 控制请求的响应
* 如果传入的是一个函数, 则它是回调函数, 当响应时会调用
* 如果传入的是一个 StaticResponse 对象, 将不会发出请求, 而是直接将这个对象当做响应返回
*/
reply(interceptor?: StaticResponse | HttpResponseInterceptor): void /**
* 使用 response body(必填) 和 response header(可选) 响应请求
*/
reply(body: string | object, headers?: { [key: string]: string }): void /**
* 使用 HTTP 状态码(必填)、 response body(可选)、response header(可选) 响应请求
*/
reply(status: number, body?: string | object, headers?: { [key: string]: string }): void /**
* 重定向到新的 location 来响应请求,
* @param statusCode 用来重定向的 HTTP 状态代码, Default: 302
*/
redirect(location: string, statusCode?: number): void
}
拦截响应的栗子
req.reply() 函数详解
前言
可以使用 req.reply() 函数来动态控制对请求的响应
使用讲解
cy.intercept('/login', (req) => {
// functions on 'req' can be used to dynamically respond to a request here // 将请求发送到目标服务器
req.reply() // 将这个 JSON 对象响应请求
req.reply({plan: 'starter'}) // 将请求发送到目标服务器, 并且拦截服务器返回的实际响应, 然后进行后续操作(类似抓包工具对响应打断点)
req.reply((res) => {
// res 就是实际的响应对象
})
})
.reply() 直接修改响应的栗子
测试代码
接口响应内容
拦截响应的小栗子
测试代码
运行结果
Console 查看打印结果
一个是 request 对象,一个是 response 对象
自定义响应内容
前言
- 可以使用 resp.send() 函数动态控制传入的响应
- 另外,当响应发送到浏览器时,对 resp 的任何修改都将保留
- 如果尚未调用 resp.send() ,则它会在 req.reply() 回调函数完成后隐式调用
使用讲解
cy.intercept('/notification', (req) => {
req.reply((resp) => {
// Success 将作为 response body 返回到浏览器
resp.send('Success') // 将 success.json 里面的数据作为 response body 返回到浏览器
resp.send({fixture: 'success.json'}) // 将响应延迟 1000ms
resp.delay(1000) // 将响应限制为 64kbps
resp.throttle(64)
})
})
传递字符串作为响应内容
测试代码
接口响应内容
传递 JSON 对象作为响应内容
测试代码
接口响应内容
传递 StaticResponse 对象作为响应内容
测试代码
接口响应内容
resp 可调用的函数总结
{
/**
* 可以自定义 response statusCode、response body、response header
* 也可以直接传 StaticResponse 对象
*/
send(status: number, body?: string | number | object, headers?: { [key: string]: string }): void
send(body: string | object, headers?: { [key: string]: string }): void
send(staticResponse: StaticResponse): void
/**
* 继续返回响应
*/
send(): void
/**
* 等待 delayMs 毫秒,然后再将响应发送给客户端
*/
delay: (delayMs: number) => IncomingHttpResponse
/**
* 以多少 kbps 的速度发送响应
*/
throttle: (throttleKbps: number) => IncomingHttpResponse
}
Cypress系列(101)- intercept() 命令详解的更多相关文章
- Hexo系列(三) 常用命令详解
Hexo 框架可以帮助我们快速创建一个属于自己的博客网站,熟悉 Hexo 框架提供的命令有利于我们管理博客 1.hexo init hexo init 命令用于初始化本地文件夹为网站的根目录 $ he ...
- Android Studio系列教程五--Gradle命令详解与导入第三方包
Android Studio系列教程五--Gradle命令详解与导入第三方包 2015 年 01 月 05 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://s ...
- Python操作redis系列以 哈希(Hash)命令详解(四)
# -*- coding: utf-8 -*- import redis #这个redis不能用,请根据自己的需要修改 r =redis.Redis(host=") 1. Hset 命令用于 ...
- Linux Shell系列教程之(八)Shell printf命令详解
本文是Linux Shell系列教程的第(八)篇,更多shell教程请看:Linux Shell系列教程 在上一篇:Linux Shell系列教程之(七)Shell输出这篇文章中,已经对Shell p ...
- pssh系列命令详解
安装 pssh提供OpenSSH和相关工具的并行版本.包括pssh,pscp,prsync,pnuke和pslurp.该项目包括psshlib,可以在自定义应用程序中使用.pssh是python写的可 ...
- Linux上的free命令详解、swap机制
Linux上的free命令详解 解释一下Linux上free命令的输出. 下面是free的运行结果,一共有4行.为了方便说明,我加上了列号.这样可以把free的输出看成一个二维数组FO(Free ...
- Linux netstat命令详解
Linux netstat命令详解 一 简介 Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多 ...
- linux sort,uniq,cut,wc命令详解
linux sort,uniq,cut,wc命令详解 sort sort 命令对 File 参数指定的文件中的行排序,并将结果写到标准输出.如果 File 参数指定多个文件,那么 sort 命令将这些 ...
- Linux下的压缩zip,解压缩unzip命令详解及实例
实例:压缩服务器上当前目录的内容为xxx.zip文件 zip -r xxx.zip ./* 解压zip文件到当前目录 unzip filename.zip ====================== ...
随机推荐
- POI做题记录
嘿嘿,偷学一波! 由于博主做的题比较少,所以没按年份整理,直接按照做题时间放上来了. 2020年9月20日 [POI2013]LUK-Triumphal arch 给你一颗\(n\)个点的树(\(n\ ...
- SAM学习笔记&AC自动机复习
形势所迫,一个对字符串深恶痛绝的鸽子又来更新了. SAM 后缀自动机就是一个对于字符串所有后缀所建立起的自动机.一些优良的性质可以使其完成很多字符串的问题. 其核心主要在于每个节点的状态和$endpo ...
- Ubuntu 18.04 Java JDK/JRE 安装命令
安装默认版本 sudo apt install default-jdk Java 8 sudo apt install openjdk-8-jdk 如果我们在服务器上安装了多个Java版本,我们可以使 ...
- LeetCode 热题 HOT 100(05,正则表达式匹配)
LeetCode 热题 HOT 100(05,正则表达式匹配) 不够优秀,发量尚多,千锤百炼,方可成佛. 算法的重要性不言而喻,无论你是研究者,还是最近比较火热的IT 打工人,都理应需要一定的算法能力 ...
- spark推测机制及参数设置
推测执行机制 推测任务是指对于一个Stage里面拖后腿的Task,会在其他节点的Executor上再次启动这个task,如果其中一个Task实例运行成功则将这个最先完成的Task的计算结果作为最终结果 ...
- Dem地形数据转换为cass支持的dat格式教程
一.获取dem数据各类精度的dem高程数据下载这里不赘述,可以查阅这篇文章:高程数据下载 这里我们以12.5m精度的dem为例进行转换: 二.将dem数据转换为文本我们这里先将地形数据加载入globa ...
- 程序员注意【自verycd.com的JavaAmg77 】
展望未来,总结过去10年的程序员生涯,给程序员小弟弟小妹妹们的一些总结性忠告 走过的路,回忆起来是那么曲折,把自己的一些心得体会分享给程序员兄弟姐妹们,虽然时代在变化,但是很可能你也会走我已经做过的1 ...
- 虚拟DOM与diff算法
虚拟DOM与diff算法 虚拟DOM 在DOM操作中哪怕我们的数据,发生了一丢丢的变化,也会被强制重建整预DOM树.这么做,涉及到很多元素的重绘和重排,导致性能浪费严重 只要实现按需更新页面上的元素即 ...
- 线程与更新UI,消除偏见,细谈原理
前言 相信不少读者都阅读过相类似的文章了,但是我还是想完整的把这之间的关系梳理清楚,细节聊好,希望你也能从中学到一些. 进入正题,大家应该都听过这样一句话--"UI更新要在主线程,子线程更新 ...
- 第14章——高级IO函数
1.套接字超时 套接字IO函数设置超时的方法有三种: (1)调用alarm. (2)select (3)使用SO_RECTIMEO和 SO_SNDTIMEO 选项 上面三种方法适用于输入输出操作(re ...