Unit Tests (Jest + React Testing App) Flashcards
What is Unit Testing?
Unit testing is the testing of a single isolated piece of code or group of pieces. Test whether a component produces an expected output when given input.
What is Integration testing
Groups of components are tested together along with the hardware. How multiple units work together (interaction)
Explain following concepts: Suite, Spec, Assertion, Matcher, Test runner
- A set of tests of a particular unit is called a test suite
- A single test within a suite is called a spec
- Assertions produce true or false values by using matchers
- Automated tests are run using test runner
Jest Suite, Spec, Assertion syntax
describe("welcomeMessage") { // Suite it("concats welcome and a name when passed a name") // Spec { let expected = "Welcome, Chris!"; let actual = welcomeMessage("Chris"); expect(actual).toEqual(expected); //Assertion } }
What are the principles of TDD and why is it good?
- Write tests before writing code (write a shell version of the code)
- “red-green” testing (Tests fail before code is written)
- ## Free regression testing
What is the difference between React Testing Library and Jest?
React Testing Library
- Provides virtual DOM for tests
Jest
- Test runner (finds tests, runs tests, determines whether tests pass or fail)
Explain the syntax for running basic tests in Jest and react testing library.
test(‘renders learn react link’, () => {
render();
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});
there is no difference between test and it keywords. - for unit tests. (string description, test function)
describe keyword is for grouping tests into Suites.
render() is a react testing library method for creating virtual dom for JSX argument (component)
it allows us to access virtual DOM via screen global.
What are Jest Assertions?
Assertions determine, whether a test passes or fails.
expect(linkElement).toBeInTheDocument(); }); expect - global, starts the assertion argument - subjecto f the assertion matcher - type of assertion, comes from Jest-DOM
Examples:
expect(element.textContent).toBe(‘hello’);
expect(elementsArray).toHaveLength(7);
Matchers:
.toBeVisible()
.toBeChecked()
We can also include a .not JEST matcher, like:
expect(checkbox).not.toBeChecked(
https://github.com/testing-library/jest-dom
What is jest-dom?
- comes with create-react-app
- src/setupTests.js imports it before each test, makes matchers available.
// import ‘@testing-library/jest-dom’; - DOM-based matchers
What is Jest Watch Mode?
- Watch for changes in files since last commit
- Only run tests related to these files
- No changes? No tests.
What are Acceptance / End-to-end (E2E) Tests
Use actual browser and server (Cypress, Selenium)
What’s the difference between Functional Testing and Unit Testing?
- different mindset: Unit Testing (Isolated: mock dependencies, test internals); Functional testing (Include all relevant units, test behavior)
Mock dependencies - if there are other components/functions that the component is relying on, you use test versions of that instead of actual version.
Accessibility and Finding Elements
Testing Library recommends finding elements by accessibility handles. https://testing-library.com/docs/queries/about/
i. getByRole(‘button’, {name: /submit/i})
ii. getByLabelText: Only really good for form fields, but this is the number one method a user finds those elements, so it should be your top preference
iii. getByPlaceholderText: A placeholder is not a substitute for a label. But if that’s all you have, then it’s better than alternatives.
iv. getByText
v. getByDisplayValue
Semantic queries:
i. getByAltText
ii. getByTitle
Test IDS:
getByTestID - only recommended for cases where you can’t mtch a role or text or it doesn’t make sense (e.g. the text is dynamic).
How do you interact with components (fire events) using react testing library?
We need to import another object from the testing library called:
import { fireEvent } from “@testing-library/react”;
How to set up eslint and prettier for react testing library
1) npm install eslint-plugin-testing-library eslint-plugin-jest-dom
2) remove eslintConfig from package.json
3) create .eslintrc.json and add standard config
{ "plugins": ["jest-dom", "testing-library"], "extends": [ "react-app", "react-app/jest", "plugin:testing-library/recommended", "plugin:testing-library/react", "plugin:jest-dom/recommended" ] }
4) add .eslintcache and .vscode to .gitignore
5) create .vscode/settings.json and add standard config
{ "eslint.options": { "configFile": ".eslintrc.json" }, "eslint.validate": ["javascript", "javascriptreact"], "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true }
6) test that it worked in App.test.js;
How do you handle more advanced events in react testing-library?
Most projects have a few use cases for fireEvent, but the majority of the time you should probably use @testing-library/user-event.
npm install –save-dev @testing-library/user-event
What are react testing library screen Query Methods?
command[All]ByQueryType
command:
- get: expect element to be in DOM
- query: expect element not to be in DOM
- find: expect element to appear async
How do you deal with elements that disappear asynchronously in react testing-library?
We need to make use of asnychronous await waitForElementToBeRemoved(() => screen.queryByText(/no ice cream will actually be delivered/i);
Which will throw an error if the element is not removed from the document.
What is Mock Service Worker and what is its purpose
Mock Service Worker - intercept network calls - return specified responses Prevent network calls during tests Set up test conditions using server response
Setup: 1) npm install msw 2) create handlers export const handlers = [ rest.get("http://localhost:3030/scoops", (req, res, ctx) => { return res( ctx.json([ { name: "Chocolate", imagePath: "/images/cholocate.png" }, { name: "Vanilla", imagePath: "/images/vanilla.png" }, ]) ); }), ]; 3) create test server import { setupServer } from "msw/node"; import { handlers } from "./handlers";
// This configures a request mocking server with the given request handlers. export const server = setupServer(...handlers);
4) make sure test server listens during all tests (in setupTests.js file)
import { server } from “./__mocks__/server.js”;
// Establish API mocking before all tests.
beforeAll(() => server.listen());
// Reset any request handlers that we may add during the tests,
// so they don’t affect other tests.
afterEach(() => server.resetHandlers());
// Clean up after the tests are finished.
afterAll(() => server.close());
How do you run and debug only selected tests?
You can run only selected tests from the jest cli, by running only those with certain regex.
test. only() will run only the selected test,
test. skip() will skip the selected test
How do you access Context Provider inside of your tests?
In order to access the provider in your tests, you need to wrap, your component that is rendered with it’s provider, by passing a wrapper property in the render function.
render(, {
wrapper: OrderDetailsProvider,
});
How do you setup custom render method, that can include things like global context providers, datastores etc?
We want to override default testing library render, with our own render that includes the wrapper.
In order to do that, we should create a test-utils folder, with testing-library-utils.js
// import render method from @testing-library/react, import the context provider
import { render } from “@testing-library/react”;
import { OrderDetailsProvider } from “../contexts/OrderDetails”;
// write a custom function that wraps render with a wrapper. const renderWithContext = (ui, options) => render(ui, { wrapper: OrderDetailsProvider, ...options });
// export all functionalities from testing library and add renderWithContext as render export * from "@testing-library/react"; export { renderWithContext as render };