{"componentChunkName":"component---src-templates-docs-js","path":"/docs/testing-environments.html","result":{"data":{"markdownRemark":{"html":"<!-- This document is intended for folks who are comfortable with JavaScript, and have probably written tests with it. It acts as a reference for the differences in testing environments for React components, and how those differences affect the tests that they write. This document also assumes a slant towards web-based react-dom components, but has notes for other renderers. -->\n<p>This document goes through the factors that can affect your environment and recommendations for some scenarios.</p>\n<h3 id=\"test-runners\"><a href=\"#test-runners\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test runners </h3>\n<p>Test runners like <a href=\"https://jestjs.io/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Jest</a>, <a href=\"https://mochajs.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">mocha</a>, <a href=\"https://github.com/avajs/ava\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">ava</a> let you write test suites as regular JavaScript, and run them as part of your development process. Additionally, test suites are run as part of continuous integration.</p>\n<ul>\n<li>Jest is widely compatible with React projects, supporting features like mocked <a href=\"#mocking-modules\">modules</a> and <a href=\"#mocking-timers\">timers</a>, and <a href=\"#mocking-a-rendering-surface\"><code class=\"gatsby-code-text\">jsdom</code></a> support. <strong>If you use Create React App, <a href=\"https://facebook.github.io/create-react-app/docs/running-tests\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Jest is already included out of the box</a> with useful defaults.</strong></li>\n<li>Libraries like <a href=\"https://mochajs.org/#running-mocha-in-the-browser\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">mocha</a> work well in real browser environments, and could help for tests that explicitly need it.</li>\n<li>End-to-end tests are used for testing longer flows across multiple pages, and require a <a href=\"#end-to-end-tests-aka-e2e-tests\">different setup</a>.</li>\n</ul>\n<h3 id=\"mocking-a-rendering-surface\"><a href=\"#mocking-a-rendering-surface\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Mocking a rendering surface </h3>\n<p>Tests often run in an environment without access to a real rendering surface like a browser. For these environments, we recommend simulating a browser with <a href=\"https://github.com/jsdom/jsdom\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">jsdom</code></a>, a lightweight browser implementation that runs inside Node.js.</p>\n<p>In most cases, jsdom behaves like a regular browser would, but doesn’t have features like <a href=\"https://github.com/jsdom/jsdom#unimplemented-parts-of-the-web-platform\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">layout and navigation</a>. This is still useful for most web-based component tests, since it runs quicker than having to start up a browser for each test. It also runs in the same process as your tests, so you can write code to examine and assert on the rendered DOM.</p>\n<p>Just like in a real browser, jsdom lets us model user interactions; tests can dispatch events on DOM nodes, and then observe and assert on the side effects of these actions <a href=\"/docs/testing-recipes.html#events\"><small>(example)</small></a>.</p>\n<p>A large portion of UI tests can be written with the above setup: using Jest as a test runner, rendered to jsdom, with user interactions specified as sequences of browser events, powered by the <code class=\"gatsby-code-text\">act()</code> helper <a href=\"/docs/testing-recipes.html\"><small>(example)</small></a>. For example, a lot of React’s own tests are written with this combination.</p>\n<p>If you’re writing a library that tests mostly browser-specific behavior, and requires native browser behavior like layout or real inputs, you could use a framework like <a href=\"https://mochajs.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">mocha.</a></p>\n<p>In an environment where you <em>can’t</em> simulate a DOM (e.g. testing React Native components on Node.js), you could use <a href=\"/docs/test-utils.html#simulate\">event simulation helpers</a> to simulate interactions with elements. Alternately, you could use the <code class=\"gatsby-code-text\">fireEvent</code> helper from <a href=\"https://testing-library.com/docs/react-native-testing-library/intro\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">@testing-library/react-native</code></a>.</p>\n<p>Frameworks like <a href=\"https://www.cypress.io/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Cypress</a>, <a href=\"https://github.com/GoogleChrome/puppeteer\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">puppeteer</a> and <a href=\"https://www.seleniumhq.org/projects/webdriver/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">webdriver</a> are useful for running <a href=\"#end-to-end-tests-aka-e2e-tests\">end-to-end tests</a>.</p>\n<h3 id=\"mocking-functions\"><a href=\"#mocking-functions\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Mocking functions </h3>\n<p>When writing tests, we’d like to mock out the parts of our code that don’t have equivalents inside our testing environment (e.g. checking <code class=\"gatsby-code-text\">navigator.onLine</code> status inside Node.js). Tests could also spy on some functions, and observe how other parts of the test interact with them. It is then useful to be able to selectively mock these functions with test-friendly versions.</p>\n<p>This is especially useful for data fetching. It is usually preferable to use “fake” data for tests to avoid the slowness and flakiness due to fetching from real API endpoints <a href=\"/docs/testing-recipes.html#data-fetching\"><small>(example)</small></a>. This helps make the tests predictable. Libraries like <a href=\"https://jestjs.io/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Jest</a> and <a href=\"https://sinonjs.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">sinon</a>, among others, support mocked functions. For end-to-end tests, mocking network can be more difficult, but you might also want to test the real API endpoints in them anyway.</p>\n<h3 id=\"mocking-modules\"><a href=\"#mocking-modules\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Mocking modules </h3>\n<p>Some components have dependencies for modules that may not work well in test environments, or aren’t essential to our tests. It can be useful to selectively mock these modules out with suitable replacements <a href=\"/docs/testing-recipes.html#mocking-modules\"><small>(example)</small></a>.</p>\n<p>On Node.js, runners like Jest <a href=\"https://jestjs.io/docs/en/manual-mocks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">support mocking modules</a>. You could also use libraries like <a href=\"https://www.npmjs.com/package/mock-require\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">mock-require</code></a>.</p>\n<h3 id=\"mocking-timers\"><a href=\"#mocking-timers\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Mocking timers </h3>\n<p>Components might be using time-based functions like <code class=\"gatsby-code-text\">setTimeout</code>, <code class=\"gatsby-code-text\">setInterval</code>, or <code class=\"gatsby-code-text\">Date.now</code>. In testing environments, it can be helpful to mock these functions out with replacements that let you manually “advance” time. This is great for making sure your tests run fast! Tests that are dependent on timers would still resolve in order, but quicker <a href=\"/docs/testing-recipes.html#timers\"><small>(example)</small></a>. Most frameworks, including <a href=\"https://jestjs.io/docs/en/timer-mocks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Jest</a>, <a href=\"https://sinonjs.org/releases/v7.3.2/fake-timers/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">sinon</a> and <a href=\"https://github.com/sinonjs/lolex\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">lolex</a>, let you mock timers in your tests.</p>\n<p>Sometimes, you may not want to mock timers. For example, maybe you’re testing an animation, or interacting with an endpoint that’s sensitive to timing (like an API rate limiter). Libraries with timer mocks let you enable and disable them on a per test/suite basis, so you can explicitly choose how these tests would run.</p>\n<h3 id=\"end-to-end-tests-aka-e2e-tests\"><a href=\"#end-to-end-tests-aka-e2e-tests\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>End-to-end tests </h3>\n<p>End-to-end tests are useful for testing longer workflows, especially when they’re critical to your business (such as payments or signups). For these tests, you’d probably want to test how a real browser renders the whole app, fetches data from the real API endpoints, uses sessions and cookies, navigates between different links. You might also likely want to make assertions not just on the DOM state, but on the backing data as well (e.g. to verify whether the updates have been persisted to the database).</p>\n<p>In this scenario, you would use a framework like <a href=\"https://www.cypress.io/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Cypress</a> or a library like <a href=\"https://github.com/GoogleChrome/puppeteer\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">puppeteer</a> so you can navigate between multiple routes and assert on side effects not just in the browser, but potentially on the backend as well.</p>","frontmatter":{"title":"Testing Environments","next":null,"prev":"testing-recipes.html"},"fields":{"path":"content/docs/testing-environments.md","slug":"docs/testing-environments.html"}}},"pageContext":{"slug":"docs/testing-environments.html"}},"staticQueryHashes":[]}