【问题标题】:Cypress Angular When Can Test Start?Cypress Angular 何时可以开始测试?
【发布时间】:2020-11-17 17:28:44
【问题描述】:

我正在使用 Cypress 对我的 Angular 应用程序进行端到端测试。我观察到的碎片来源之一是赛普拉斯行动迅速,而我的应用程序(相对)缓慢地准备好进行交互。赛普拉斯有一些经常被引用的 blog posts 讨论这个难题。

其中一篇博文中的示例建议劫持 addEventListener 来处理一个非常具体的示例。但我正在寻找的是适合 Angular 的“大锤”......任何人都有任何聪明的想法/技术,不涉及在参与测试活动之前为每次页面访问添加 10 秒等待(顺便说一下 工作)?我花了相当多的时间谷歌搜索无济于事。提前感谢您的想法!

除此之外:我还发现this open issue,如果它得到有效解决可能是答案的一部分。

【问题讨论】:

  • 您可以尝试查找表明应用已准备就绪的 UI 元素。对于我们的项目,当出现欢迎弹出窗口时,应用程序已准备就绪。有时我们还需要等待特定的 API 请求完成。
  • @konekoya 感谢您的评论!是的,我已经包含了一些等待网络请求,我什至在根应用程序组件上引入了一个绑定 AfterViewInit 的类,但我希望有某种与应用程序无关的解决方案;否则对于我可以直接导航到的每个页面,我都需要不同的策略。
  • 考虑到@konekoya 评论,这是我和我的开发团队发现的最佳实践,因为每个页面加载不同的内容并依赖于不同的元素来呈现。一种半可靠的通用方法是使用Cypress.$('document').ready(function functionToDoAfterPageLoad () =>{}),但如果您在初始加载后触发某些事情,则每次都需要运行它。
  • 本次网络研讨会谈到了此类案例,可能会有所帮助:youtube.com/…
  • Test retries 是一种方法。

标签: javascript angular testing cypress


【解决方案1】:

我自己也遇到过这个问题,我们在我们的应用程序上尝试了许多不同的方法。尽管它需要进行调整,但我们对当前的解决方案非常满意。

但在我找到解决方案之前,让我解释一下为什么这是一个很难解决的问题,而无需在开始测试之前简单地使用很长的wait

首先,我们需要等待页面准备好。幸运的是,赛普拉斯为我们做到了。

然后,我们可以等待 Angular 被引导。意识到这一点的一种方法是检查getAllAngularRootElements 是否在window 对象上可用。是的,即使在 prod 模式下,这个功能也显然存在!

  cy.window()
    .its('getAllAngularRootElements' as any)
    .should('exist');

但这并不是一个完美的解决方案,尤其是如果...您使用延迟加载。

仅仅因为 Angular 引导您的应用程序并不意味着您所有的惰性模块都已加载!这就是很难找到一种自动等待您想要准备好的方式的地方。

那么,我们如何才能以安全的方式尽快开始测试呢?在我看来,最好的选择是在每次cy.visit 调用后进行检查,并等待你要测试的元素存在。示例:

cy.visit(`some-page`);

cy.get(
  '.some-class-around-what-I-want-to-test',
  { timeout: 15000 }
).should('exist');

// ... rest of the test goes here

上面的代码将加载页面,等待你的目标元素最多存在 15 秒但是需要注意的重要一点是,一旦这个元素可用,它会认为检查成功并继续。因此,如果您的应用需要 2 秒来显示该元素,那么您的测试将立即开始!

如果您想减少所有测试的重复性,您可以创建一个函数来打开给定页面并等待其内容出现,然后再执行其他操作。示例:

// at the top of the test file
const openProfilePage = () => {
  cy.visit('profile');
  cy.get(
    '.profile',
    { timeout: 15000 }
  ).should('exist');
}

// in every tests after or in a before each
openProfilePage();

// test something else

【讨论】:

    【解决方案2】:

    使用cy.visit 一直对我有用,只要确保如docs 中所述事先设置应用程序路由、身份验证cookie 和模拟响应即可。

    通过将正确的选项传递给visit(参见Arguments),可能会找到适合您的解决方案

    访问您的网站路线的有用包装器

    waitForAppToStart: () => {
      cy.window().then(
          { timeout: 120000 }, // should definitely be enough
          win => new Cypress.Promise(
              (resolve, reject) => win.requestIdleCallback(resolve)));
    },
    
    visitSite: (path = '') => {
      cy.visit(`${appRoute}/${path}`).then(waitForAppToStart);
    },
    

    然后在你的实际测试用例中beforeEach-hook 调用visitSite()

    【讨论】:

      猜你喜欢
      • 2022-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-20
      • 2021-10-07
      • 2021-10-26
      • 1970-01-01
      • 2022-06-29
      相关资源
      最近更新 更多