通过一个简单的例子,了解 Cypress 的运行原理

举报
汪子熙 发表于 2022/05/18 12:19:37 2022/05/18
【摘要】 Cypress 是 SAP Spartacus 前端 e2e 测试使用的框架。Cypress 并不是广义上的 web 自动化工具,并不适合编写脚本来测试已经处于生产状态下的不受测试者控制的网站。Cypress is not a general purpose web automation tool. It is poorly suited for scripting live, produc...

Cypress 是 SAP Spartacus 前端 e2e 测试使用的框架。

Cypress 并不是广义上的 web 自动化工具,并不适合编写脚本来测试已经处于生产状态下的不受测试者控制的网站。

Cypress is not a general purpose web automation tool. It is poorly suited for scripting live, production websites not under your control.

https://docs.cypress.io/guides/getting-started/writing-your-first-test#Step-1-Visit-a-page

After a test function is finished running, Cypress goes to work executing the commands that were enqueued using the cy.* command chains.

等到 Cypress 所有的测试函数都结束运行后,Cypress 才开始执行之前通过 cy.* 命令放到任务队列中的指令。

这个简单的 Cypress 测试程序,源代码如下:

/// <reference types="Cypress" />

describe('My First Test', () => {
  it('finds the content "type"', () => {
    cy.visit('https://example.cypress.io')

    cy.contains('type').click();

    cy.url().should('include', '/commands/actions');

    cy.get('.action-email')
      .type('jerry@email.com')
      .should('have.value', 'jerry@email.com');
  })
})

测试结果如下:

逐行语句分析

1. describe 语句

describe 是一个 Mocha.SuiteFunction 函数,接受字符串 title 和箭头函数作为输入参数。返回 Mocha.Suite 实例。该 describe 函数仅当被 mocha CLI 调用时才可用。

2. it

定义一个 test specification(也称 test case),回调函数为测试主程序的执行代码。

3. cy.visit

访问指定的 url.

命令的帮助文档:

https://docs.cypress.io/api/commands/visit

当 visit 参数指定的 url 对应的页面结束加载后,会 yield 一个 windows 对象:

cy.visit('/') // yields the window object
  .its('navigator.language') // yields window.navigator.language
  .should('equal', 'en-US') // asserts the expected value

its 方法:取得调用对象指定参数的值。

例子:

cy.wrap({ width: '50' }).its('width') // Get the 'width' property
cy.window().its('sessionStorage') // Get the 'sessionStorage' property

参考其帮助文档:

https://docs.cypress.io/api/commands/its

cy.visit() 的执行细节:

Cypress automatically detects things like a page transition event and will automatically halt running commands until the next page has finished loading.

Cypress 自动检测诸如 page transition 类型的事件,如果 cy.visit 待访问的页面没有加载完毕,则不会继续执行指令。

Had the next page not finished its loading phase, Cypress would have ended the test and presented an error.

如果 cy.visit 的页面最终无法完成加载, Cypress 会停止测试,抛出错误消息。

Under the hood - this means you don’t have to worry about commands accidentally running against a stale page, nor do you have to worry about running commands against a partially loaded page.

这使得我们完全不用担心,我们书写的 Cypress 程序里的指令,会运行在一个正在加载中的页面。

We mentioned previously that Cypress waited 4 seconds before timing out finding a DOM element - but in this case, when Cypress detects a page transition event it automatically increases the timeout to 60 seconds for the single PAGE LOAD event.

Cypress 指令查找 DOM 元素的超时时间是 4 秒,而 Cypress 等待 cy.visit 加载页面完成时,超时时间自动修改成了 60 秒。

4. cy.contains(‘type’)

Get the DOM element containing the text.

查找 DOM 树中包含 type 文本的元素。

如下图所示:

打开 Chrome 开发者工具,可以查看到该指令执行后返回的结果:

下面这个例子,待测试的 HTML 如下图所示:

<ul>
  <li>apples</li>
  <li>oranges</li>
  <li>bananas</li>
</ul>

下面这行语句:

cy.contains(‘apples’)

生成的 DOM 对象为:

<li>apples</li>

contains 方法可以在一个节点的后代节点里进行查询:

<div id="main">
  <form>
    <div>
      <label>name</label>
      <input name="name" />
    </div>
    <div>
      <label>age</label>
      <input name="age" />
    </div>
    <input type="submit" value="submit the form!" />
  </form>
</div>

查找 input 元素的代码:

cy.get('form').contains('submit the form!').click()

5. click

This command simulates a user interacting with your application. Under the hood, Cypress fires the events a browser would fire thus causing your application’s event bindings to fire.

click 命令模拟应用里的用户点击行为。在底层,Cypress 采取和用户在浏览器上真实点击时抛出 event 的同样方式,来触发应用程序的事件处理函数。

Prior to issuing any of the commands, we check the current state of the DOM and take some actions to ensure the DOM element is “ready” to receive the action.

在 Cypress 执行 click 命令之前,框架会进行 DOM 状态的检查,确保该 DOM 元素真正能够接收点击事件。

在执行 click 命令之前,总共有这些检查和前置事件需要执行:

  • Scroll the element into view.
  • Ensure the element is not hidden.
  • Ensure the element is not disabled.
  • Ensure the element is not detached.
  • Ensure the element is not readonly.
  • Ensure the element is not animating.
  • Ensure the element is not covered.
  • Scroll the page if still covered by an element with fixed position.
  • Fire the event at the desired coordinates.

打开 Chrome 开发者工具,可以观察到 click 指令执行时的屏幕坐标,以及发生的鼠标事件:

6. cy.url

得到当前处于激活状态的页面的 url.

7. cy.url().should(‘include’, ‘/commands/actions’);

7. cy.get(’.action-email’)

使用 get 输入参数里包含的 select,获取指定的 DOM 元素。

结果:得到了包含 .action-email 的 input DOM 元素。

8. type(‘jerry@email.com’)

在第 7 步查询到的 input 字段里,输入指定的字符。

指令帮助文档:

https://docs.cypress.io/api/commands/type#Tabindex

发生的键盘事件如下:

最后的 assert 成功执行:

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。