Jest and Enzyme
- Jest is a fully feature testing framework not just for React
- Enzyme is a library that makes testing React components specifically easier
- If you are using React in your application, it might make sense to use Enzyme and Jest together to automatically test your UI
- Many people use Jest as a test runner and assertion library, then use Enzyme to build the tests for their UI
Jest compares snapshots
- Snapshot is a saved fragment of HTML generated by your application
- when Jest run tests, it compares the output of rendering a component with the saved snapshot HTML, it they are the same, then the tests passes.
Issues with snapshots
- if your component has many states, you have to create a snapshot for each state.
Enzyme
- Enzyme renders the component in memory, then provides a series of APIs to examine the component’s properties
Shallow rendering
- only render that component itself, Enzyme doesn’t render any of the children of that component
- then you could use functions like
find()
orfindWhere()
to find the element within the component
Full rendering
- useful for integration testing, where you need to test multiple components and how they work together
Introduction
Create react app
- npm package
- Creates react application with
- configuration
- webpack and babel
- webpack will bundle all your code in one file
- babel will translate react to the code that our browser can understand
- web server
- to run our app on localhost
- testing library
npx
- downloads the latest version of create-react-app templates every time
- not dependent on when you last installed create-react-app
- it is never installed on your laptop
Breaking down syntax
- render
- create virtual DOM for argument JSX
- screen
- global object to access virtual DOM
screen.getByText()
to find element by display text
- expect
- assertion, causes test to succeed to fail
Jest and React Testing Library
- React Testing Library helps with
- rendering components into virtual DOM
- searching virtual DOM
- interacting with virtual DOM
- needs a test runner
- find tests, run them, make assertions
- Jest is the test runner
- is recommended by Testing Library
- comes with create-react-app
npm test
runs an npm script that runs Jest in watch mode
Jest Watch mode
- watch for changes in files since last commit
- only run tests related to these files
- no changes? no tests.
How does Jest work
- global
test
method has two arguments- string description
- test function
- test fails if error is thrown when running function
- assertions throw errors when expectation fails
- no error -> tests pass
- empty test passes
TDD
- write tests before writing code
- then write code according to spec set by tests
- red green testing
- tests fail before code is written
React Testing Library
- creates virtual DOM for testing
- and utilities for interacting with DOM
- allows testing without a browser
Types of tests
- Unit test
- tests one unit of code in isolation
- mock dependencies, test internals
- easy to pinpoint failures but further from how users interact with software
- more likely to break with refactoring
- Integration tests
- how multiple units work together
- functional tests
- tests a particular function of software
- you are not testing your code, you are testing a behavior
- close to how users interact with software
- more difficult to debug failing tests (tests are not tightly coupled with the code)
- e.g. enter data in form and click submit
- acceptance E2E tests
- use actual browser and server (Cypress, Selenium)
BDD
- Behavior driven development
- testing library encourages testing behavior over implementation
- but we still call it TDD, why?
- because BDD is very explicitly defined
- involves collaboration between lots of roles
- developers, QA, business partners, etc…
- defines process for different groups to interact
Unit testing functions
- functions separate from components
- used by several components
- complex logic
- unit test if
- complex logic difficult to test via functional tests
- too many edge cases
Review
- Test interactivity using
fireEvent
userEvent
is more popular thanfireEvent
- jest DOM assertions
toBeEnabled()
toBeDisabled()
toBeChecked()
getByRole
optionname
- jest
describe
to group tests
ESLint and Prettier
ESLint
- Linter
- analyzes static text and marks syntax that breaks rules
- Static
- analyze code as written, not what happens when code is run
- Popular linter for JavaScript
- linting keeps code style consistent
- especially for multi engineer projects
- also catches errors in code
- using variable before defining
- importing from non-existing file
- etc…
Linting vs Formatting
- Formatters (like prettier) automatically format code
- linters address format and code style
- enforce best practices
Sundaes on Demand: Form review and popover
- more complex user interactions
- multiple form entry, moving through order phases
- mouseover popup
- test that element disappears from DOM
- simulating server response
- mock service worker (without the need of a real backend server)
- mock responses from server
- async app updates
- tell assertion to wait until DOM changes
- global state via context
Code organization
- organize components by pages
test
directory for each page- Jest will find and run any files that end in
.test.js
screen Query methods
- get: expect element to be in DOM
- query: expect element NOT to be in DOM
- find: expect element to appear async
Check that tests can fail
- sometimes tests pass because of async and assertions don’t have a chance to run before the tests end.
- so it is a good habit to check that the tests can fail as well as pass
wait for element to disappear
1 | // popover disappears when we mouse out |
- sometimes the disappearance of elements is happening asynchronously, so we need to wait for it before doing assertions
Review
userEvent.hover
anduserEvent.unhover
queryByText
async waitForElementToBeRemoved
test not wrapped in act(...)
warning- determine how component is getting updated async and account for in tests