使用 Cypress.io 测试 React
Cypress 测试库
什么是 Cypress?
Cypress 是一款前端测试工具。Cypress 允许您测试任何在浏览器中运行的应用程序。使用 Cypress,您可以编写单元测试、集成测试和端到端测试。Cypress 的架构让您可以完全控制您的应用程序。
Cypress 旨在帮助您编写更快、更轻松、更可靠的测试。无需选择一堆不同的框架、断言库和其他工具,Cypress 为您做好了选择,让您可以立即编写测试。Cypress 适用于任何框架或网站。React、Vue、Ember、Vue、Elm……Cypress 使用您可能已经熟悉的工具,例如 JQuery、Mocha、Chai 和 sinon.js……这些稳定且物有所值的工具,都已集成到 Cypress 中。
现在我们来讨论一下它是什么,让我们使用它吧!
系统要求
Cypress 使用您计算机上安装的桌面应用程序。要使用它,您必须拥有以下操作系统:
- macOS 10.9 及更高版本(仅限 64 位)
- Linux Ubuntu 12.04 及以上版本、Fedora 21 和 Debian 8(仅限 64 位)
- Windows 7 及更高版本
安装 Cypress
在本文中,我们将在 React 应用程序上编写测试。因此,首先,我们将使用create-react-app创建一个 React 应用程序。运行以下命令create-react-app first-cypress-tests
:
如果您尚未安装 create-react-app,可以在此处找到获取说明。设置好应用程序后,请进入新的 React 应用程序文件夹:cd first-cypress-tests
。接下来,我们将安装 Cypress 包。在本文中,我将使用 yarn 并运行yarn add cypress --dev
。如果您是 npm 用户,则可以运行npm install cypress --save-dev
。
现在 Cypress 已经安装完毕,我们可以使用命令 运行 Cypress Test Runner yarn run cypress open
。或者,使用 npm 运行$(npm bin)/cypress open
。现在你应该会在屏幕上看到以下窗口。
您会看到 Cypress 为您创建了一个文件夹。在其中,您可以找到一些关于如何编写测试的有用示例,以及一些关于如何使用 Cypress 的示例。示例测试位于 中cypress/integration/examples
。
运行你的第一个测试
单击“OK,知道了!”绿色按钮后,您将看到 Cypress Test Runner。
这里我们可以看到一些东西。首先,您可以看到窗口中列出的所有测试文件。Cypress 会自动在文件夹中找到您的测试文件。请注意,每个文件都以spec.jscypress/integration
结尾。我会在整篇文章中都使用这个命名,但您不必这样做。在右侧,有一个小小的下拉菜单。
这是 Cypress Test Runner 找到的可用浏览器列表。Cypress 运行测试时会为您启动一个浏览器。如您所见,我只提供了两个浏览器选项。如果您想了解可以使用哪些浏览器以及如何添加它们,可以阅读文档。目前我还是推荐使用 Chrome。
好了,让我们来运行一些测试吧!有两种方法可以运行测试。您可以点击右侧的“运行所有规范”按钮,或者点击某个文件名。如果选择后者,则只会运行该文件的测试。测试开始运行时,会打开一个浏览器,具体取决于您在 Cypress 测试运行器中选择的浏览器。我们稍后会有时间详细讨论这个问题,因为我现在想编写自己的自定义测试。
编写第一个测试
您可能已经猜到了在 Cypress 中运行测试需要什么:
- 在中创建测试文件
cypress/integration
- 让 Cypress 实时更新 Cypress Test Runner 中的测试文件列表
- 启动测试
让我们创建一个名为custom
inside our cypress/integration
folder 的文件夹。然后,我将在该新文件夹中创建一个名为 inside 的文件first_tests.spec.js
。如果您返回 Cypress Test Runner,您会看到我们的文件夹和文件已添加到列表中!实时!
太好了,现在让我们编写第一个通过的测试。
describe("First custom test", function() {
it("does something!", function() {
expect(5).to.equal(5);
});
});
现在非常简单。回到 Cypress Test Runner,点击文件名来启动新测试。你会看到一个浏览器窗口打开(我用的是 Chrome),我们的测试成功运行了!
您已解锁“用 Cypress 编写一个通过测试!”徽章。干得好,年轻的 TDD 学徒。现在让我们编写一个失败的测试,并看看实时重新加载的效果。
我们首先编写一个失败的测试,它会在浏览器中以红色显示。Cypress 会监控测试文件的变化,并相应地更新测试套件的结果。真是太棒了!
您可能对这些测试的语法很熟悉。例如,describe()来自mocha , expect()来自chai。正如我之前提到的,它们是 Cypress 自带工具的一部分。
好的,让我们写一些真正的测试,一些我们可能在实际生活中会用到的东西。我们之前创建了一个 React 应用程序。虽然内容不多,但现有的框架可以让我们写一些东西。
访问我们的申请页面
我的 React 应用将在 3000 端口上运行。我们首先要测试的是确保访问http://localhost:3000时它不会崩溃。让我们创建一个名为react_app.spec.js
inside的文件cypress/integration/custom
来保存测试。我们还需要运行我们的应用。运行yarn start
或npm start
启动我们的 React 应用。访问http://localhost:3000时,你应该会看到以下内容:
让我们编写测试并查看测试运行器如何处理它:
发生了一些事情:
- 您将在左侧看到访问日志。
- 在右侧,我们的 React 应用程序正在 App 预览中加载。
- 即使没有断言,测试也是绿色的。如果请求返回 404 或 500 状态码,则测试失败。
- 页面加载时,VISIT测试的背景为蓝色。这表示页面处于待处理状态。
注意:请务必测试您控制的应用程序。请勿测试您无法控制的网站。这些网站可能随时发生变化,或者启用了某些安全功能,导致 Cypress 无法正常运行。
检查元素是否存在
我已经启动了通过命令创建的 React 应用程序create-react-app
。由此,我知道了应用程序中 HTML 的两点状态:主页上应该有一张图片和一个链接。
对于图像,我想测试两件事:
- 该图像具有App-logo类
- 图片有 alt 属性标志
首先,让我们写一个失败测试。
it("finds an image", function() {
cy.visit("http://localhost:3000");
cy.get("image");
});
这会失败,但请注意它变红所花的时间。
超过4 秒!我的情况是 4.39 秒。这是因为 Cypress 会自动等待并重新运行测试。Cypress 预计会在 DOM 中的某个位置找到该元素。因此,它不会立即失败。
首先,让我们改变这一点,让我们的测试通过:
it("finds an image", function() {
cy.visit("http://localhost:3000");
cy.get("img");
});
果然,它变绿了:
太好了,至少我们可以确定页面上确实有一个元素了。接下来,我们将测试类名App-logo是否被图片使用。操作方法如下:
it("finds an image", function() {
cy.visit("http://localhost:3000");
cy.get("img").should("have.class", "App-logo");
});
测试通过了!
最后,我们要确保图像具有与logo相同的属性。由于cy.get()返回一个 jQuery 对象,因此我们可以使用invoke()方法获取所需的任何属性。
it("finds an image", function() {
cy.visit("http://localhost:3000");
cy.get("img")
.should("have.class", "App-logo")
.invoke("attr", "alt")
.should("equal", "logo");
});
现在,运行测试,结果仍然是绿色。
DOM快照
我还想向您展示如何固定DOM 快照以获取控制台中的信息。在 Cypress 为您打开的浏览器中打开开发者控制台。然后点击左侧日志中的“INVOKE”行。您应该会看到灰色的图钉变成紫色。看看控制台中发生了什么?拥有所有这些信息真是太棒了!它使测试调试变得非常容易。
注意:我们可以进一步完善上一个测试,确保 DOM 中只有一个图像具有这些属性,或者检查 src 属性。这个就留给你自己决定吧 😉
点击元素
我们还知道我们的 React 应用有一个链接。借助 Cypress,我们可以与该元素进行交互,并确保它将我们带到它所声明的位置。首先,我将更改<a>
HTML 中的元素标记,以便于测试。如下所示:
<a className="App-link" href="/about" rel="noopener noreferrer">
Learn React
</a>
我修改了 href 属性,确保它只存在于应用程序内部,这样我就能完全控制它。我们来写一个测试来获取<a>
元素:
it("clicks a link", function() {
cy.visit("http://localhost:3000");
cy.get("a.App-link")
.invoke("attr", "href")
.should("equal", "/about");
});
我找到了一个带有App-link类和 href 属性/about 的<a>
元素。好了,现在我们可以在元素上调用 click 方法了。然后我们会检查新的 URL 是否符合我们的预期。
it("clicks a link", function() {
cy.visit("http://localhost:3000");
cy.get("a.App-link")
.should($link => {
expect($link)
.attr("href")
.to.equal("/about");
})
.click();
cy.url().should("contain", "/about");
});
这个测试看起来可能有点复杂。我们来分解一下。
- 首先,我们获取元素。
- 然后,我们使用should()方法。该方法接受一个回调函数,其中包含前一个get()方法的结果。
- 在该回调之外,链接到should()的是我们的click()方法。
为什么要使用回调?因为click()方法会与上一个结果进行交互。所以,如果我们像之前一样将该方法链接到一个invoke().should()方法,就会出错,因为该链接的结果不是DOM元素。这就是为什么我们必须在常规链接之外进行 href 属性测试。
最后,我们使用cy.url()函数检查 url 是否包含字符串/about。
如您所见,预览根据click()事件更新了 URL。日志向我们展示了所有不同的步骤:CLICK、PAGE LOAD、NEW URL。
结论
我希望这篇文章能让您了解 Cypress 的强大功能。我们已经了解了如何:
- 安装 Cypress
- 运行 Cypress 测试运行器
- 测试 React 应用程序
我发现 Cypress 确实简化了前端测试的编写,而这正是我一直苦苦挣扎的。Cypress 使用了很多开发者已经熟悉的工具,入门非常容易。未来我还会向大家展示更多其他精彩的功能。
玩得开心❤️
文章来源:https://dev.to/damcosset/testing-react-with-cypress-io-5b4j