Watch the bar turn green with TDD
When there are bugs, there is probably nothing more pleasing than figure out a way to:
- Write a failing unit test that reproduces that bug.
- Fix it and watch the bar turn green again, forever and ever 😉
If your goal is to stay green for all of your existing tests by using the Test Driven Development (TDD) approach, you need to mentally train yourself to:
- Think about the behavior around the next pieces of functionalities that you need in your code, then start moving towards your end goal in tiny steps and you will end up seeing tangible progress every moment.
- Write unit test first, they shouldn’t be written as an extra chore when you finally have the code already working, this is called Test-Driven Development.
If you are designing an application to expose your data sources as REST API endpoints or as a unique GraphQL endpoint, TDD will definitely help you to design and maintain your APIs better. So if you are a principled developer who writes the tests that exercise the API first, you will discover where the APIs get complex to use before you even write the code, and you will be free to redesign much more easily than if you only add the tests afterwards.
Test the UI
Thanks goodness Create-React-App comes with Jest as its test runner and jest-dom for improved assertions. In combination with a state of the art package called the react-testing-library you will enjoy testing any React Component behavior or any Function or Hook’s inputs and outputs.
RTL Principle:
“The more your tests resemble the way your software is used, the more confidence they can give you.”
Another cool friendly kid in the hood is:
First thing you need to ask is: why we would want to mock fetch requests?
Because you use fetch to allow your App to interact with the rest of world, using:
- Client-side JavaScript to trigger a network request to some local or remote backend API.
- Server-side JavaScript talks to other local or remote servers.
Because you want to make sure your code doesn’t depends of flaky externalities, you want to ensure to produce the exact same output given the same inputs.
Setup your test environment
- docs/running-tests/#initializing-test-environment
- docs/en/configuration#collectcoveragefrom-array
- docs/en/configuration#coveragethreshold-object
Initial configuration:
...
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}",
"!src/**/index.{js,jsx,ts,tsx}",
"!src/config/*",
"!src/index.js",
"!src/serviceWorker.js"
],
"coverageThreshold": {
"global": {
"branches": 90,
"functions": 90,
"lines": 90,
"statements": 90
}
},
"coverageReporters": [
"text-summary"
]
}
...
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"test-changed": "npm test --watchAll=false",
"test-coverage-text": "npm test -- --coverage --coverageReporters=\"text\" --watchAll",
"test-coverage-text-summary": "npm test -- --coverage --coverageReporters=\"text-summary\" --watchAll",
"eject": "react-scripts eject"
}
...
"devDependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"@testing-library/react-hooks": "^3.4.1",
"jest-fetch-mock": "^3.0.3",
"react-test-renderer": "^16.13.1"
}
...
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 src/setupTests.js to your project. It will be automatically executed before running your tests.
// https://github.com/testing-library/jest-dom
import "@testing-library/jest-dom/extend-expect";
// https://github.com/jefflau/jest-fetch-mock
import fetchMock from "jest-fetch-mock";
fetchMock.enableMocks();
Code Sample
git clone https://github.com/josoroma/reactjs-challenge.git
Routes
Components
You should test components’ behavior only.
App
States
States.lazy
Toolbar
Custom Hooks (renderHook())
You should test functions’ inputs and outputs only.
SearchValue Dispatch Hook
SearchValue State Hook
Context Reducer Function
Service Function
Util Function
Happy hacking!!!
Tip: If you are a great team player and the project is going through a long maintenance process, you should probably start writing tests for untested code, just seeing the Coverage Report as a G.A.M.E.