1"use strict";(self.webpackChunkcra_docs=self.webpackChunkcra_docs||[]).push([[9167],{876:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return m}});var a=n(2784);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},i=Object.keys(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),m=r,h=d["".concat(l,".").concat(m)]||d[m]||u[m]||i;return n?a.createElement(h,o(o({ref:t},c),{},{components:n})):a.createElement(h,o({ref:t},c))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,o[1]=s;for(var p=2;p<i;p++)o[p]=n[p];return a.createElement.apply(null,o)}return a.createElement.apply(null,n)}d.displayName="MDXCreateElement"},3969:function(e,t,n){n.r(t),n.d(t,{frontMatter:function(){return s},contentTitle:function(){return l},metadata:function(){return p},toc:function(){return c},default:function(){return d}});var a=n(7896),r=n(1461),i=(n(2784),n(876)),o=["components"],s={id:"running-tests",title:"Running Tests"},l=void 0,p={unversionedId:"running-tests",id:"running-tests",title:"Running Tests",description:"Note: this feature is available with [email protected] and higher.",source:"@site/../docs/running-tests.md",sourceDirName:".",slug:"/running-tests",permalink:"/docs/running-tests",editUrl:"https://github.com/facebook/create-react-app/edit/main/docusaurus/website/../docs/running-tests.md",tags:[],version:"current",lastUpdatedBy:"Rick Hanlon",lastUpdatedAt:1738032994,formattedLastUpdatedAt:"1/27/2025",frontMatter:{id:"running-tests",title:"Running Tests"},sidebar:"docs",previous:{title:"Creating a Production Build",permalink:"/docs/production-build"},next:{title:"Debugging Tests",permalink:"/docs/debugging-tests"}},c=[{value:"Filename Conventions",id:"filename-conventions",children:[],level:2},{value:"Command Line Interface",id:"command-line-interface",children:[],level:2},{value:"Version Control Integration",id:"version-control-integration",children:[],level:2},{value:"Writing Tests",id:"writing-tests",children:[],level:2},{value:"Testing Components",id:"testing-components",children:[{value:"React Testing Library",id:"react-testing-library",children:[],level:3}],level:2},{value:"Using Third Party Assertion Libraries",id:"using-third-party-assertion-libraries",children:[],level:2},{value:"Initializing Test Environment",id:"initializing-test-environment",children:[{value:"<code>src/setupTests.js</code>",id:"srcsetuptestsjs",children:[],level:3}],level:2},{value:"Focusing and Excluding Tests",id:"focusing-and-excluding-tests",children:[],level:2},{value:"Coverage Reporting",id:"coverage-reporting",children:[{value:"Configuration",id:"configuration",children:[],level:3}],level:2},{value:"Continuous Integration",id:"continuous-integration",children:[],level:2},{value:"On CI servers",id:"on-ci-servers",children:[{value:"Travis CI",id:"travis-ci",children:[],level:3},{value:"CircleCI",id:"circleci",children:[],level:3}],level:2},{value:"On your own environment",id:"on-your-own-environment",children:[{value:"Windows (cmd.exe)",id:"windows-cmdexe",children:[],level:4},{value:"Windows (Powershell)",id:"windows-powershell",children:[],level:4},{value:"Linux, macOS (Bash)",id:"linux-macos-bash",children:[],level:4}],level:2},{value:"Disabling jsdom",id:"disabling-jsdom",children:[],level:2},{value:"Snapshot Testing",id:"snapshot-testing",children:[],level:2},{value:"Editor Integration",id:"editor-integration",children:[],level:2}],u={toc:c};function d(e){var t=e.components,n=(0,r.Z)(e,o);return(0,i.kt)("wrapper",(0,a.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"Note: this feature is available with ",(0,i.kt)("inlineCode",{parentName:"p"},"[email protected]")," and higher.")),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},(0,i.kt)("a",{parentName:"p",href:"https://github.com/facebook/create-react-app/blob/main/CHANGELOG-0.x.md#migrating-from-023-to-030"},"Read the migration guide to learn how to enable it in older projects!"))),(0,i.kt)("p",null,"Create React App uses ",(0,i.kt)("a",{parentName:"p",href:"https://jestjs.io/"},"Jest")," as its test runner. To prepare for this integration, we did a ",(0,i.kt)("a",{parentName:"p",href:"https://jestjs.io/blog/2016/09/01/jest-15.html"},"major revamp")," of Jest so if you heard bad things about it years ago, give it another try."),(0,i.kt)("p",null,"Jest is a Node-based runner. This means that the tests always run in a Node environment and not in a real browser. This lets us enable fast iteration speed and prevent flakiness."),(0,i.kt)("p",null,"While Jest provides browser globals such as ",(0,i.kt)("inlineCode",{parentName:"p"},"window")," thanks to ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/tmpvar/jsdom"},"jsdom"),", they are only approximations of the real browser behavior. Jest is intended to be used for unit tests of your logic and your components rather than the DOM quirks."),(0,i.kt)("p",null,"We recommend that you use a separate tool for browser end-to-e
1nd tests if you need them. They are beyond the scope of Create React App."),(0,i.kt)("h2",{id:"filename-conventions"},"Filename Conventions"),(0,i.kt)("p",null,"Jest will look for test files with any of the following popular naming conventions:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Files with ",(0,i.kt)("inlineCode",{parentName:"li"},".js")," suffix in ",(0,i.kt)("inlineCode",{parentName:"li"},"__tests__")," folders."),(0,i.kt)("li",{parentName:"ul"},"Files with ",(0,i.kt)("inlineCode",{parentName:"li"},".test.js")," suffix."),(0,i.kt)("li",{parentName:"ul"},"Files with ",(0,i.kt)("inlineCode",{parentName:"li"},".spec.js")," suffix.")),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},".test.js")," / ",(0,i.kt)("inlineCode",{parentName:"p"},".spec.js")," files (or the ",(0,i.kt)("inlineCode",{parentName:"p"},"__tests__")," folders) can be located at any depth under the ",(0,i.kt)("inlineCode",{parentName:"p"},"src")," top level folder."),(0,i.kt)("p",null,"We recommend to put the test files (or ",(0,i.kt)("inlineCode",{parentName:"p"},"__tests__")," folders) next to the code they are testing so that relative imports appear shorter. For example, if ",(0,i.kt)("inlineCode",{parentName:"p"},"App.test.js")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"App.js")," are in the same folder, the test only needs to ",(0,i.kt)("inlineCode",{parentName:"p"},"import App from './App'")," instead of a long relative path. Collocation also helps find tests more quickly in larger projects."),(0,i.kt)("h2",{id:"command-line-interface"},"Command Line Interface"),(0,i.kt)("p",null,"When you run ",(0,i.kt)("inlineCode",{parentName:"p"},"npm test"),", Jest will launch in watch mode",(0,i.kt)("sup",null,"*"),". Every time you save a file, it will re-run the tests, like how ",(0,i.kt)("inlineCode",{parentName:"p"},"npm start")," recompiles the code."),(0,i.kt)("p",null,"The watcher includes an interactive command-line interface with the ability to run all tests, or focus on a search pattern. It is designed this way so that you can keep it open and enjoy fast re-runs. You can learn the commands from the \u201cWatch Usage\u201d note that the watcher prints after every run:"),(0,i.kt)("p",null,(0,i.kt)("img",{parentName:"p",src:"https://jestjs.io/img/blog/15-watch.gif",alt:"Jest watch mode"})),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"*","Although we recommend running your tests in watch mode during development, you can disable this behavior by passing in the ",(0,i.kt)("inlineCode",{parentName:"p"},"--watchAll=false")," flag. In most CI environments, this is handled for you (see ",(0,i.kt)("a",{parentName:"p",href:"#on-ci-servers"},"On CI servers"),").")),(0,i.kt)("h2",{id:"version-control-integration"},"Version Control Integration"),(0,i.kt)("p",null,"By default, when you run ",(0,i.kt)("inlineCode",{parentName:"p"},"npm test"),", Jest will only run the tests related to files changed since the last commit. This is an optimization designed to make your tests run fast regardless of how many tests you have. However it assumes that you don\u2019t often commit the code that doesn\u2019t pass the tests."),(0,i.kt)("p",null,"Jest will always explicitly mention that it only ran tests related to the files changed since the last commit. You can also press ",(0,i.kt)("inlineCode",{parentName:"p"},"a")," in the watch mode to force Jest to run all tests."),(0,i.kt)("p",null,"Jest will always run all tests on a ",(0,i.kt)("a",{parentName:"p",href:"#continuous-integration"},"continuous integration")," server or if the project is not inside a Git or Mercurial repository."),(0,i.kt)("h2",{id:"writing-tests"},"Writing Tests"),(0,i.kt)("p",null,"To create tests, add ",(0,i.kt)("inlineCode",{parentName:"p"},"it()")," (or ",(0,i.kt)("inlineCode",{parentName:"p"},"test()"),") blocks with the name of the test and its code. You may optionally wrap them in ",(0,i.kt)("inlineCode",{parentName:"p"},"describe()")," blocks for logical grouping but this is neither required nor recommended."),(0,i.kt)("p",null,"Jest provides a built-in ",(0,i.kt)("inlineCode",{parentName:"p"},"expect()")," global function for making assertions. A basic test c
1ould look like this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},"import sum from './sum';\n\nit('sums numbers', () => {\n expect(sum(1, 2)).toEqual(3);\n expect(sum(2, 2)).toEqual(4);\n});\n")),(0,i.kt)("p",null,"All ",(0,i.kt)("inlineCode",{parentName:"p"},"expect()")," matchers supported by Jest are ",(0,i.kt)("a",{parentName:"p",href:"https://jestjs.io/docs/expect"},"extensively documented here"),"."),(0,i.kt)("p",null,"You can also use ",(0,i.kt)("a",{parentName:"p",href:"https://jestjs.io/docs/expect#tohavebeencalled"},(0,i.kt)("inlineCode",{parentName:"a"},"jest.fn()")," and ",(0,i.kt)("inlineCode",{parentName:"a"},"expect(fn).toBeCalled()"))," to create \u201cspies\u201d or mock functions."),(0,i.kt)("h2",{id:"testing-components"},"Testing Components"),(0,i.kt)("p",null,"There is a broad spectrum of component testing techniques. They range from a \u201csmoke test\u201d verifying that a component renders without throwing, to shallow rendering and testing some of the output, to full rendering and testing component lifecycle and state changes."),(0,i.kt)("p",null,"Different projects choose different testing tradeoffs based on how often components change, and how much logic they contain. If you haven\u2019t decided on a testing strategy yet, we recommend that you start with creating basic smoke tests for your components:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},"import React from 'react';\nimport ReactDOMClient from 'react-dom/client';\nimport App from './App';\n\nit('renders without crashing', () => {\n const div = document.createElement('div');\n ReactDOMClient.createRoot(div).render(<App />);\n});\n")),(0,i.kt)("p",null,"This test mounts a component and makes sure that it didn\u2019t throw during rendering. Tests like this provide a lot of value with very little effort so they are great as a starting point, and this is the test you will find in ",(0,i.kt)("inlineCode",{parentName:"p"},"src/App.test.js"),"."),(0,i.kt)("p",null,"When you encounter bugs caused by changing components, you will gain a deeper insight into which parts of them are worth testing in your application. This might be a good time to introduce more specific tests asserting specific expected output or behavior."),(0,i.kt)("h3",{id:"react-testing-library"},"React Testing Library"),(0,i.kt)("p",null,"If you\u2019d like to test components in isolation from the child components they render, we recommend using ",(0,i.kt)("inlineCode",{parentName:"p"},"react-testing-library"),". ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/testing-library/react-testing-library"},(0,i.kt)("inlineCode",{parentName:"a"},"react-testing-library"))," is a library for testing React components in a way that resembles the way the components are used by end users. It is well suited for unit, integration, and end-to-end testing of React components and applications. It works more directly with DOM nodes, and therefore it's recommended to use with ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/testing-library/jest-dom"},(0,i.kt)("inlineCode",{parentName:"a"},"jest-dom"))," for improved assertions."),(0,i.kt)("p",null,"To install ",(0,i.kt)("inlineCode",{parentName:"p"},"react-testing-library")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"jest-dom"),", you can run:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"npm install --save @testing-library/react @testing-library/dom @testing-library/jest-dom\n")),(0,i.kt)("p",null,"Alternatively you may use ",(0,i.kt)("inlineCode",{parentName:"p"},"yarn"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @testing-library/react @testing-library/dom @testing-library/jest-dom\n")),(0,i.kt)("p",null,"If you want to avoid boilerplate in your test files, you can create a ",(0,i.kt)("a",{parentName:"p",href:"#initializing-test-environment"},(0,i.kt)("inlineCode",{parentName:"a"},"src/setupTests.js"))," file:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},"// react-testing-library renders your components to document.body,\n// this adds jest-dom's custom assertions\nimport '@testing-library/jest-dom';\n")),(0,i.kt)("p",null,"Here's an example of using ",(0,i.kt)("inlineCode",{parentName:"p"},"react-testing-library")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"jest-dom")," for testing that the ",(0,i.kt)("inlineCode",{parentName:"p"},"<App />"),' component renders "Learn React".'),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},"import React from 'react';\nimport { render, screen } from '@testing-library/react';\nimport App from './App';
1\n\nit('renders welcome message', () => {\n render(<App />);\n expect(screen.getByText('Learn React')).toBeInTheDocument();\n});\n")),(0,i.kt)("p",null,"Learn more about the utilities provided by ",(0,i.kt)("inlineCode",{parentName:"p"},"react-testing-library")," to facilitate testing asynchronous interactions as well as selecting form elements from the ",(0,i.kt)("a",{parentName:"p",href:"https://testing-library.com/react"},(0,i.kt)("inlineCode",{parentName:"a"},"react-testing-library")," documentation")," and ",(0,i.kt)("a",{parentName:"p",href:"https://codesandbox.io/s/github/kentcdodds/react-testing-library-examples"},"examples"),"."),(0,i.kt)("h2",{id:"using-third-party-assertion-libraries"},"Using Third Party Assertion Libraries"),(0,i.kt)("p",null,"We recommend that you use ",(0,i.kt)("inlineCode",{parentName:"p"},"expect()")," for assertions and ",(0,i.kt)("inlineCode",{parentName:"p"},"jest.fn()")," for spies. If you are having issues with them please ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/facebook/jest/issues/new"},"file those against Jest"),", and we\u2019ll fix them. We intend to keep making them better for React, supporting, for example, ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/facebook/jest/pull/1566"},"pretty-printing React elements as JSX"),"."),(0,i.kt)("p",null,"However, if you are used to other libraries, such as ",(0,i.kt)("a",{parentName:"p",href:"https://www.chaijs.com/"},"Chai")," and ",(0,i.kt)("a",{parentName:"p",href:"https://sinonjs.org/"},"Sinon"),", or if you have existing code using them that you\u2019d like to port over, you can import them normally like this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},"import sinon from 'sinon';\nimport { expect } from 'chai';\n")),(0,i.kt)("p",null,"and then use them in your tests like you normally do."),(0,i.kt)("h2",{id:"initializing-test-environment"},"Initializing Test Environment"),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"Note: this feature is available with ",(0,i.kt)("inlineCode",{parentName:"p"},"[email protected]")," and higher.")),(0,i.kt)("p",null,"If your app uses a browser API that you need to mock in your tests or if you need a global setup before running your tests, add a ",(0,i.kt)("inlineCode",{parentName:"p"},"src/setupTests.js")," to your project. It will be automatically executed before running your tests."),(0,i.kt)("p",null,"For example:"),(0,i.kt)("h3",{id:"srcsetuptestsjs"},(0,i.kt)("inlineCode",{parentName:"h3"},"src/setupTests.js")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js"},"const localStorageMock = {\n getItem: jest.fn(),\n setItem: jest.fn(),\n removeItem: jest.fn(),\n clear: jest.fn(),\n};\nglobal.localStorage = localStorageMock;\n")),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},'Note: Keep in mind that if you decide to "eject" before creating ',(0,i.kt)("inlineCode",{parentName:"p"},"src/setupTests.js"),", the resulting ",(0,i.kt)("inlineCode",{parentName:"p"},"package.json")," file won't contain any reference to it, so you should manually create the property ",(0,i.kt)("inlineCode",{parentName:"p"},"setupFilesAfterEnv")," in the configuration for Jest, something like the following:")),(0,i.kt)("blockquote",null,(0,i.kt)("pre",{parentName:"blockquote"},(0,i.kt)("code",{parentName:"pre",className:"language-js"},'"jest": {\n // ...\n "setupFilesAfterEnv": ["<rootDir>/src/setupTests.js"]\n }\n'))),(0,i.kt)("h2",{id:"focusing-and-excluding-tests"},"Focusing and Excluding Tests"),(0,i.kt)("p",null,"You can replace ",(0,i.kt)("inlineCode",{parentName:"p"},"it()")," with ",(0,i.kt)("inlineCode",{parentName:"p"},"xit()")," to temporarily exclude a test from being executed."),(0,i.kt)("p",null,"Similarly, ",(0,i.kt)("inlineCode",{parentName:"p"},"fit()")," lets you focus on a specific test without running any other tests."),(0,i.kt)("h2",{id:"coverage-reporting"},"Coverage Reporting"),(0,i.kt)("p",null,"Jest has an integrated coverage reporter that works well with ES6 and requires no configuration."),(0,i.kt)("p",null,"Run ",(0,i.kt)("inlineCode",{parentName:"p"},"npm test -- --coverage")," (note extra ",(0,i.kt)("inlineCode",{parentName:"p"},"--")," in the middle) to include a coverage report like this:"),(0,i.kt)("p",null,(0,i.kt)("img",{parentName:"p",src:"https://i.imgur.com/5bF
1hnTS.png",alt:"coverage report"})),(0,i.kt)("p",null,"Note that tests run much slower with coverage so it is recommended to run it separately from your normal workflow."),(0,i.kt)("h3",{id:"configuration"},"Configuration"),(0,i.kt)("p",null,"The ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/scripts/utils/createJestConfig.js"},"default configuration")," that Create React App uses for Jest can be overridden by adding any of the following supported keys to a Jest config in your package.json."),(0,i.kt)("p",null,"Supported overrides:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#clearmocks-boolean"},(0,i.kt)("inlineCode",{parentName:"a"},"clearMocks"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#collectcoveragefrom-array"},(0,i.kt)("inlineCode",{parentName:"a"},"collectCoverageFrom"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#coveragepathignorepatterns-arraystring"},(0,i.kt)("inlineCode",{parentName:"a"},"coveragePathIgnorePatterns"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#coveragereporters-arraystring--string-options"},(0,i.kt)("inlineCode",{parentName:"a"},"coverageReporters"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#coveragethreshold-object"},(0,i.kt)("inlineCode",{parentName:"a"},"coverageThreshold"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#displayname-string-object"},(0,i.kt)("inlineCode",{parentName:"a"}
1,"displayName"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#extraglobals-arraystring"},(0,i.kt)("inlineCode",{parentName:"a"},"extraGlobals"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#globalsetup-string"},(0,i.kt)("inlineCode",{parentName:"a"},"globalSetup"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#globalteardown-string"},(0,i.kt)("inlineCode",{parentName:"a"},"globalTeardown"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#modulenamemapper-objectstring-string--arraystring"},(0,i.kt)("inlineCode",{parentName:"a"},"moduleNameMapper"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#resetmocks-boolean"},(0,i.kt)("inlineCode",{parentName:"a"},"resetMocks"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#resetmodules-boolean"},(0,i.kt)("inlineCode",{parentName:"a"},"resetModules"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#restoremocks-boolean"},(0,i.kt)("inlineCode",{parentName:"a"},"restoreMocks"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#snapshotserializers-arraystring"},(0,i.kt)("inlineCode",{parentName:"a"},"snapshotSerializers"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#testmatch-arraystring"},(0,i.kt)("inlineCode",{parentName:"a"},"testMatch"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object"},(0,i.kt)("inlineCode",{parentName:"a"},"transform"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#transformignorepatterns-arraystring"},(0,i.kt)("inlineCode",{parentName:"a"},"transformIgnorePatterns"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://jestjs.io/docs/configuration#watchpathignorepatterns-arraystring"},(0,i.kt)("inlineCode",{parentName:"a"},"watchPathIgnorePatterns")))),(0,i.kt)("p",null,"Example package.json:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "name": "your-package",\n "jest": {\n "collectCoverageFrom": [\n "src/**/*.{js,jsx,ts,tsx}",\n "!<rootDir>/node_modules/",\n "!<rootDir>/path/to/dir/"\n ],\n "coverageThreshold": {\n "global": {\n "branches": 90,\n "functions": 90,\n "lines": 90,\n "statements": 90\n }\n },\n "coverageReporters": ["text"],\n "snapshotSerializers": ["my-serializer-module"]\n }\n}\n')),(0,i.kt)("h2",{id:"continuous-integration"},"Continuous Integration"),(0,i.kt)("p",null,"By default ",(0,i.kt)("inlineCode",{parentName:"p"},"npm test")," runs the watcher with interactive CLI. However, you can force it to run tests once and finish the process by setting an environment variable called ",(0,i.kt)("inlineCode",{parentName:"p"},"CI"),"."),(0,i.kt)("p",null,"When creating a build of your application with ",(0,i.kt)("inlineCode",{parentName:"p"},"npm run build")," linter warnings are not checked by default. Like ",(0,i.kt)("inlineCode",{parentName:"p"},"npm test"),", you can force the build to perform a linter warning check by setting the environment variable ",(0,i.kt)("inlineCode",{parentName:"p"},"CI"),". If any warnings are encountered then the build fails."),(0,i.kt)("p",null,"Popular CI servers already set the environment variable ",(0,i.kt)("inlineCode",{parentName:"p"},"CI")," by default but you can do this yourself too:"),(0,i.kt)("h2",{id:"on-ci-servers"},"On CI servers"),(0,i.kt)("h3",{id:"travis-ci"},"Travis CI"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Following the ",(0,i.kt)("a",{parentName:"li",href:"https://docs.travis-ci.com/user/getting-started/"},"Travis Getting started")," guide for syncing your GitHub repository with Travis. You may need to initialize some settings manually in your ",(0,i.kt)("a",{parentName:"li",href:"https://travis-ci.org/profile"},"profile")," page."),(0,i.kt)("li",{parentName:"ol"},"Add a ",(0,i.kt)("inlineCode",{parentName:"li"},".travis.yml")," file to your git repository.")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"language: node_js\nnode_js:\n - 8\ncache:\n directories:\n - node_modules\nscript:\n - npm run build\n - npm test\n")),(0,i.kt)("ol",{start:3},(0,i.kt)("li",{parentName:"ol"},"Trigger your first build with a git push."),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("a",{parentName:"li",href:"https://docs.travis-ci.com/user/customizing-the-build/"},"Customize your Travis CI Build")," if needed.")),(0,i.kt)("h3",{id:"circleci"},"CircleCI"),(0,i.kt)("p",null,"Follow ",(0,i.kt)("a",{parentName:"p",href:"https://medium.com/@knowbody/circleci-and-zeits-now-s
1h-c9b7eebcd3c1"},"this article")," to set up CircleCI with a Create React App project."),(0,i.kt)("h2",{id:"on-your-own-environment"},"On your own environment"),(0,i.kt)("h4",{id:"windows-cmdexe"},"Windows (cmd.exe)"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-cmd"},"set CI=true&&npm test\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-cmd"},"set CI=true&&npm run build\n")),(0,i.kt)("p",null,"(Note: the lack of whitespace is intentional.)"),(0,i.kt)("h4",{id:"windows-powershell"},"Windows (Powershell)"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-Powershell"},'($env:CI = "true") -and (npm test)\n')),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-Powershell"},'($env:CI = "true") -and (npm run build)\n')),(0,i.kt)("h4",{id:"linux-macos-bash"},"Linux, macOS (Bash)"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"CI=true npm test\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"CI=true npm run build\n")),(0,i.kt)("p",null,"The test command will force Jest to run in CI-mode, and tests will only run once instead of launching the watcher."),(0,i.kt)("p",null,"For non-CI environments, you can pass the ",(0,i.kt)("inlineCode",{parentName:"p"},"--watchAll=false")," flag to disable test-watching."),(0,i.kt)("p",null,"The build command will check for linter warnings and fail if any are found."),(0,i.kt)("h2",{id:"disabling-jsdom"},"Disabling jsdom"),(0,i.kt)("p",null,"If you know that none of your tests depend on ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/tmpvar/jsdom"},"jsdom"),", you can safely set ",(0,i.kt)("inlineCode",{parentName:"p"},"--env=node"),", and your tests will run faster:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-diff"},' "scripts": {\n "start": "react-scripts start",\n "build": "react-scripts build",\n- "test": "react-scripts test"\n+ "test": "react-scripts test --env=node"\n')),(0,i.kt)("p",null,"To help you make up your mind, here is a list of APIs that ",(0,i.kt)("strong",{parentName:"p"},"need jsdom"),":"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Any browser globals like ",(0,i.kt)("inlineCode",{parentName:"li"},"window")," and ",(0,i.kt)("inlineCode",{parentName:"li"},"document")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://facebook.github.io/react/docs/top-level-api.html#reactdom.render"},(0,i.kt)("inlineCode",{parentName:"a"},"ReactDOM.render()"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://facebook.github.io/react/docs/test-utils.html#renderintodocument"},(0,i.kt)("inlineCode",{parentName:"a"},"TestUtils.renderIntoDocument()"))," (",(0,i.kt)("a",{parentName:"li",href:"https://github.com/facebook/react/blob/34761cf9a252964abfaab6faf74d473ad95d1f21/src/test/ReactTestUtils.js#L83-L91"},"a shortcut")," for the above)"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://airbnb.io/enzyme/docs/api/mount.html"},(0,i.kt)("inlineCode",{parentName:"a"},"mount()"))," in ",(0,i.kt)("a",{parentName:"li",href:"https://airbnb.io/enzyme/index.html"},"Enzyme")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://testing-library.com/docs/react-testing-library/api/#render"},(0,i.kt)("inlineCode",{parentName:"a"},"render()"))," in ",(0,i.kt)("a",{parentName:"li",href:"https://testing-library.com/docs/react-testing-library/intro/"},"React Testing Library"))),(0,i.kt)("p",null,"In contrast, ",(0,i.kt)("strong",{parentName:"p"},"jsdom is not needed")," for the following APIs:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://facebook.github.io/react/docs/test-utils.html#shallow-rendering"},(0,i.kt)("inlineCode",{parentName:"a"},"TestUtils.createRenderer()"))," (shallow rendering)"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://airbnb.io/enzyme/docs/api/shallow.html"},(0,i.kt)("inlineCode",{parentName:"a"},"shallow()"))," in ",(0,i.kt)("a",{parentName:"li",href:"https://airbnb.io/enzyme/index.html"},"Enzyme"))),(0,i.kt)("p",null,"Finally, jsdom is also not needed for ",(0,i.kt)("a",{parentName:"p",href:"https://jestjs.io/blog/2016/07/27/jest-14.html"},"snapshot testing"),"."),(0,i.kt)("h2",{id:"snapshot-testing"},"Snapshot Testing"),(0,i.kt)("p",null,"Snapshot testing is a feature of Jest that automatically generates text snapshots of your components and saves them on the disk so if the UI output changes, you get notified without manually writing any assertions on the component output. ",(0,i.kt)("a",{parentName:"p",href:"https://jestjs.io/blog/2016/07/27/jest-14.html"},"Read more about snapshot testing.")),(0,i.kt)("h2",{id:"editor-integration"},"Editor Integration"),(0,i.kt)("p",null,"If you use ",(0,i.kt)("a",{parentName:"p",href:"https://code.visualstudio.com"},"Visual Studio Code"),", there is a ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/orta/vscode-jest"},"Jest extension")," which works with Create React App out of the box. This provides a lot of IDE-like features while using a text editor: showing the status of a test run with potential fail messages inline, starting and stopping the watcher automatically, and offering one-click snapshot updates."),(0,i.kt)("p",null,(0,i.kt)("img",{parentName:"p",src:"https://cloud.githubusercontent.com/assets/49038/20795349/a032308a-b7c8-11e6-9b34-7eeac781003f.png",alt:"
1VS Code Jest Preview"})))}d.isMDXComponent=!0}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.