赛普拉斯 12864_赛普拉斯使用TypeScript单元测试React组件

赛普拉斯 12864

At work, we’ve recently been shifting our testing strategy to use Cypress. We’ve found it’s a powerful tool that has enabled fast and reliable end-to-end and integration tests, but there’s one piece that until recently was missing: unit tests. Cypress introduced some experimental features designed to help with unit testing and over the last few days I’ve spent some time familiarising myself with these to see if we can do all our testing in one framework.

在工作中,我们最近正在改变测试策略以使用赛普拉斯。 我们发现它是一个功能强大的工具,可以快速,可靠地进行端到端和集成测试,但是直到最近才缺少一个功能:单元测试。 赛普拉斯介绍了一些旨在帮助进行单元测试的实验性功能,最近几天我花了一些时间熟悉这些功能,以了解我们是否可以在一个框架中进行所有测试。

🔖 TL;DR: You can find my example repo with the finished code here 😊

🔖TL ; DR:您可以在此处找到带有完整代码的示例存储 😊

先决条件 (Prerequisites)

In this tutorial, I’m unit testing a Progress Bar component. It’s built with React in TypeScript and styling with styled-components so we need all these dependencies.

在本教程中,我将对进度条组件进行单元测试。 它是在TypeScript中使用React构建的,并使用样式化组件进行样式化,因此我们需要所有这些依赖项。

入门 (Getting Started)

To add and setup all these packages in package.json:

要在package.json添加并设置所有这些软件包:

(Cypress)

$ yarn add -D cypress cypress-react-unit-test

Enable experimentalComponentTesting (don’t worry, it’s quite stable now) and assign componentFolder to your preferred location for your tests. I also added a condition to only target .spec files but that’s optional.

启用experimentalComponentTesting(不用担心,它现在已经很稳定了),并将componentFolder分配到您的测试首选位置。 我还为仅目标.spec文件添加了一个条件,但这是可选的。

{  
"experimentalComponentTesting": true,
"componentFolder": "cypress/component",
"testFiles": "**/*.spec.*"
}

We also need to setup Cypress to include the unit test plugin.

我们还需要设置赛普拉斯以包含单元测试插件。

Add the following to cypress/support/index.js

将以下内容添加到cypress/support/index.js

import 'cypress-react-unit-test/support';

打字稿 (TypeScript)

💡 You can skip this step if you are using create-react-app with TypeScript template because it doesn’t require extra settings.

if 如果您将 带有TypeScript模板的 create-react-app 使用,则可以跳过此步骤, 因为它不需要额外的设置。

Cypress supports TypeScript as long as you have a tsconfig.json file. However, imports don't work unless you preprocess your TypeScript files.

只要您拥有tsconfig.json文件,赛普拉斯就支持TypeScript。 但是,除非您预处理TypeScript文件,否则导入将无法进行。

Let’s add the necessary packages to our dev dependencies if they’re not already configured.

如果尚未配置必要的程序包,则将它们添加到我们的dev依赖项中。

$ yarn add -D 

In webpack.config.js: ts-loader is needed to preprocess TypeScript files.

webpack.config.js :需要ts-loader来预处理TypeScript文件。

{  
rules: [
{
test: /\.tsx?$/,
exclude: [/node_modules/],
use: [
{
loader: "ts-loader",
options: {
transpileOnly: true,
},
},
],
},
],
}

Add the webpack preprocessor to ./cypress/plugin/index.js

将webpack预处理器添加到./cypress/plugin/index.js

const preprocessor = require('@cypress/webpack-preprocessor');
module.exports = (on, config) => {
const webpack = require('./webpack.config.js');
on("file:preprocessor", preprocessor({ webpack }));
return config;
};

Then make sure TypeScript understands Cypress’ types by adding this to tsconfig.json

然后通过将TypeScript添加到tsconfig.json来确保TypeScript了解Cypress的类型。

{
"compilerOptions": {
"types": ["cypress"]
}
}

And that’s all the setup done, we are good to go!

