{"id":43351,"date":"2023-03-01T16:59:53","date_gmt":"2023-03-01T16:59:53","guid":{"rendered":"https:\/\/polarising.com\/techinside\/?p=43351"},"modified":"2023-10-25T11:10:47","modified_gmt":"2023-10-25T11:10:47","slug":"react-test-driven-development","status":"publish","type":"post","link":"https:\/\/polarising.com\/techinside\/react-test-driven-development\/","title":{"rendered":"React Test-Driven Development."},"content":{"rendered":"\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>At the start of my journey in testing React applications, I experienced frustration with the diversity of testing approaches, methods, and technologies utilized. I found myself asking questions such as &#8220;Where do I begin?&#8221; and &#8220;What precisely should I be testing?&#8221;. Some React components appeared to be so simple that the necessity of testing them was unclear.<\/p>\n\n\n\n<p>React provides an abundance of tools to help with testing, however, writing the tests can pose a challenge. Fortunately, the Test-driven Development (TDD) approach in React makes testing enjoyable. In this article I will show you how to combine React and TDD by using the <strong>Jest<\/strong> testing framework, <strong>React testing library<\/strong> and <strong>Cypress<\/strong>.<\/p>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">What is TDD?<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>Test-Driven Development<\/strong> (TDD) is a software development approach in which tests are developed to specify and validate what the code will do. Simply put, tests for each functionality are created and tested first and if the test fails then the new code is written in order to pass the test. This makes code simple and bug-free.<\/p>\n\n\n\n<p><strong>Jest<\/strong> is a JavaScript testing framework that lets developers to run tests on JavaScript and TypeScript code and can be easily integrated with React JS.<\/p>\n\n\n\n<p><strong>React Testing library<\/strong> is&nbsp;a set of helpers that allows developers test React components without relying on their implementation details.&nbsp;<\/p>\n\n\n\n<p><strong>Cypress<\/strong> is the best framework to run end to end tests. It comes with its own test environment and syntax.<\/p>\n\n\n\n<p>The feature we will build is a simple list of notes.<\/p>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Let\u00b4s build the app.<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Create simple app using create-react-app and install the Cypress.<\/p>\n\n\n\n<p>The next step is to <strong>create an end-to-end test describing the functionality we want users to be able to do:<\/strong><\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enter a note,<\/li>\n\n\n\n<li>Save it,<\/li>\n\n\n\n<li>And see it in the list.<\/li>\n<\/ul>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In the&nbsp;cypress&nbsp;folder, create an&nbsp;e2e&nbsp;folder and inside it create a file&nbsp;creating_a_note.cy.js. Then type the following contents:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>describe('Creating a note', () =&gt; {\n    it('Displays the note in the list', () =&gt; {\n      cy.visit('http:\/\/localhost:3000');\n  \n      cy.get('&#91;data-testid=\"noteText\"]')\n        .type('New note');\n  \n      cy.get('&#91;data-testid=\"saveButton\"]')\n        .click();\n  \n      cy.get('&#91;data-testid=\"noteText\"]')\n        .should('have.value', '');\n  \n      cy.contains('New note');\n    });\n  });\n<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The code describes the actions that a user would need to take:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Visit the site<\/li>\n\n\n\n<li>Enter the text &#8220;New Note&#8221; into a text field<\/li>\n\n\n\n<li>Click a button to save<\/li>\n\n\n\n<li>Confirm that the text field is cleared out<\/li>\n\n\n\n<li>Verify that the &#8220;New Note&#8221; appears somewhere on the screen<\/li>\n<\/ul>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>After creating the test, the next step in TDD is to&nbsp;run the test and watch it fail.&nbsp;This test will initially fail because we have not yet implemented the functionality.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>Timed out retrying after 4000ms: Expected to find element: &#91;data-testid=\"noteText\"], but never found it.<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The next step in TDD is to&nbsp;<strong>write just enough production code to fix the current test failure.<\/strong>&nbsp;<\/p>\n\n\n\n<p>Let\u2019s create component NewNoteForm,<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>export default function NewNoteForm() {\n  return (\n    &lt;input\n      type=\"text\"\n      data-testid=\"noteText\"\n   \/&gt;\n  );}\n<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>&nbsp; and use it in our App component.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>import NewNoteForm from \".\/NewNoteForm\";\nfunction App() {\n  return (\n   &lt;NewNoteForm\/&gt;\n  );}\nexport default App;\n<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Now the error we have is :<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>Timed out retrying after 4000ms: Expected to find element: &#91;data-testid=\"saveButton\"], but never found it.<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>To fix this error is easy. We just add a&nbsp;&lt;button&gt;&nbsp;to our component.&nbsp;<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>export default function NewNoteForm() {\n  return (\n    &lt;&gt;\n      &lt;input type=\"text\" data-testid=\"noteText\" \/&gt;\n      &lt;button data-testid=\"saveButton\"&gt;Save&lt;\/button&gt;\n    &lt;\/&gt;\n  );}\n<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Rerun the Cypress test. Now we get a new kind of test failure:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>Timed out retrying after 4000ms: expected '&lt;input&gt;' to have value '', but the value was 'New note'<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>We have reached to our first assertion, which is that the note text box should be empty &#8211; but it isn&#8217;t. We haven&#8217;t yet added the behavior to our app to clear the text box.<\/p>\n\n\n\n<p>Instead of adding the behavior directly, let&#8217;s&nbsp;<strong>step down from the &#8220;outside&#8221; level of end-to-end tests to an &#8220;inside&#8221; component test.<\/strong>&nbsp;<\/p>\n\n\n\n<p>Create a file&nbsp;src\/NewNoteForm.spec.js&nbsp;and add the following:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>import { render, screen } from \"@testing-library\/react\";\nimport userEvent from \"@testing-library\/user-event\";\nimport NewNoteForm from \".\/NewNoteForm\";\ndescribe(\"&lt;NewNoteForm \/&gt;\", () =&gt; {\n  describe(\"clicking the save button\", () =&gt; {\n    async function saveNote() {\n      render(&lt;NewNoteForm \/&gt;);\n\n      await userEvent.type(screen.getByTestId(\"noteText\"), \"New note\");\n      userEvent.click(screen.getByTestId(\"saveButton\"));\n    }\nit(\"clears the text field\", async () =&gt; {\n      await saveNote();\n      expect(screen.getByTestId(\"noteText\").value).toEqual(\"\");\n    });\n  });\n});\n<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Run&nbsp; component test. We get the same error as we did with the end-to-end test:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"895\" height=\"476\" src=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/end-to-end-image-react.png\" alt=\"end-to-end image react\" class=\"wp-image-43375\" style=\"width:671px;height:357px\" srcset=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/end-to-end-image-react.png 895w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/end-to-end-image-react-300x160.png 300w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/end-to-end-image-react-768x408.png 768w\" sizes=\"auto, (max-width: 895px) 100vw, 895px\" \/><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>React Testing Library has a different API than Cypress, but a lot of the test seems the same as the end-to-end test. With RTL Instead of testing the whole app running together, we&#8217;re testing just the&nbsp;NewNoteForm&nbsp;by itself.<\/p>\n\n\n\n<p>Now, let\u2019s add the behavior to the component to get this test to pass. We&#8217;ll need to make the input a controlled component and its text will be available in the parent component&#8217;s state. And next, we want to clear out&nbsp;inputText&nbsp;when the save button is clicked:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>import { useState } from \"react\";\nexport default function NewNoteForm() {\n  const &#91;inputText, setInputText] = useState(\"\");\n  function handleTextChange(event) {\n    setInputText(event.target.value);\n  }\n  function handleSave() {\n    setInputText(\"\");\n  }\n  return (\n    &lt;&gt;\n      &lt;input\n        type=\"text\"\n        data-testid=\"noteText\"\n        value={inputText}\n        onChange={handleTextChange}\n      \/&gt;\n      &lt;button data-testid=\"saveButton\" onClick={handleSave}&gt;\n        Save\n      &lt;\/button&gt;\n    &lt;\/&gt;\n  );\n}\n<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>When you save the file, the component test reruns and passes.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"732\" src=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/test-reruns-image-react-1024x732.png\" alt=\"\" class=\"wp-image-43377\" style=\"width:512px;height:366px\" srcset=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/test-reruns-image-react-1024x732.png 1024w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/test-reruns-image-react-300x215.png 300w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/test-reruns-image-react-768x549.png 768w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/test-reruns-image-react.png 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>After a component test passes, step back up to the outer end-to-end test to see what the next error is.<\/strong>&nbsp;<\/p>\n\n\n\n<p>Rerun&nbsp;creating_a_note.cy.js. Now our final assertion fails:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>Timed out retrying after 4000ms: Expected to find content: 'New note' but never did.<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Finally, the test is going to lead us to implement the actual feature: storing the note entered and displaying it in the list.<\/p>\n\n\n\n<p>Let\u2019s add event handler behavior to&nbsp;the NewNoteForm. Now, the component test won&#8217;t be asserting the same thing as the end-to-end test. The end-to-end test is looking for the &#8216;New note&#8217; content on the screen, but the component test will only be asserting whether the&nbsp;NewNoteForm&nbsp;component calls the event handler.<\/p>\n\n\n\n<p>Add another test case to&nbsp;NewNoteForm.spec.js:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>import { render, screen } from \"@testing-library\/react\";\nimport userEvent from \"@testing-library\/user-event\";\nimport NewNoteForm from \".\/NewNoteForm\";\n\ndescribe(\"&lt;NewNoteForm \/&gt;\", () =&gt; {\n  describe(\"clicking the save button\", () =&gt; {\n    let saveHandler;\n\n    beforeEach(async function saveNote() {\n      saveHandler = jest.fn().mockName(\"saveHandler\");\n      render(&lt;NewNoteForm onSave={saveHandler} \/&gt;);\n\n      await userEvent.type(screen.getByTestId(\"noteText\"), \"New note\");\n      userEvent.click(screen.getByTestId(\"saveButton\"));\n    });\n    it(\"clears the text field\", () =&gt; {\n      expect(screen.getByTestId(\"noteText\").value).toEqual(\"\");\n    });\n\n    it(\"calls the save handler\", async () =&gt; {\n      expect(saveHandler).toHaveBeenCalledWith(\"New note\");\n    });\n  });\n});\n<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Run the component test again. You&#8217;ll see the &#8220;clears the text field&#8221; test pass, and the &#8220;calls the save handler\u201d test fails:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"895\" height=\"219\" src=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/react-image-test-fails.png\" alt=\"\" class=\"wp-image-43378\" srcset=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/react-image-test-fails.png 895w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/react-image-test-fails-300x73.png 300w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/react-image-test-fails-768x188.png 768w\" sizes=\"auto, (max-width: 895px) 100vw, 895px\" \/><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>&nbsp;Let&#8217;s fix that:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>export default function NewNoteForm({ onSave }) {\n  const &#91;inputText, setInputText] = useState(\"\");\n  function handleTextChange(event) {\n    setInputText(event.target.value);\n  }\n  function handleSave() {\n    onSave(inputText);\n    setInputText(\"\");\n  }\u2026\n<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>And NewNoteForm component:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>import NewNoteForm from \".\/NewNoteForm\";\nfunction App() {\n  function handleSave() {}\n  return &lt;NewNoteForm onSave={handleSave} \/&gt;;\n}\nexport default App;\n<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Rerun the end-to-end test and we get:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>Timed out retrying after 4000ms: Expected to find content: 'New note' but never did.<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>We no longer get the&nbsp;onSave&nbsp;error. But we still not displaying the note.<\/p>\n\n\n\n<p>Next, we need to save the note in state in the&nbsp;App&nbsp;component.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>import { useState } from \"react\";\nimport NewNoteForm from \".\/NewNoteForm\";\nfunction App() {\n  const &#91;notes, setNotes] = useState(&#91;]);\n  function handleSave(newNote) {\n    setNotes(&#91;newNote, ...notes]);\n  }\n  return &lt;NewNoteForm onSave={handleSave} \/&gt;;\n}\nexport default App;\n<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Next, to display the notes, let&#8217;s create NoteList&nbsp;component.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>export default function NoteList({ data }) {\n  return (\n    &lt;ul&gt;\n      {data.map((note, index) =&gt; (\n        &lt;li key={index}&gt;{note}&lt;\/li&gt;\n      ))}\n    &lt;\/ul&gt;\n  );\n}\n<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>And use it in App component.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>import { useState } from \"react\";\nimport NewNoteForm from \".\/NewNoteForm\";\nimport NoteList from \".\/NoteList\";\nfunction App() {\n  const &#91;notes, setNotes] = useState(&#91;]);\n  function handleSave(newNote) {\n    setNotes(&#91;newNote, ...notes]);\n  }\n  return (\n    &lt;&gt;\n      &lt;NewNoteForm onSave={handleSave} \/&gt;\n      &lt;NoteList data={notes} \/&gt;\n    &lt;\/&gt;\n  );}\nexport default App;\n<\/code><\/pre>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Rerun the tests and they pass. So, that\u2019s how we have developed a basic React app using TDD.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"895\" height=\"470\" src=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/react-image-TDD.png\" alt=\"\" class=\"wp-image-43379\" style=\"width:448px;height:235px\" srcset=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/react-image-TDD.png 895w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/react-image-TDD-300x158.png 300w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/react-image-TDD-768x403.png 768w\" sizes=\"auto, (max-width: 895px) 100vw, 895px\" \/><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"800\" src=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/TDD-image-react-1024x800.png\" alt=\"TDD image react\" class=\"wp-image-43380\" style=\"width:512px;height:400px\" srcset=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/TDD-image-react-1024x800.png 1024w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/TDD-image-react-300x234.png 300w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/TDD-image-react-768x600.png 768w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2023\/02\/TDD-image-react.png 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Why to use TDD.<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Test coverage up to 100%. <\/strong>By writing only the minimum code needed to pass each error, this ensures we do not have any code that&nbsp;is not&nbsp;covered by a test.<\/li>\n\n\n\n<li><strong>Ability to refactor.<\/strong>&nbsp;Thanks to full testing coverage, we can modify our code to enhance its design and accommodate future needs.<\/li>\n\n\n\n<li><strong>Capacity for rapid delivery. <\/strong>We avoid investing time in developing code that &nbsp;our users don&#8217;t need. When some old code hinders our progress, we can restructure it to increase efficiency. Our tests minimize the amount of manual testing we need to do before a release.<\/li>\n<\/ul>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">More Resources<a href=\"https:\/\/learntdd.in\/react\/#more-resources\" target=\"_blank\" rel=\"noopener\">\u200b<\/a>.<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>To learn more about TDD:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u201cMastering React Test-Driven Development\u201d&nbsp;&#8211; a book walking through this style of TDD in much more detail.<\/li>\n\n\n\n<li>\u201cTest-Driven Development in React\u201d- a free video series of live stream recordings. From 2018 so technical details have changed, but the approach still applies.<\/li>\n<\/ul>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>React Testing Libraries:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/testing-library.com\/docs\/react-testing-library\/intro\/\" target=\"_blank\" rel=\"noopener\">https:\/\/testing-library.com\/docs\/react-testing-library\/intro\/<\/a> &#8211; official React Testing Library documentation.<\/li>\n\n\n\n<li><a href=\"https:\/\/jestjs.io\/docs\/tutorial-react\" target=\"_blank\" rel=\"noopener\">https:\/\/jestjs.io\/docs\/tutorial-react<\/a> &#8211; testing React apps with Jest.<\/li>\n\n\n\n<li><a href=\"https:\/\/docs.cypress.io\/guides\/component-testing\/react\/quickstart\" target=\"_blank\" rel=\"noopener\">https:\/\/docs.cypress.io\/guides\/component-testing\/react\/quickstart<\/a> &#8211; testing React apps with Cypress.<\/li>\n<\/ul>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong>Some interesting blog posts about React testing:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.freecodecamp.org\/news\/how-to-test-react-applications\/\" target=\"_blank\" rel=\"noopener\">https:\/\/www.freecodecamp.org\/news\/how-to-test-react-applications\/<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.freecodecamp.org\/news\/8-simple-steps-to-start-testing-react-apps-using-react-testing-library-and-jest\/\" target=\"_blank\" rel=\"noopener\">https:\/\/www.freecodecamp.org\/news\/8-simple-steps-to-start-testing-react-apps-using-react-testing-library-and-jest\/<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.freecodecamp.org\/news\/testing-react-hooks\/\" target=\"_blank\" rel=\"noopener\">https:\/\/www.freecodecamp.org\/news\/testing-react-hooks\/<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.freecodecamp.org\/news\/write-unit-tests-using-react-testing-library\" target=\"_blank\" rel=\"noopener\">https:\/\/www.freecodecamp.org\/news\/write-unit-tests-using-react-testing-library<\/a><\/li>\n<\/ul>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong><strong>Ekaterina Sleptsova<\/strong><\/strong><br>Software Developer at Polarising<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>At the start of my journey in testing React applications, I experienced frustration with the diversity of testing approaches, methods, and technologies utilized. I found myself asking questions such as &#8220;Where do I begin?&#8221; and &#8220;What precisely should I be testing?&#8221;. Some React components appeared to be so simple that the necessity of testing them [&hellip;]<\/p>\n","protected":false},"author":44,"featured_media":41280,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"default","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"footnotes":""},"categories":[22],"tags":[],"class_list":["post-43351","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-react"],"uagb_featured_image_src":{"full":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured.jpg",1600,900,false],"thumbnail":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-150x150.jpg",150,150,true],"medium":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-300x169.jpg",300,169,true],"medium_large":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-768x432.jpg",768,432,true],"large":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-1024x576.jpg",1024,576,true],"1536x1536":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-1536x864.jpg",1536,864,true],"2048x2048":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured.jpg",1600,900,false],"authorship-box-avatar":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-150x150.jpg",150,150,true],"authorship-box-related":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-70x70.jpg",70,70,true]},"uagb_author_info":{"display_name":"Ekaterina Sleptsova","author_link":"https:\/\/polarising.com\/techinside\/author\/ekaterina-sleptsova\/"},"uagb_comment_info":0,"uagb_excerpt":"At the start of my journey in testing React applications, I experienced frustration with the diversity of testing approaches, methods, and technologies utilized. I found myself asking questions such as &#8220;Where do I begin?&#8221; and &#8220;What precisely should I be testing?&#8221;. Some React components appeared to be so simple that the necessity of testing them&hellip;","_links":{"self":[{"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/posts\/43351","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/users\/44"}],"replies":[{"embeddable":true,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/comments?post=43351"}],"version-history":[{"count":13,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/posts\/43351\/revisions"}],"predecessor-version":[{"id":43435,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/posts\/43351\/revisions\/43435"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/media\/41280"}],"wp:attachment":[{"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/media?parent=43351"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/categories?post=43351"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/tags?post=43351"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}