{"id":18720630,"url":"https://github.com/nareshbhatia/react-testing-techniques","last_synced_at":"2025-08-21T22:31:15.613Z","repository":{"id":38369290,"uuid":"414325857","full_name":"nareshbhatia/react-testing-techniques","owner":"nareshbhatia","description":"Testing effectively using a user-centered approach","archived":false,"fork":false,"pushed_at":"2023-06-04T23:12:20.000Z","size":1602,"stargazers_count":142,"open_issues_count":1,"forks_count":35,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-12-09T17:58:13.102Z","etag":null,"topics":["cypress","jest","mock-service-worker","react","react-testing-library","storybook","testing"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nareshbhatia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-10-06T18:23:16.000Z","updated_at":"2024-11-22T23:08:00.000Z","dependencies_parsed_at":"2024-11-07T13:50:12.530Z","dependency_job_id":null,"html_url":"https://github.com/nareshbhatia/react-testing-techniques","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nareshbhatia%2Freact-testing-techniques","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nareshbhatia%2Freact-testing-techniques/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nareshbhatia%2Freact-testing-techniques/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nareshbhatia%2Freact-testing-techniques/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nareshbhatia","download_url":"https://codeload.github.com/nareshbhatia/react-testing-techniques/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230537062,"owners_count":18241515,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cypress","jest","mock-service-worker","react","react-testing-library","storybook","testing"],"created_at":"2024-11-07T13:31:59.413Z","updated_at":"2024-12-20T05:08:41.648Z","avatar_url":"https://github.com/nareshbhatia.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React Testing Techniques\n\nThis project demonstrates best practices in testing React applications by\nimplementing a realistic online shopping application. It is also the repository\nfor my Medium article titled\n[React Testing Techniques](https://medium.com/engineered-publicis-sapient/react-testing-techniques-d97e9dd8f081).\n\nP.S. If you find this project useful, please show your appreciation by starring\nthis repository.\n\n## Tools of the trade\n\n**Unit \u0026 Integration Testing**\n\n- [Jest](https://jestjs.io/) - a testing framework designed to ensure\n  correctness of any JavaScript or TypeScript codebase\n\n- [React Testing Library](https://testing-library.com/) - a testing framework\n  for React components that encourages better testing practices\n\n- [Mock Service Worker](https://mswjs.io/) - a framework to mock APIs by\n  intercepting requests at the network level. It allows us to reuse the same\n  mock definition for testing, development, and debugging.\n\n**End-to-End Testing**\n\n- [Cypress](https://www.cypress.io/) - a testing framework for fully built Web\n  applications running in a browser\n\n**Manual Testing**\n\n- [Storybook](https://storybook.js.org/) - a tool that helps build components in\n  isolation and record their states as stories. Stories make it easy to explore\n  a component in all its permutations no matter how complex. They also serve as\n  excellent visual test cases. Storybook testing can also be automated. For\n  details, look at the\n  [Storybook documentation](https://storybook.js.org/docs/react/workflows/testing-with-storybook).\n\n_This project was bootstrapped with\n[React Accelerate](https://github.com/PublicisSapient/cra-template-accelerate)._\n\n## Why do we write tests?\n\nFor me, writing tests is about building confidence in what I am delivering.\nTests provide a mechanism to verify the intent of my code by exercising it in\nvarious ways. Moreover, they give me the confidence that I have not broken\nanything when I refactor or extend the code to meet new requirements. The last\nthing I want is to get a call at 3:00 AM to fix a bug that has crashed my app!\n\n## Guiding principles when writing tests\n\nThe principles listed in this section are based on an article by Kent C. Dodds\ntitled\n[Write tests. Not too many. Mostly integration.](https://kentcdodds.com/blog/write-tests)\nKent is a testing guru with very good guidance on how to test effectively. I\nhave listed several of his useful articles in the references below.\n\nSo without further ado, let's jump into the guiding principles.\n\n### Don't test implementation details\n\nIf your test does something that your user doesn't, chances are that you are\ntesting implementation details. For example, you may be exposing a private\nfunction just to test your component. This is a code smell – don't do it. A\nrefactor can easily break your test. Another example is using certain APIs of a\nReact testing tool called [Enzyme](https://enzymejs.github.io/enzyme/), e.g. its\n`instance()`, `state()` and `setState()` APIs. Stay away from such tools,\ninstead use tools that make it harder to test implementation details (e.g.\n[React Testing Library](https://testing-library.com/)).\n\n### Test your components as a user would\n\nThe classic testing wisdom was to write a lot of unit tests to test individual\n\"units\" of code. We used to isolate our components from their environment using\nmocks. It was like testing a fish's swimming abilities out of the water. This\napproach still makes sense for pure functions. But for UI components, which\ndepend on communications with surrounding components, mocking reduces our\nconfidence in their integrations.\n\n\u003e For this reason, the latest thinking is to test several units together to\n\u003e recreate real interaction scenarios, hence the name \"integration testing\".\n\nThis brings us to the guiding principle which is the foundation of the\n[React Testing Library](https://testing-library.com/docs/guiding-principles):\n\n\u003e The more your tests resemble the way your software is used, the more\n\u003e confidence they can give you.\n\nFor example, drop a couple of components under a `\u003cContext.Provider\u003e` to test\nreal user interactions. You could also use\n[Mock Service Worker](https://mswjs.io) to mock APIs at the network level rather\nthan excessively mocking at the component or service layer. We will talk more\nabout this in the testing techniques section below.\n\n### Focus on use case coverage\n\nThere is a tradeoff between time spent writing tests and code coverage. Some\norganizations put undue focus on code coverage. Unfortunately this sets the\nwrong goal for developers. You start seeing people gaming the system by writing\nmeaningless tests.\n\nInstead, focus on _use case coverage_. Think of all the use cases (including\ncorner cases) that you want to test to feel confident about your code. This\napproach by itself generally yields high code coverage. The tests in this\nproject were written with use case coverage in mind and yet as a byproduct we\nhave upwards of 90% code coverage! It is generally accepted that 80% coverage is\na good goal to aim for.\n\n### Push business logic into pure functions rather than UI components\n\nFor example, a Shopping Cart UI component should not compute the cart total.\nThis should be pushed to a\n[pure function](https://en.wikipedia.org/wiki/Pure_function) because it is\neasier to test. Even better, push it off to the back-end where more\nsophisticated calculations can be performed without complicating the UI. See\n[here](./src/models/Cart.ts) for examples for pure functions and the\n[related tests](./src/models/Cart.test.ts).\n\n## Testing Techniques\n\nNow that we understand why we test the way we do, let's go over 12 techniques\nyou can apply now.\n\n1. [Setting up React Testing Library](./docs/setting-up-react-testing-library.md)\n2. [Functional testing vs. snapshot testing vs. screenshot testing](./docs/functional-vs-snapshot-vs-screenshot-testing.md)\n3. [Difference between queryBy, getBy and findBy queries](./docs/difference-between-query-types.md)\n4. [Checking for existence of an element](./docs/checking-for-existence-of-an-element.md)\n5. [Waiting for removal of an element](./docs/waiting-for-removal-of-an-element.md)\n6. [Waiting for something to happen](./docs/waiting-for-something-to-happen.md)\n7. [fireEvent() vs userEvent](./docs/fireEvent-vs-userEvent.md)\n8. [Mocking an event handler](./docs/mocking-an-event-handler.md)\n9. [Avoid mocking by using Mock Service Worker](./docs/avoid-mocking-by-using-mock-service-worker.md)\n10. [Overriding MSW handlers](./docs/overriding-msw-handlers.md)\n11. [Testing page navigation](./docs/testing-page-navigation.md)\n12. [Suppressing console errors](./docs/suppressing-console-errors.md)\n\n## Getting Started\n\n\u003e Note: If you prefer to use npm, please feel free to replace the yarn commands\n\u003e in this section with equivalent npm commands.\n\nMake sure your development machine is set up for building React apps. See the\nrecommended setup procedure\n[here](https://github.com/nareshbhatia/react-learning-resources#developer-machine-setup).\n\nExecute the following commands to install dependencies:\n\n```sh\nyarn install\n```\n\nExecute the following commands to run the app:\n\n```sh\nyarn start\n```\n\nNow point your browser to http://localhost:3000/.\n\n## Running Unit Tests\n\nExecute one of the following command to run unit tests.\n\n```sh\nyarn test # interactive mode\n\n# OR\n\nyarn test:coverage # non-interactive mode with coverage information\n```\n\n## Running End-to-End Tests\n\n```sh\nyarn start # starts a local server hosting your react app\n\n# in a difference shell, run cypress\nyarn cypress:open\n```\n\n## Running Storybook\n\n```sh\nyarn storybook\n```\n\n## Running In Production Mode\n\nBecause MSW is disabled in production mode, you must first run an external API\nserver. To do this, clone the\n[React Test Shop Server](https://github.com/nareshbhatia/react-test-shop-server)\nrepository and follow the instructions there to start an API server on\nport 8080.\n\nNow build this project in production mode and start it using a web server like\n`serve`:\n\n```sh\nyarn build\nserve -s build\n```\n\n## Screenshots\n\n### Home Page\n\n![Home Page](assets/screenshot-home.png)\n\n### Checkout Page\n\n![Checkout Page](assets/screenshot-checkout.png)\n\n### Orders Page\n\n![Orders Page](assets/screenshot-orders.png)\n\n## References\n\n### Testing Best Practices\n\n- [How to know what to test](https://kentcdodds.com/blog/how-to-know-what-to-test)\n  by Kent C. Dodds\n- [Write tests. Not too many. Mostly integration.](https://kentcdodds.com/blog/write-tests)\n  by Kent C. Dodds\n- [Write fewer, longer tests](https://kentcdodds.com/blog/write-fewer-longer-tests)\n  by Kent C. Dodds\n- [Making your UI tests resilient to change](https://kentcdodds.com/blog/making-your-ui-tests-resilient-to-change)\n  by Kent C. Dodds\n- [Testing Implementation Details](https://kentcdodds.com/blog/testing-implementation-details)\n  by Kent C. Dodds\n\n### Jest\n\n- [Documentation](https://jestjs.io/docs/getting-started)\n\n### React Testing Library\n\n- [Introduction](https://testing-library.com/docs/)\n- [Guiding Principles](https://testing-library.com/docs/guiding-principles)\n- [Example](https://testing-library.com/docs/react-testing-library/example-intro)\n- [Cheatsheet](https://testing-library.com/docs/react-testing-library/cheatsheet)\n- [Query Priority Guidelines](https://testing-library.com/docs/queries/about/#priority)\n- [Common mistakes with React Testing Library](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library)\n\n### Storybook\n\n- [Introduction to Storybook](https://storybook.js.org/docs/react/get-started/introduction)\n\n### Mock Service Worker\n\n- [Documentation](https://mswjs.io/docs/)\n\n### Cypress\n\n- [Documentation](https://docs.cypress.io/guides/overview/why-cypress)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnareshbhatia%2Freact-testing-techniques","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnareshbhatia%2Freact-testing-techniques","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnareshbhatia%2Freact-testing-techniques/lists"}