以上就是所有设置,我们很高兴!

单元测试我们的第一个组件 (Unit Testing Our First Component)

I picked a Progress Bar component to unit test. You can view the Progress Bar Component on a Live Site and check how the functionality works in my Github repository.

我选择了一个进度条组件进行单元测试。 您可以在实时站点上查看进度栏组件,并检查该功能在我的Github存储库中如何工作。

Image for post

我们要测试什么? (What do we want to test?)

  • A progress bar should be visible

    进度条应该是可见的
  • A progress bar should setup its state correctly based on passed data

    进度条应根据传递的数据正确设置其状态
  • A progress bar should render correctly in different states

    进度条应在不同状态下正确呈现

With unit tests, we’re aiming to test functionality rather than styling itself. If you want to test all your styles then adding Snapshot or Visual Regression to your integration tests would be more suitable. In this example, we are testing state of the component — when the step changes, does the rendering change as we expect? This is also part of the functionality.

对于单元测试,我们的目标是测试功能而不是样式本身。 如果要测试所有样式,则将SnapshotVisual Regression添加到集成测试中会更合适。 在此示例中,我们正在测试组件的状态-当步骤更改时,渲染是否按我们预期的那样更改? 这也是功能的一部分。

添加测试脚本 (Add test scripts)

./cypress/component/ProgressBar.spec.tsx
/// <reference types="cypress" />import React from "react";
import { mount } from "cypress-react-unit-test";
import ProgressBar from "../../src/ProgressBar";
import GlobalStyle from "../../src/globalStyle";describe("Progress Bar", () => {
const mockSteps = ["Step 1", "Step 2", "Step 3", "Step 4"];
it("renders steps", () => {
mount(
<ProgressBar steps={mockSteps}><GlobalStyle /></ProgressBar>
); cy.get("ul li").first().should("have.text", "Step 1")
.next().should("have.text", "Step 2")
.next().should("have.text", "Step 3")
.next().should("have.text", "Step 4"); cy.get("ul li").find("span")
.and("have.css", "background-color", "rgb(255, 255, 255)")
.and("have.css", "border-color", "rgb(0, 182, 237)");
}); it("renders active steps", () => {
mount(
<ProgressBar steps={mockSteps} current={3}>
<GlobalStyle />
</ProgressBar>
); cy.get("ul li:nth-child(2)").find("span")
.and("have.css", "background-color", "rgb(0, 182, 237)")
.and("have.css", "border-color", "rgb(0, 0, 0)"); cy.get("ul li:nth-child(3)").find("span")
.and("have.css", "background-color", "rgb(255, 255, 255)")
.and("have.css", "border-color", "rgb(0, 182, 237)"); cy.get("ul li:nth-child(4)").find("span")
.and("have.css", "border", "3px solid rgb(198, 198, 198)");
});
});

There are two key concepts here:

这里有两个关键概念:

  • mount tells Cypress that we want it to render our React Component on its own rather than in the context of a whole application

    mount告诉赛普拉斯,我们希望它自己呈现React组件,而不是在整个应用程序的上下文中呈现

  • mockData is used so we can test the Component outside the context of our application.

    使用了嘲笑数据 ,因此我们可以在应用程序上下文之外测试组件。

Our first test “renders steps” simply checks that the component has correctly setup the mockData that we passed to it. We can do this by checking that the text for each step matches what we passed in.

我们的第一个测试“ 渲染步骤 ”仅检查组件是否正确设置了传递给它的模拟数据。 我们可以通过检查每个步骤的文本是否与我们传递的内容匹配来做到这一点。

In our second test “renders active steps” we also set the third step to be “active” . We then expect that the component will render this with a blue open circle. We also expect the first and second step to be “completed” (with a blue background colour and white tick) and the fourth step should be “inactive” (a grey open circle). It’s a simple test but very effective, we covered both functionality and state of the component. Note that we only tested the styles that are changed by the component on state change, not all the styling.

