Skip to content

Cypress - 断言

断言(Assertions)是测试的根本部分,因为它们用于验证应用程序是否处于预期的状态。Cypress 集成了 Chai 断言库,提供了强大且易于阅读的方式来进行断言。它还包含了 Sinon-Chai,用于对 spies(间谍)、stubs(存根)和 clocks(时钟)进行断言;以及 jQuery-Chai,用于执行特定于 jQuery 的断言。

Cypress 断言大致可分为隐式断言(Implicit Assertions)和显式断言(Explicit Assertions)。

隐式断言(使用 .should() 和 .and())

Section titled “隐式断言(使用 .should() 和 .and())”

隐式断言应用于命令链中上一个 Cypress 命令返回的“主题”(subject)。最常用的隐式断言命令是 .should() 及其别名 .and()。这些命令会自动重试,直到断言通过或达到超时时间为止。

隐式断言示例:

describe('Implicit Assertions Example', function() {
it('Validates element properties', function() {
cy.visit('https://example.cypress.io/commands/assertions');
cy.get('.assertion-table tbody tr').eq(2)
.should('have.class', 'success') // Asserts class on the <tr>
.find('td').eq(1) // Now the subject is the second <td>
.should('have.text', 'Column content') // Asserts text content of the <td>
.and('contain', 'content') // Alias for .should(), still on the same <td>
.and('not.contain', 'Foobar');
// Asserting on multiple list items
cy.get('.assertion-list li')
.should('have.length', 3) // Asserts number of <li> elements
.and('include.text', 'List item 1'); // Checks if any li contains this text
});
});

隐式断言的执行结果:

命令日志(Command Log)将显示每个断言通过的情况。如果一个断言在重试后失败,测试将在该步骤失败,并突出显示失败的断言及其原因。

显式断言(使用 expect() 和 assert())

Section titled “显式断言(使用 expect() 和 assert())”

显式断言允许你直接对特定值或对象进行断言。通常使用 Chai 的 expect(BDD 风格)或 assert(TDD 风格)来实现。这些断言常用于 .then() 回调函数中,在其中你可以直接访问返回的主题(subject)或值。

显式断言示例:

describe('Explicit Assertions Example', function() {
it('Uses expect and assert', function() {
cy.visit('https://example.cypress.io/commands/querying');
// Using expect
cy.get('#query-btn').then(($button) => {
const buttonText = $button.text();
expect(buttonText).to.equal('Button');
expect($button).to.have.class('query-btn');
expect($button).not.to.be.disabled;
});
// Using assert (less common in Cypress tests but available)
const person = { name: 'Joe', age: 20 };
assert.isObject(person, 'person is an object');
assert.equal(person.name, 'Joe', 'name should be Joe');
// Example with a simple variable
const myVar = true;
expect(myVar).to.be.true;
});
});

显式断言的执行结果:

命令日志(Command Log)将显示 .then() 等步骤。断言本身(expect/assert)不会创建新的日志条目,但如果它们在 .then() 回调中不通过,将导致测试失败。

Cypress 的许多命令也内置了默认断言(Default Assertions)。例如:

  • cy.visit(): 期望页面发送 text/html 内容且状态码为 200。
  • cy.request(): 期望远程服务器存在并提供响应。
  • cy.get(): 期望元素存在于 DOM 中(会重试直到元素出现或超时)。
  • cy.contains(): 期望最终在 DOM 中出现包含指定内容的元素。
  • .find(): 期望元素存在于当前主题(subject)中。
  • .type(): 期望元素处于可输入状态。
  • .click(): 期望元素处于可操作状态(例如,可见、未禁用)。

以下是一些你经常会与 .should() 或 expect() 一起使用的常见 Chai 断言:

检查上一个命令返回的元素数量。

cy.get('ul > li').should('have.length', 3);

检查元素是否具有特定的 CSS 类名。

cy.get('button.primary').should('have.class', 'active');
cy.get('button.primary').should('not.have.class', 'disabled');

检查 input、textarea 或 select 元素的值。

cy.get('input[name="email"]').type('test@example.com').should('have.value', 'test@example.com');

检查元素的文本内容。have.text 要求完全匹配,contain.text 或 include.text 检查是否包含部分文本。

cy.get('h1').should('have.text', 'Welcome!');
cy.get('p').should('contain.text', 'important information'); // alias for include.text

检查元素对用户是否可见或隐藏。

cy.get('.modal').should('be.visible');
cy.get('.tooltip').should('not.be.visible');

检查元素是否存在于 DOM 中。

cy.get('#loading-spinner').should('not.exist');
cy.get('main#content').should('exist');

检查元素是否具有特定的 CSS 属性和值。

cy.get('.error-message').should('have.css', 'color', 'rgb(255, 0, 0)'); // Color can be hex, rgb, etc.
cy.get('button').should('have.css', 'display', 'block');
  • be.disabled / be.enabled: 检查元素(如按钮或输入框)是否被禁用或启用。
  • be.checked / not.be.checked: 用于复选框或单选按钮。
  • have.attr / not.have.attr: 检查属性是否存在或具有特定值(例如,href、data-testid)。
  • match: 断言主题(subject)匹配某个正则表达式。

常见学习障碍:知道何时使用隐式断言 vs. 显式断言。通常,对于返回 DOM 元素的命令,优先使用隐式断言(.should()),因为它们内置了重试机制。当你需要在 .then() 回调中直接使用返回的值或执行更复杂的逻辑时,使用显式断言(expect())。

有关 Chai 断言的完整列表,请参阅 Chai.js 文档:[https://www.chaijs.com/api/]