You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cypress中判断操作完成?解决测试不稳定问题

Cypress E2E测试不稳定问题的解决方案

一、拦截API请求,确保操作完成

你的购物车操作依赖upsertOrder GraphQL mutation,固定等待时间不稳定的核心原因是网络请求耗时不可控。Cypress的cy.intercept可以精准捕获请求,等待响应完成后再执行后续步骤,这是最可靠的方案。

实现方式:

  1. 提前定义拦截规则,给目标请求起别名
  2. 触发操作后,用cy.wait(别名)等待请求完成
  3. 后续操作无需固定等待

购物车测试代码修改:

context("user adds two items of this same type", () => {
  // 拦截upsertOrder请求,精准匹配operationName
  cy.intercept('POST', '/graphql', (req) => {
    if (req.body.operationName === 'upsertOrder') {
      req.alias = 'upsertOrder';
    }
  });

  cy.visit("/products");
  
  // 第一次添加商品
  cy.getByData("add-to-cart-button").first().click();
  cy.wait('@upsertOrder'); // 等待请求响应完成
  cy.getByData("cart-icon").first().should("contain.text", "1");
  
  // 第二次添加商品
  cy.getByData("add-to-cart-button").first().click();
  cy.wait('@upsertOrder');
  cy.visit("/cart");
  cy.getByData("cart-item-quantity").should("contain.text", "2");
});

登录测试优化(解决重定向偶尔失败):

context("User logs in to make a purchase", () => {
  // 拦截登录接口
  cy.intercept('POST', '/auth/login').as('login');
  
  cy.visit("/auth/login");
  cy.getByData("email").type(Cypress.env("login"));
  cy.getByData("password").type(Cypress.env("password"));
  cy.get("form").find("button").click();
  
  cy.wait('@login'); // 确保登录请求完成后再检查重定向
  cy.location().should((loc) => {
    expect(loc.pathname).to.eq("/auth/dashboard");
  });
  cy.get("section").should("contain.text", Cypress.env("login"));
});

二、通过UI或前端状态判断操作完成

你提到的两种方式都可行,适合无法拦截请求的场景:

1. 等待按钮重新启用

按钮在请求期间处于禁用状态,请求完成后恢复可用。直接等待按钮的disabled属性移除:

cy.getByData("add-to-cart-button").first().click();
// 等待按钮不再禁用
cy.getByData("add-to-cart-button").first().should('not.be.disabled');
cy.getByData("cart-icon").first().should("contain.text", "1");

2. 等待clickedItemSlug变为空字符串

如果是React组件内部state,需要先将状态暴露到全局window对象(仅测试环境添加,避免影响生产):

// 在你的React组件中添加(测试环境)
if (process.env.NODE_ENV === 'test') {
  window.clickedItemSlug = clickedItemSlug;
}

然后在测试中等待状态变为空:

cy.getByData("add-to-cart-button").first().click();
// 等待状态清空
cy.window().its('clickedItemSlug').should('eq', '');
cy.getByData("cart-icon").first().should("contain.text", "1");

三、完整优化后测试代码

describe("Logged in user journey", () => {
  it("customer is able to do the full journey from login to purchase", () => {
    context("User logs in to make a purchase", () => {
      cy.intercept('POST', '/auth/login').as('login');
      
      cy.visit("/auth/login");
      cy.getByData("email").type(Cypress.env("login"));
      cy.getByData("password").type(Cypress.env("password"));
      cy.get("form").find("button").click();
      
      cy.wait('@login');
      cy.location().should((loc) => {
        expect(loc.pathname).to.eq("/auth/dashboard");
      });
      cy.get("section").should("contain.text", Cypress.env("login"));
    });

    context("user adds two items of this same type", () => {
      cy.intercept('POST', '/graphql', (req) => {
        if (req.body.operationName === 'upsertOrder') {
          req.alias = 'upsertOrder';
        }
      });

      cy.visit("/products");
      
      cy.getByData("add-to-cart-button").first().click();
      cy.wait('@upsertOrder');
      cy.getByData("cart-icon").first().should("contain.text", "1");
      
      cy.getByData("add-to-cart-button").first().click();
      cy.wait('@upsertOrder');
      
      cy.visit("/cart");
      cy.getByData("cart-item-quantity").should("contain.text", "2");
    });
  });
});

内容的提问来源于stack exchange,提问作者seven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 22:25:18