在我们的第二个测试“ 呈现活动步骤 ”中,我们还将第三步设置为“活动”。 然后,我们期望该组件将使用一个蓝色的空心圆来呈现它。 我们还期望第一步和第二步“完成”(带有蓝色背景色和白色勾号),第四步应该“不活动”(灰色空心圆)。 这是一个简单的测试,但非常有效,我们介绍了组件的功能和状态。 请注意,我们仅测试了组件在状态更改时更改的样式,而不是所有样式。

Run yarn cypress open, you should see your browser load, the tests run and pass! 🎉

运行yarn cypress open ,您应该看到浏览器负载,测试运行并通过! 🎉

Image for post

But some of my styles are missing?

但是我的某些样式丢失了吗?

Cypress is running unit tests against our component in isolation. When using styled-components, the style is self contained, we don’t need to load external css or separate stylesheet. However, in some cases, we will rely on global styling (i.e: fonts, font size, spacing..etc) from the top level to ensure our component displays correctly during test.

赛普拉斯正在针对我们的组件单独运行单元测试。 使用样式化组件时,样式是独立的,我们不需要加载外部CSS或单独的样式表。 但是,在某些情况下,我们将依靠顶层的全局样式(即:字体,字体大小,间距等)来确保我们的组件在测试过程中正确显示。

The simplest solution is to also mount GloablStyle — we use this helper function to generate a special StyledComponent that handles global styles by styled-components.

最简单的解决方案是也挂载GloablStyle-我们使用此辅助函数来生成一个特殊的StyledComponent,该样式集可以通过styled-components处理全局样式。

import GlobalStyle from "../../src/globalStyle";
...
mount(
<ProgressBar steps={mockSteps}><GlobalStyle /></ProgressBar>
);

While this is useful for us visually when we run the tests in our browser, it is not necessary; remember, we’re only testing the functionality that is built into the component, not all of our styles!

尽管这在浏览器中运行测试对我们来说非常有用,但这不是必需的; 记住,我们只是在测试组件内置的功能,而不是我们所有的样式!

Run Cypress unit testing with NPM scripts

使用NPM脚本运行Cypress单元测试

I encountered an odd issue with NPM script. When adding cypress run into the script, it triggered all our tests including integrations. This is not ideal, we need to able to run unit tests on a specific component file or folder so we don’t have to wait for everything to complete.

我在NPM脚本中遇到了一个奇怪的问题。 在脚本中添加cypress run ,它触发了我们所有的测试,包括集成。 这不是理想的选择,我们需要能够在特定的组件文件或文件夹上运行单元测试,因此我们不必等待所有操作完成。

A useful tip I discovered is to add a separate command with yarn into our build script. Also for some reason two extra dashes are needed before - - spec to target file or folder.

我发现的一个有用的技巧是将带有yarn的单独命令添加到我们的构建脚本中。 同样由于某种原因,在将目标文件或文件夹指定为规范之前,还需要两个破折号。

"scripts": {
"test:unit": "yarn cypress run —- —-spec 'cypress/component/*.spec.tsx'"
}

而已! (That’s it!)

This is a quick walkthrough to explain how Cypress can unit test a React component. Setting up Typescript can be a little fiddly, but once you’ve got that done the testing is really straight forward. If you want to see more of what you can do with Cypress unit tests, this is a really good repo with lots of examples to start diving in further!

这是快速的演练,以说明赛普拉斯如何对React组件进行单元测试。 设置Typescript可能有点麻烦,但是一旦完成,测试就很简单了。 如果您想了解赛普拉斯单元测试的更多功能,这是一个非常不错的回购协议,其中包含许多示例,供您进一步深入研究!

https://github.com/bahmutov/cypress-react-unit-test

https://github.com/bahmutov/cypress-react-unit-test

Hopefully this tutorial helps! 😃

希望本教程对您有所帮助! 😃

翻译自: https://medium.com/swlh/cypress-unit-testing-react-components-with-typescript-77b38e5043b3

赛普拉斯 12864

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值