编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

我们如何使用 Cypress?(我们如何使用电子产品)

wxchong 2024-09-25 23:00:41 开源技术 12 ℃ 0 评论


为什么我们需要 UI 测试?

在我们项目的早期阶段,我们做的是手动测试,而不是编写自动测试,因为这样更容易。但是,当应用程序增长时,事情变得比以前更加困难,我们需要一个解决方案。

有些情况下需要不同的数据操作,这些操作很难在每个测试中重复,因此我们决定构建一个新的测试基础结构。

还有别的选择吗?

通常,人们使用 Selenium 来测试 UI 行为,但是 Selenium 消耗更多的资源,比如内存或处理能力,而且大多数情况下,当 Chromium 驱动程序加载过多时,它会崩溃。另外,当测试失败或者记录测试运行的视频时,我们需要截屏。但是如果我们在 Selenium 或其他工具中这样做,我们需要编写更多的代码。

除了 Selenium 之外,我们还可以组合多个库或框架来构建基础设施。但是它的学习曲线很高,我们不想花费不必要的时间来学习不同的图书馆。

Cypress

Cypress 是一个开源应用程序,它使我们能够编写前端应用程序的自动化测试,而不需要任何其他库。

当我们开始编写Cypress测试时,它是如此容易学习。它的 API 提供了我们需要的一切,比如 Mocking API,等待异步操作而不使用承诺等等。

在过去的六个月中,我们已经完成了整个项目的集成测试,大约有200-250个测试用例。运行这么多测试用例需要花费太多的时间; 因此我们需要添加并行化来加快流水线的速度。与 Cypress 并行运行测试很容易,只需要在管道中添加更多作业。

我们也需要端到端的测试,Cypress 已经满足了我们的需求,因为它允许您编写端到端的测试。

我们如何决定与Cypress集成?

在 Trendyol,当我们需要选择框架、解决方案等时,我们会使用决策工具。对于测试框架,我们考虑了 Cypress 和 Selenium 作为选项,因为它们是测试领域中最流行的框架。


我们如何将cypress整合到我们的管道中?

一开始,在管道中运输柏木太困难了。因为在启动 npm 应用程序时,不能在同一 CLI 中执行任何其他命令。我们需要的是一起运行前端应用程序和 Cypress,并在 Cypress 完成后终止应用程序。解决这个问题花了将近一个月的时间。

最后,我们找到了解决方案! 您只需要在运行 cypress 的脚本中添加一些命令。

我们使用了两个不同的库: 并发库和等待库。

同时允许我们并行运行不同的 bash 命令,而 wait-on 允许我们等待 URL 被访问。

package.json 看起来是这样的:

"scripts":{
   "cy:start:tests-and-server": "concurrently \"yarn run start\" \"wait-on
    http-get://localhost:8080 && yarn run cypress run --parallel --record --key         
    {your-api-key} --group TY
    \" --kill-others --success first"
}

这个脚本同时启动 UI 应用程序和 Cypress,并在测试完成后杀死它们。

您可以从这里访问 Cypress 的官方文档来安装 Cypress。

https://cypress.io/

最佳实践

下面是我们应用到项目中的一些最佳实践。

正在进行隔离测试

每个测试用例必须能够独立运行; 测试用例的结果或状态不能影响其他测试用例。这就是为什么 cypress 会在每次运行时重置环境的状态。

例如,您必须导航到每个测试用例的测试下面的页面。您可以使用 before each hook 来设置规范中每个测试用例的状态或执行相同的操作。

beforeEach(() => {
cy.visit('/page-under-test')
})

元素选择器

对于不受源代码更改影响的可靠元素选择,需要为 DOM 元素指定 test id 属性。这样,您的测试不会受到类、 id 或文本内容更改的影响。在我们的项目中,我们对元素使用 data-test-id 属性。

下面是按照 data 属性选择元素的示例。

cy.get(['data-test-id=success-message'])


访问外部网站


Cypress 阻止访问你无法控制的外部网站。如果您的测试依赖于外部网站,那么您仍然可以在不实际访问该网站的情况下进行测试。

例如,如果您的目的是在系统上触发一个更新; 那么您可以使用 cy.request ()命令向外部 API 发送一个请求。

如果您想断言所做的导航,最好在单元测试级别上覆盖这个检查。但是,如果必须使用 cypress 执行此操作,并且不能使用锚的 href 属性进行断言,那么可以停止 window 对象方法并检查是否调用了预期的 URL。

cy.visit('/', {
  onBeforeLoad (window) {
   cy.stub(window, 'open').as('openAction')
  }
}
cy.get('[data-test-id=action-button]').click()
cy.get('@openAction').should('be.calledWith', expectedLink)

登陆

必须通过直接发送请求而不是使用登录用户界面来处理登录。Cypress 的网站 https://docs.cypress.io/examples/examples/recipes#testing-the-dom 有多个登入示例。

要使用 jwt 登录,您可以向登录端点发出请求,从响应中获取一个令牌,并将其写入本地存储。

cy.session([], () => {
cy.request({
  method: 'POST',
  url: 'https://api-url',
  body: loginData
}).then((loginResponse) => {
    cy.setLocalStorage('ACCESS_TOKEN', authResponse.body.token)
    cy.saveLocalStorage()
  })
})

为了对所有测试用例使用相同的令牌,您需要在每个测试开始之前恢复本地存储,因为 Cypress 为每个测试用例重置了本地存储。

before(() => {
  cy.login();
  cy.saveLocalStorage();
});
 
beforeEach(() => {
  cy.restoreLocalStorage();
});

不必要的等待


大多数情况下,柏树都在等你,你不必像 cy.wait (500)那样等一定的时间。

cy.request():在接收到响应后解析

cy.visit(): 在加载页面后进行解析

cy.get(), cy.find(): 重试,直到找到指定的元素(当然会有超时)

但是,在某些情况下,wait 命令确实是有益的。

就像你可以用它来断言一个请求是否被发出。在下面的示例中,我们观察带有别名提供的 request/get-offer。Wait (‘@offer’)命令等待请求发出。这样我们就可以确定请求已经发出,否则测试就会失败。


cy.intercept({
  method: 'GET',
  path: '/get-offers'
}).as('offers')
 
cy.visit('/test-page')
cy.wait('@alias')


结论

我们使用 Cypress 进行 UI 和端到端测试。它易于使用,为我们提供了测试所需的一切。

本人抖音账号:里面有最新最流行的automation devops等技术的介绍,欢迎大家一键三连。



Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表