作者:蒙奇D
描述:Cypress上提供的4个Courses学习,介绍cypress的使用方式,测试的基本观点,以及Cypress的API、Commands...
Cypress的使用
Cypress桌面程序
//会打开页面
npx cypress open
cypress API
cy.get('button')
cy.request('/users/1').its('body')
cypress 是chain function
task
cy.task('seed:db',{})
on('task',{
'seed:db':data=>{
return ''
}
})
cy.window().then(win=>win.app.$store)
Stubbing Network Response with Fixtures
cy.server()
cy.route('GET','/tweets*','fixture:tweets')
.as('tweets')
cy.wait().its()
cypress CLI终端
//不会打开浏览器页面
npx cypress run
npx cypress run --record
测试基础(用例for what?)
场景一:给现有的项目加测试用例
将原文翻译成中文是:
如果您尝试测试现有的应用程序,我们建议您首先为应用程序中最 “关键任务” 的部分编写测试。 我们所说的“关键任务”是指应用程序中不会出现故障或损坏的任何部分。 例如,登录/身份验证、购买产品、处理信用卡、注册表单等。我们建议您的第一套测试应该针对应用程序的这些部分,并且它们应该是端到端测试 。
并且使用"User Journeys"方式模拟用户操作步骤,测试完整的场景
场景二:开发新功能
将原文翻译成中文是:
当您实现新功能时,为该功能编写测试的一个有用技巧是首先从最终目标开始。 这个功能具体需要做什么? 它解决什么问题? 一旦理解了这一点,您就可以将该功能分解为小的增量步骤,所有这些都可以转化为测试。
简而言之就是,先从最终目标开始逐步细分
场景三:改bug
将原文翻译成中文是:
强烈建议您围绕应用程序中出现的任何错误编写测试。 一个好的方法是首先围绕故障编写期望正确的测试,此时测试用例执行会失败。 一旦错误被修复,您的测试就会通过,这将验证您的新代码是否已经消除了错误。
这样,您的测试将有助于确保该错误将来永远不会再出现。
voyage%r=zhang.ran130@zte.com.cn,r=chen.bo222@zte.com.cn,r=tao.ran@zte.com.cn,r=yin.peipei@zte.com.cn,r=mo.jianfei@zte.com.cn,r=li.zhongwei160@zte.com.cn,r=ma.xiaoting@zte.com.cn
cypress基础知识
Cypress 是基于Mocha构建
Cypress 原生依赖 Lodash,可以直接使用
异步特性
-
1.cy.commands不返回任何东西。所以把链式调用用变量拆开不可行的
// THIS WILL NOT WORK const button = cy.get("button") button.click()
commands are asynchronous and get queued for execution at a later time.
- 2.then()是cypress自己的命令,不支持async/await
-
get里then返回的btn)才能执行交互。比如
cy.get("button").then(($btn) => { const cls = $btn.attr("class") cy.wrap($btn).click().should("not.have.class", cls) })
waiting&retry
别名:
// Create an alias using the `as()` Cypress Command
cy.get("table").find("tr").as("rows")
// 获取
cy.get("@rows")
- 等待 接口返回
cy.request("POST", "/users").as("signup") // creating the signup alias
cy.wait("@signup") // waiting upon the signup alias
调试
1.cypressUI页面上点击断言步骤,在控制台会打印get的真实的数据
2.在命令终端里 使用cy.screenshot可以记录快照
3.cy.log()可以在UI页面打印日志
4.console.log()可以在UI页面的控制台里打印日志
5.浏览器的开发者工具可以正常使用,正常的浏览器调试
使用JS写测试用例
由于cypress测试用例就是以js代码运行在浏览器上,所以可以使用JS甚至loadsh动态生产测试用例
_.each(feedViews, (feed, feedName) => {
if('',()=>{
//something
})
})
const comments = ["Thank you!", "Appreciate it."]
comments.forEach((comment, index) => {
cy.getBySelLike("comment-input").type(`${comment}{enter}`)
cy.getBySelLike("comments-list").children().eq(index).contains(comment)
})
cypress 高级概念
测试数据
- 测试数据脚本
- Faker模拟数据
持续集成(CI)中使用Cypress
拦截网络请求
拦截
//拦截对/users路由的任何POST请求
cy.intercept("POST", "/users")
//拦截对任何与 /transactions/public *匹配的路由的GET请求
beforeEach(() => {
cy.intercept("GET", "/transactions/public*").as("publicTransactions")
})
使用fixture覆盖返回体
//拦截并覆盖数据
cy.intercept("GET", "/transactions/public*", {
// ...
fixture: "public-transactions.json",
}).as("mockedPublicTransactions")
更改响应头
响应中的原始标头将保持不变。这些新标头将附加到原始标头中。
cy.intercept("GET", "/transactions/public*", {
headers: {
"X-Powered-By": "Express",
Date: new Date().toString(),
},
})
修改响应数据:
我们需要使用.continue()来修改响应数据。
cy.intercept("POST", "/bankaccounts", (req) => {
const { body } = req
req.continue((res) => {
res.body.data.listBankAccount = []
})
})
检查请求
cy.intercept("POST", apiGraphQL, (req) => {
const { body } = req
if (
body.hasOwnProperty("operationName") &&
body.operationName === "CreateBankAccount"
) {
req.alias = "gqlCreateBankAccountMutation"
}
})
同步等待请求
cy.intercept('POST', '/users').as('signup');
cy.wait('@signup')
API 和集成测试
RWA:真实世界应用程序
发起请求
// cypress/tests/api/api-users.spec.ts
context("GET /users", () => {
it("gets a list of users", () => {
cy.request("GET", "/users").then((response) => {
expect(response.status).to.eq(200)
expect(response.body.results).length.to.be.greaterThan(1)
})
})
})
自定义命令
cypress.command可以支持自定义命令
声明自定义命令:
Cypress.Commands.add("loginByApi", (username, password) => {
return cy.request("POST", `http://localhost:3000/login`, {
username,
password,
})
})
使用自定义命令:
describe("POST /login", () => {
it("login as user", () => {
cy.loginByApi("jdoe", "password123").then((response) => {
expect(response.status).to.eq(200)
})
})
})
视口和浏览器测试技巧
在多个浏览器和各种屏幕尺寸中运行所有测试非常重要。目前,Cypress 支持Chrome 系列浏览器(包括基于 Electron 和 Chromium 的 Microsoft Edge)、WebKit(Safari 的浏览器引擎,目前在 Cypress 中处于实验状态)和 Firefox。
指定运行浏览器
1.ci命令里设置参数
--browser
cypress run --browser Firefox
2.UI页面里选择参数
3.测试用例里
//对位于describe()块内的所有测试执行此操作
describe("happy path suite", { browser: "firefox" }, () => {
it("...")
it("...")
it("...")
})
//或者
// Run the test if Cypress is run via Chrome
it('Show warning outside Chrome', { browser: 'chrome' }, () => {
// ...
})
测试手机
默认情况下,RWA 中的所有测试都是为桌面编写的。在 中package.json
,我们有自定义脚本来启动具有移动维度的 Cypress。
1.ci设置参数--config
"cypress:open:mobile": "cypress open --config viewportWidth=375,viewportHeight=667",
"cypress:run:mobile": "cypress run --config viewportWidth=375,viewportHeight=667",
2.实用函数isMobile()
export const isMobile = () => {
return (
Cypress.config("viewportWidth") <
Cypress.env("mobileViewportWidthBreakpoint")
)
}
//环境变量mobileViewportWidthBreakpoint位于cypress.json配置文件中。
{
// ...
"env": {
"apiUrl": "http://localhost:3001",
"mobileViewportWidthBreakpoint": 414,
"coverage": false,
"codeCoverage": {
"url": "http://localhost:3001/__coverage__"
}
},
"experimentalStudio": true
}
cypress Method
-
its(属性|下标,options)从数组或者对象里取值
cy.wrap({ age: 52 }).its("age").should("eq", 52) // true
-
invoke(options?,functionName,args...?) 在JS 数据类型上调用 JS 函数。
cy.wrap(["Wai Yan", "Yu"]).invoke("slice", 0, 1)
-
request()发起http请求
数据驱动测试
可以自定义模拟数据甚至请求真实的数据来进行测试,这种方式比硬编码数据有以下几个好处:
1.更接近真实用户的交互
2.比硬编码数据维护更简单