{"id":26652622,"url":"https://github.com/subraatakumar/react-testing-library","last_synced_at":"2026-01-05T18:03:43.754Z","repository":{"id":101512178,"uuid":"600482532","full_name":"subraatakumar/react-testing-library","owner":"subraatakumar","description":null,"archived":false,"fork":false,"pushed_at":"2023-02-11T16:27:59.000Z","size":13,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T03:57:31.988Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"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/subraatakumar.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}},"created_at":"2023-02-11T16:26:04.000Z","updated_at":"2023-02-11T16:27:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"506eab24-d20b-475d-bef6-7dc348c264a0","html_url":"https://github.com/subraatakumar/react-testing-library","commit_stats":null,"previous_names":["subraatakumar/react-testing-library"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/subraatakumar/react-testing-library","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subraatakumar%2Freact-testing-library","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subraatakumar%2Freact-testing-library/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subraatakumar%2Freact-testing-library/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subraatakumar%2Freact-testing-library/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/subraatakumar","download_url":"https://codeload.github.com/subraatakumar/react-testing-library/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subraatakumar%2Freact-testing-library/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28217888,"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","status":"online","status_checked_at":"2026-01-05T02:00:06.358Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-03-25T03:57:34.662Z","updated_at":"2026-01-05T18:03:43.724Z","avatar_url":"https://github.com/subraatakumar.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# React Testing\n\n## What should you test ?\n\n- High value features\n- Edge cases in high value features\n- Things that are easy to break\n- Basic React component testing\n    - User Interactions\n    - Conditional Rendering\n    - Utils/Hooks\n\n## Manual Vs. Automation Testing\n\nIt's important to make the distinction between manual and automated tests. Manual testing is done in person, by clicking through the application or interacting with the software and APIs with the appropriate tooling. This is very expensive since it requires someone to setup an environment and execute the tests themselves, and it can be prone to human error as the tester might make typos or omit steps in the test script.\n\nAutomated tests, on the other hand, are performed by a machine that executes a test script that was written in advance. These tests can vary in complexity, from checking a single method in a class to making sure that performing a sequence of complex actions in the UI leads to the same results. It's much more robust and reliable than manual tests – but the quality of your automated tests depends on how well your test scripts have been written.\n\n## Types of Testing\n\n- Unit Testing\n\nUnit tests are very low level and close to the source of an application. They consist in testing individual methods and functions of the classes, components, or modules used by your software. Unit tests are generally quite cheap to automate and can run very quickly by a continuous integration server.\n\n- Integration\n\nIntegration tests verify that different modules or services used by your application work well together. For example, it can be testing the interaction with the database or making sure that microservices work together as expected. These types of tests are more expensive to run as they require multiple parts of the application to be up and running.\n\n- End to End\n\nEnd-to-end testing replicates a user behavior with the software in a complete application environment. It verifies that various user flows work as expected and can be as simple as loading a web page or logging in or much more complex scenarios verifying email notifications, online payments, etc...\n\nEnd-to-end tests are very useful, but they're expensive to perform and can be hard to maintain when they're automated. It is recommended to have a few key end-to-end tests and rely more on lower level types of testing (unit and integration tests) to be able to quickly identify breaking changes.\n\n## Other Types of Testing\n\nIn addition to above three there are other types of testing as below :\n\n- Acceptance Testing\n\nAcceptance tests are formal tests that verify if a system satisfies business requirements. They require the entire application to be running while testing and focus on replicating user behaviors. But they can also go further and measure the performance of the system and reject changes if certain goals are not met.\n\n- Performance Testing\n\nPerformance tests evaluate how a system performs under a particular workload. These tests help to measure the reliability, speed, scalability, and responsiveness of an application. For instance, a performance test can observe response times when executing a high number of requests, or determine how a system behaves with a significant amount of data. It can determine if an application meets performance requirements, locate bottlenecks, measure stability during peak traffic, and more. \n\n- Somke Testing\n\nSmoke tests are basic tests that check the basic functionality of an application. They are meant to be quick to execute, and their goal is to give you the assurance that the major features of your system are working as expected.\n\nSmoke tests can be useful right after a new build is made to decide whether or not you can run more expensive tests, or right after a deployment to make sure that they application is running properly in the newly deployed environment.\n\nIn this course we will learn about `Unit Testing` and `Integration Testing`.\n\n## Create A New React App\n\n```js\nnpx create-react-app@latest testing\ncd testing\ncode . // Open the code in VSCode\n```\n\nnow open package.json file. You will see the below lines in dependencies.\n\nAs we are using create-react-app, Jest (and React Testing Library) comes by default with the installation. If you are using a custom React setup, you need to install and set up Jest (and React Testing Library) yourself.\n\n```js\n    \"@testing-library/jest-dom\": \"^5.16.5\",\n    \"@testing-library/react\": \"^13.4.0\",\n    \"@testing-library/user-event\": \"^13.5.0\",\n```\n\nJest offers you the following functions for your tests:\n\n```js\ndescribe('my function or component', () =\u003e {\n  it('does the following', () =\u003e {\n    expect(something).toBe(anotherthing);\n  });\n});\n```\n\n- describe: It is the test suite which can have multiple test cases.\n- it: It is the test case. we can also name it `test` instead of `it`.\n- expect: It is called assertion. It either turn out to be successful (green) or erroneous (red).\n\n## Write first test case\n\nOut App.test.js file already have test cases. below that add this test case.\n\n```js\ndescribe('true is truthy and false is falsy', () =\u003e {\n  it('true is truthy', () =\u003e {\n    expect(true).toBe(true);\n  });\n\n  it('false is falsy', () =\u003e {\n    expect(false).toBe(false);\n  });\n});\n```\n\nNow your App.test.js may look like below:\n\n```js\nimport { render, screen } from '@testing-library/react';\nimport App from './App';\n\ntest('renders learn react link', () =\u003e {\n  render(\u003cApp /\u003e);\n  const linkElement = screen.getByText(/learn react/i);\n  expect(linkElement).toBeInTheDocument();\n});\n\ndescribe('true is truthy and false is falsy', () =\u003e {\n  it('true is truthy', () =\u003e {\n    expect(true).toBe(true);\n  });\n\n  it('false is falsy', () =\u003e {\n    expect(false).toBe(false);\n  });\n});\n```\n\nNow go to terminal and run the below command \n\n```js\nnpm run test\n```\n\nWhen we run the test command, Jest's test runner matches all files with a test.js suffix by default. You could configure this matching pattern and others things in a custom Jest configuration file.\n\nOutput:\n\n![](https://firebasestorage.googleapis.com/v0/b/mymasai-school.appspot.com/o/react-testing%2Ftest1.JPG?alt=media\u0026token=7b7795a2-6aa4-4081-9622-3d11c9d959ed)\n\n\nNote: If you are using any `Jest` extension in Vs-Code then you can see the green ticks in VS Code itself.\n\n![](https://firebasestorage.googleapis.com/v0/b/mymasai-school.appspot.com/o/react-testing%2Ftest2.JPG?alt=media\u0026token=a39215b9-7c2c-494f-8411-dba498127480)\n\nIn a real world project, your javascript function will be in another file and test cases will be on another. Let's create below two files.\n\n```js\n// sum.js\nfunction sum(a,b){\n    return a+b;\n}\n\nexport default sum;\n```\n\n```js\n// sum.test.js\nimport sum from \"./sum\";\n\ndescribe(\"sum of 2 and 4 should be 6\", () =\u003e {\n  it(\"sums up two values\", () =\u003e {\n    expect(sum(2, 4)).toBe(6);\n  });\n});\n```\n\n## Summary Till Now\n\nJest is a test runner, which gives you the ability to run tests from command line. It offers us functions for test suits, test cases and assertions. \n\n## VITEST VS REACT TESTING LIBRARY\n\nVitest is a popular alternative to Jest, especially when being used in Vite. Vitest can be seen as direct replacement to Jest, because it also comes with a test runner, test suites (describe-block), test cases (it-block), and assertions (e.g. expect). I recommend Vitest to everyone who is using Vite instead of create-react-app (also recommended) for single page applications. You can also use React Testing Library in Vite.\n\n## RTL: Rendering a component\n\nRTL's render function takes any JSX as argument to render it as output. Afterward, you should have access to the React component in your test. To convince yourself that it's there, you can use RTL's debug function.\n\n```js\n// Counter.jsx\nimport React, { useState } from \"react\";\n\nconst Counter = () =\u003e {\n  const [ counter, setCounter ] = useState(0);\n\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eCounter App\u003c/h1\u003e\n      \u003cbutton onClick={() =\u003e setCounter((prev) =\u003e prev - 1)}\u003e-\u003c/button\u003e\n      {counter}\n      \u003cbutton onClick={() =\u003e setCounter((prev) =\u003e prev + 1)}\u003e+\u003c/button\u003e\n    \u003c/div\u003e\n  );\n};\n\nexport default Counter;\n```\n\n```js\nimport React from \"react\";\nimport { render, screen } from \"@testing-library/react\";\nimport Counter from './Counter'\n\ndescribe('\u003cCounter /\u003e',()=\u003e{\n    test('counter renders successfully',()=\u003e{\n        render(\u003cCounter /\u003e);\n        screen.debug();\n    })\n})\n```\n\nOutput:\n\n```js\n    \u003cbody\u003e\n      \u003cdiv\u003e\n        \u003cdiv\u003e\n          \u003ch1\u003e\n            Counter App\n          \u003c/h1\u003e\n          \u003cbutton\u003e\n            -\n          \u003c/button\u003e\n          \u003cbutton\u003e\n            +\n          \u003c/button\u003e\n        \u003c/div\u003e\n      \u003c/div\u003e\n    \u003c/body\u003e\n```\n\nAfter running your test on the command line, you should see the HTML output of your component. The great thing about it, React Testing Library doesn't care much about different React features (useState, event handler, props) and concepts (controlled component).\n\n## RTL : Selecting Elements\n\nAfter you have rendered your React component(s), React Testing Library offers you different search functions to grab elements. These elements are then used for assertions or for user interactions. But before we can do these things, let's learn about how to grab them:\n\n```js\nimport React from \"react\";\nimport { render, screen } from \"@testing-library/react\";\nimport Counter from \"./Counter\";\n\ndescribe(\"\u003cCounter /\u003e\", () =\u003e {\n  test(\"counter renders successfully\", () =\u003e {\n    render(\u003cCounter /\u003e);\n    screen.debug();\n    //expect(screen.getByText(/Counter app/i)).toBeInTheDocument();\n    expect(\n      screen.getByText(\"Counter app\", { exact: false })\n    ).toBeInTheDocument();\n  });\n});\n```\n\nIn the above test assertion, you can use either regex or {exact: false} to ignore the case of letters.\n\n## Search Type and Search Variant \n\nIn `getByText` , `getBy` is called search variant and `Text` is called search Type.\n\n### Different Search Types\n\n- getByText:\n- getByRole: Based on [implicit roles of html element](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles).\n- getByLabelText: ` \u003clabel for=\"search\" /\u003e`\n- getByPlaceholderText:  `\u003cinput placeholder=\"Search\" /\u003e`\n- getByAltText: `\u003cimg alt=\"profile\" /\u003e`\n- getByDisplayValue: `\u003cinput value=\"JavaScript\" /\u003e`\n- getByTestId: assign `data-testid` attribute in html element\n\n### Different Search Variant\n\n- queryByText\n- queryByRole\n- queryByLabelText\n- queryByPlaceholderText\n- queryByAltText\n- queryByDisplayValue\n\n- findByText\n- findByRole\n- findByLabelText\n- findByPlaceholderText\n- findByAltText\n- findByDisplayValue\n\n## What's the difference between getBy vs queryBy?\n\nThe big question in the room: When to use getBy and when to use the other two variants queryBy and findBy. You already know that getBy returns an element or an error. This makes it difficult to check for elements which shouldn't be there. Because getBy throws an error before we can make the assertion.\n\nSo every time you are asserting that an element isn't there, use queryBy.\n\n```js\ntest(\"There should not be input element\", () =\u003e {\n  render(\u003cCounter /\u003e);\n  // expect(screen.getByRole(\"input\")).toBeNull();\n  expect(screen.queryByRole(\"input\")).toBeNull();\n});\n```\n\nIn above example `getByRole` will through error `TestingLibraryElementError: Unable to find an accessible element with the role \"input\"`.\n\n## When to use findBy?\n\nThe findBy search variant is used for asynchronous elements which will be there eventually.\n\n```js\n// UserScreen.jsx\nimport * as React from \"react\";\n\nconst getUser = () =\u003e {\n  return Promise.resolve({ id: \"1\", name: \"Robin\" });\n};\n\nfunction UserScreen() {\n  const [search, setSearch] = React.useState(\"\");\n  const [user, setUser] = React.useState(null);\n\n  React.useEffect(() =\u003e {\n    const loadUser = async () =\u003e {\n      const user = await getUser();\n      setUser(user);\n    };\n\n    loadUser();\n  }, []);\n\n  function handleChange(event) {\n    setSearch(event.target.value);\n  }\n\n  return (\n    \u003cdiv\u003e\n      {user ? \u003cp\u003eSigned in as {user.name}\u003c/p\u003e : null}\n\n      \u003cSearch value={search} onChange={handleChange}\u003e\n        Search:\n      \u003c/Search\u003e\n\n      \u003cp\u003eSearches for {search ? search : \"...\"}\u003c/p\u003e\n    \u003c/div\u003e\n  );\n}\n\nexport default UserScreen;\n\nfunction Search({ value, onChange, children }) {\n  return (\n    \u003cdiv\u003e\n      \u003clabel htmlFor=\"search\"\u003e{children}\u003c/label\u003e\n      \u003cinput id=\"search\" type=\"text\" value={value} onChange={onChange} /\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n```js\nimport * as React from \"react\";\nimport { render, screen } from \"@testing-library/react\";\n\nimport UserScreen from \"./UserScreen\";\n\ndescribe(\"App\", () =\u003e {\n  it(\"renders App component\", async () =\u003e {\n    render(\u003cUserScreen /\u003e);\n\n    expect(screen.queryByText(/Signed in as/)).toBeNull();\n    expect(await screen.findByText(/Signed in as/)).toBeInTheDocument();\n  });\n});\n```\n\n## [Test-driven development (TDD) ](https://en.wikipedia.org/wiki/Test-driven_development)\n\nIt is a software development process relying on software requirements being converted to test cases before software is fully developed, and tracking all software development by repeatedly testing the software against all test cases. This is as opposed to software being developed first and test cases created later.\n\n```js\n// CommentForm.test.js\nimport React from \"react\";\nimport { render, screen } from \"@testing-library/react\";\nimport CommentForm from \"./CommentForm\";\n\ntest(\"comment form should have textbox\", () =\u003e {\n  render(\u003cCommentForm /\u003e);\n  expect(screen.getByRole(\"textbox\")).toBeInTheDocument();\n});\ntest(\"comment form should have terms and condition\", () =\u003e {\n  render(\u003cCommentForm /\u003e);\n  expect(\n    screen.getByLabelText(\"i agree to terms and conditions\", { exact: false })\n  ).toBeInTheDocument();\n});\ntest(\"comment form should have submit button\", () =\u003e {\n  render(\u003cCommentForm /\u003e);\n  const submit = screen.getByRole(\"button\", { name: \"button\", exact: false });\n  expect(submit).toBeInTheDocument();\n});\ntest(\"comment form submit button should be disabled.\", () =\u003e {\n  render(\u003cCommentForm /\u003e);\n  const submit = screen.getByRole(\"button\", { name: \"button\", exact: false });\n  expect(submit).toBeDisabled();\n});\n\n```\n\n## Multiple Elements\n\n- getAllBy\n- queryAllBy\n- findAllBy\n\n## Assertive Functions\n\nAssertive functions happen on the right hand-side of your assertion.\n\n- toBeDisabled\n- toBeEnabled\n- toBeEmpty\n- toBeEmptyDOMElement\n- toBeInTheDocument\n- toBeInvalid\n- toBeRequired\n- toBeValid\n- toBeVisible\n- toContainElement\n- toContainHTML\n- toHaveAttribute\n- toHaveClass\n- toHaveFocus\n- toHaveFormValues\n- toHaveStyle\n- toHaveTextContent\n- toHaveValue\n- toHaveDisplayValue\n- toBeChecked\n- toBePartiallyChecked\n- toHaveDescription\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsubraatakumar%2Freact-testing-library","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsubraatakumar%2Freact-testing-library","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsubraatakumar%2Freact-testing-library/lists"}