如何开玩笑

    科技2023-12-02  99

    Hi there, welcome back! Thank you for stopping by. Last month in my Getting Started with AWS article I wrote:

    嗨,欢迎回来! 谢谢您的光临。 上个月,在我的AWS入门文章中,我写道:

    “ If you are a budding developer looking to get that first opportunity, it is important to get familiar with some of the different cloud infrastructure providers out there. ”

    “ 如果您是一个发芽的开发人员,希望获得第一个机会,那么熟悉那里的一些其他云基础架构提供商就很重要。 ”

    The exact same can be said for writing tests for your code and the Testing Frameworks and libraries that help you do it. In this article, we will walk through setting up some unit tests with jest and react-testing-library for some components in an existing React application.

    可以说为代码编写测试以及可以帮助您完成测试的测试框架和库完全一样。 在本文中,我们将逐步通过jest和react-testing-librar y为现有React应用程序中的某些组件设置一些单元测试 。

    什么是开玩笑? (What is Jest?)

    Jest is a delightful JavaScript Testing Framework with a focus on simplicity. It works with projects using: Babel, TypeScript, Node, React, Angular, Vue, and more!

    Jest是一个令人愉快JavaScript测试框架,其重点是简单性 。 它适用于使用以下项目的项目: Babel , TypeScript , Node , React , Angular , Vue等等!

    什么是React Testing库? (What is React Testing Library?)

    The React Testing Library is a very light-weight solution for testing React components. It provides light utility functions on top of react-dom and react-dom/test-utils, in a way that encourages better testing practices. Its primary guiding principle is:

    React Testing Library是用于测试React组件的非常轻巧的解决方案。 它在react-dom和react-dom/test-utils之上提供了轻量级的实用程序功能,从而鼓励了更好的测试实践。 其主要指导原则是:

    The more your tests resemble the way your software is used, the more confidence they can give you.

    测试越类似于软件使用方式,就越能给您信心。

    So rather than dealing with instances of rendered React components, your tests will work with actual DOM nodes. The utilities this library provides facilitate querying the DOM in the same way the user would.

    因此,您的测试将与实际的DOM节点一起使用,而不是处理呈现的React组件的实例。 该库提供的实用程序可以方便地以与用户查询方式相同的方式查询DOM。

    让我们开始吧! (Let’s get started!)

    应用程序 (The Application)

    For this example, we have a simple SPA bootstrapped using the create-react-app your-apps-name command. The app has 2 simple components, a counter with “up” and “down” buttons. Clicking them increases and decreases the count displayed on the screen. The other component is a basic form with a submit button. Filling the form and clicking submit will display the message typed in the form.

    在此示例中,我们使用create-react-app your-apps-name命令引导了一个简单的SPA。 该应用程序有2个简单的组件,一个带有“向上”和“向下”按钮的计数器。 单击它们会增加和减少屏幕上显示的计数。 另一个组件是带有提交按钮的基本表单。 填写表格并单击提交将显示在表格中键入的消息。

    When you create projects using theCreate React App command, you have out of the box support for React Testing Library and Jest. If you didn’t use that command, you can add them via npm like so:

    当使用Create React App命令创建项目时,对React Testing Library和Jest具有开箱即用的支持。 如果您没有使用该命令,则可以通过npm将其添加,如下所示:

    // Install React Testing Librarynpm install --save-dev @testing-library/react// Install Jestnpm install --save -dev jest

    组成部分: (The Components:)

    As mentioned, our first component is the Counter component.

    如前所述,我们的第一个组件是Counter组件。

    As you can see, it is a very simple component that manages state locally with the useState hook(line 5 and 6). It has a single arrow function called handleClick (line 8) that manages both button clicks with some conditional statements. It also removes the element from the screen based on a nested conditional statements(line 17).

    如您所见,这是一个非常简单的组件,它通过useState钩子(第5行和第6行)在本地管理状态。 它具有一个称为handleClick (第8行)的单箭头功能,该功能使用一些条件语句来管理两次按钮单击。 它还基于嵌套的条件语句从屏幕上删除该元素(第17行)。

    Our second component is the Printer component.

    我们的第二个组件是Printer组件。

    This component has a bit more going on. Again, we manage all our state attributes with the useState hook(lines 4 – 7). In this case, we have a handleChange arrow function (line 9) that manages input changes on the form when the user is typing in the input field. Finally, we have a handleClick arrow function (line 13) that triggers all our state changes. Also, this component disables the “Print” button if there is no data in the input field.

    这个组件还有更多的事情要做。 同样,我们使用useState钩子管理所有状态属性(第useState行)。 在这种情况下,我们具有handleChange箭头功能(第9行),当用户在输入字段中键入内容时,该功能可管理表单上的输入更改。 最后,我们有一个handleClick箭头函数(第13行),该函数触发所有状态更改。 另外,如果输入字段中没有数据,此组件将禁用“打印”按钮。

    应用测试 (The App Test)

    Since our app was bootstrapped with create-react-app there is already one test file available for us in the src directory of the app called App.test.js. Let’s break this down a bit.

    由于我们的应用是通过create-react-app引导的,因此在应用的src目录中已经有一个可供我们使用的测试文件,名为App.test.js 让我们分解一下。

    This is the test file for the App.js component. Notice that like any other React component it starts by importing React (line 1). Then we import the necessary functions from React Testing Library(line 2) followed by importing the component to be tested(line 3).

    这是App.js组件的测试文件。 注意,像其他任何React组件一样,它从导入React(第1行)开始。 然后,我们从React Testing库(第2行)导入必要的功能,然后导入要测试的组件(第3行)。

    As the test indicates it is expecting that our App component “renders learn react link” (line 5). To verify this we need to destructure the getByText query and make it equal to the render function we imported and we pass it our component(line 6). This basically tells our query where it is going to be looking. Then we create a variable and assign it the return value of the getByText query and pass in the text we are looking for. In the example above, line 7 is passing in a regular expression of the desired text. Now that the query is ready to go the expectation can be set. Here, we expect the text “learn react” to be in the document. This is the basic structure of the tests we will be writing.

    如测试所示,期望我们的App组件“提供学习React链接”(第5行)。 为了验证这一点,我们需要对getByText查询进行getByText ,使其等于我们导入的render函数,然后将其传递给组件(第6行)。 这基本上告诉了我们查询将要查找的位置。 然后,我们创建一个变量,并为它分配getByText查询的返回值,并传递我们要查找的文本。 在上面的示例中,第7行传递了所需文本的正则表达式 。 现在查询已准备就绪,可以设置期望了。 在这里,我们希望文本“学习React”出现在文档中。 这是我们将要编写的测试的基本结构。

    // To run tests use these commands// If using yarnyarn test// If using npmnpm test

    Currently, this test is failing because we changed all the code this was testing for. If you are following along, you should see something like this.

    当前,该测试失败了,因为我们更改了该测试的所有代码。 如果您一直关注,您应该会看到类似的内容。

    Let’s update our test so we are looking for stuff that actually exists in our document.

    让我们更新测试,以便我们寻找文档中实际存在的内容。

    Ok, above we have the same test but we added some new variables with a few examples of different ways we are able to search for text. Line 11 shows an example that searches for a string and uses a flag to ignore case sensitivity. Lines 14 and 15 show 2 ways of using regular expressions. Line 15 is looking for a full string match while ignoring case and line 14 is looking for substrings while ignoring case. Now, when we run our test it passes.

    好的,上面我们进行了相同的测试,但是我们添加了一些新变量以及一些能够搜索文本的不同方式的示例。 第11行显示了一个搜索字符串并使用标志忽略大小写敏感性的示例。 第14和15行显示了两种使用正则表达式的方式。 第15行在忽略大小写的情况下寻找完整的字符串,而第14行在忽略大小写的情况下寻找子字符串。 现在,当我们运行测试时,它通过了。

    计数器测试 (The Counter Test)

    Let’s break down the steps to writing your test from scratch.

    让我们分解一下从头开始编写测试的步骤。

    1-创建一个测试文件 (1 - Create a test file)

    Create a new file in the src directory with the name of the component to be tested. All test files should follow the same naming convention ComponentName.test.js. In our case, we are testing the Counter component so our file will be called Counter.test.js.

    使用要测试的组件名称在src目录中创建一个新文件。 所有测试文件应遵循相同的命名约定ComponentName.test.js 。 在本例中,我们正在测试Counter组件,因此我们的文件将称为Counter.test.js 。

    2-导入React,组件和功能 (2 - Import React, components, and functions)

    As we did before we go through our imports and this time we also include the FireEvent function from React Testing Library. This will allow us to simulate button clicks in our tests.

    正如我们在导入之前所做的那样,这次我们还包括了React Testing库中的FireEvent函数。 这将使我们能够模拟测试中的按钮单击。

    3-编写功能测试 (3 - Write functionality tests)

    With everything in place, we can start writing our test. Since we are already checking that our components render correctly in our App.test.js file, we can test the functionality of the buttons by testing their individual actions and results.

    一切就绪后,我们就可以开始编写测试了。 由于我们已经在App.test.js文件中检查了组件的渲染App.test.js ,因此可以通过测试按钮的各个操作和结果来测试按钮的功能。

    测试“向上”按钮 (Testing the “Up” button)

    In this test, we are making sure that when we click the “Up” button for the first time we get the number 1 printed on the screen. To achieve this, we will be looking at multiple values.

    在此测试中,我们确保首次单击“向上”按钮时,将在屏幕上打印出数字1。 为了实现这一点,我们将研究多个值。

    The text on the button.

    按钮上的文字。 The text we are looking for as a result of clicking the button.

    单击该按钮后,我们正在寻找的文本。

    This means we will need to use a different query function other than getByText. Thankfully, there is a very flexible one called getByTestIdthat allows us to search by an id we create on the component we are testing using the data-testid= attribute.

    这意味着我们将需要使用除getByText其他查询函数。 值得庆幸的是,有一个非常灵活的名为getByTestId ,它允许我们使用我们在使用data-testid=属性测试的组件上创建的ID来搜索。

    Then in our test, we can access that id like this.

    然后在我们的测试中,我们可以像这样访问该ID。

    On line 14 we destructure our getByTestId query and pass it as an argument to our fireEvent.click() function and include the testId we created.

    在第14行,我们对getByTestId查询进行了getByTestId ,并将其作为参数传递给fireEvent.click()函数,并包含我们创建的testId 。

    With that test passing, we can pretty much do the same for the “Down” button.

    通过测试,我们几乎可以对“向下”按钮执行相同的操作。

    In order to be able to test that the “Down” button decrements the count correctly we have to increment the count first so we added an extra click event on line 26 then we check that the number incremented and then we fire the down click event on line 34.

    为了能够测试“向下”按钮是否正确地减少了计数,我们必须首先增加计数,因此我们在第26行添加了一个额外的click事件,然后检查数字是否增加,然后触发on第34行。

    打印机测试 (The Printer Test)

    Our Printer component has a text input and a submit button. We are going to test a few things here.

    我们的Printer组件具有文本输入和提交按钮。 我们将在这里测试一些东西。

    1-重复上一个测试的步骤1和2。 (1 - Repeat steps 1 and 2 from the previous test.)

    src directory. src目录中为组件创建测试文件。 Set all imports. 设置所有导入。

    2-开始编写测试 (2 - Start writing tests)

    We will test a couple of things for each part of this component. We can keep things organized by using Jest’s describe blocks to group together several related tests.

    我们将对该组件的每个部分进行一些测试。 通过使用Jest的describe 块将几个相关的测试组合在一起,我们可以使事情井井有条。

    输入测试 (Input tests)

    In this example, want to make sure the input field renders. We also so want to test if the input field updates when the user types into it.

    在此示例中,要确保输入字段呈现。 我们还想测试用户输入时输入字段是否更新。

    We will start with a new describe block.

    我们将从一个新的describe块开始。

    We’ll group all our input tests inside this block. Our first test will check that the input field renders correctly.

    我们将所有输入测试分组在此块内。 我们的第一个测试将检查输入字段是否正确呈现。

    React Testing Library has many queries at our disposal. Here is a very handy cheatsheet. Since we are looking for the text in the component and our component is just the input and buttons we can use the getByPlaceholderText query. Note that this is not the best practice. Normally, we would be using form tags and there would be labels for each input of the form, etc.

    React Testing库有许多查询可供我们使用。 这是一个非常方便的备忘单 。 由于我们正在寻找组件中的文本,而组件只是输入和按钮,因此我们可以使用getByPlaceholderText查询。 请注意,这不是最佳做法。 通常,我们将使用表单标签,并且表单的每个输入都会有标签,等等。

    A placeholder is not a good substitute for a label so you should generally use getByLabelText instead.

    占位符不能很好地代替标签,因此通常应改用 getByLabelText 。

    So far all our tests should be passing.

    到目前为止,我们所有的测试都应该通过。

    Now we can move on to testing if it updates on change.

    现在,我们可以继续测试它是否会随着更改而更新。

    As you can see on line 29, we are using a different event called “change”. This allows us to simulate a user inputting text into a form or input field.

    如您在第29行所看到的,我们正在使用一个称为“ change”的不同事件。 这使我们可以模拟用户在表单或输入字段中输入文本。

    Now our describe block should look like this.

    现在,我们的describe块应如下所示。

    And all our tests are passing.

    而且我们所有的测试都通过了。

    Now we want to make sure that our Print button works as expected. To do that we need 2 tests, one for each case. The first case is when the button is clicked with some data in the input field. The second case is when there is no data in the input field. To make these tests a bit more descriptive we can wrap each test case in a describe block. This way we are able to state each case individually.

    现在,我们要确保我们的“ Print按钮可以正常工作。 为此,我们需要2个测试,每个案例一个。 第一种情况是单击按钮时在输入字段中输入了一些数据。 第二种情况是输入字段中没有数据。 为了使这些测试更具描述性,我们可以将每个测试用例包装在describe块中。 这样,我们就可以分别陈述每种情况。

    Then we want to add another test inside this describe block to make sure our “Print” button is not disabled when there is data in the input field.

    然后,我们想在此describe块中添加另一个测试,以确保当输入字段中有数据时,我们的“打印”按钮未被禁用。

    Our “print button” describe block should now look like this. I will remove the notes just so it all fits in the image.

    现在,我们的“打印按钮” describe块应如下所示。 我将删除注释,以使其完全适合图像。

    Now, we can add our second case inside its own describe block. Here we want to check that the button is disabled when there is no data in the input field.

    现在,我们可以将第二种情况添加到其自己的describe块中。 在这里,我们要检查在输入字段中没有数据时按钮是否被禁用。

    This is what our finished “print button” block should look like.

    这就是我们完成的“打印按钮”块的外观。

    And our tests are all passing!

    我们的测试都通过了!

    Just like that, we have written 3 test suites with a total of 8 tests for App and our 2 components. Here is the working app.

    像这样,我们已经编写了3个测试套件,其中App和2个组件共8个测试。 这是正在运行的应用程序。

    演示地址

    I hope this was fun and informative. I’d love to hear your thoughts in the comments. As always, stay healthy, stay curious!

    我希望这是有趣和有益的。 我很想听听您在评论中的想法。 一如既往,保持健康,保持好奇心!

    翻译自: https://medium.com/swlh/how-to-testwith-jest-bfdb9bd40d86

    相关资源:四史答题软件安装包exe
    Processed: 0.015, SQL: 8