If React is a bit of a new concept to you I highly suggest taking ten minutes to work through the official tutorial - it’s a worthy investment.
If you’d like to follow along by writing code (I strongly suggest you do) you need should clone this boilerplate for a quick start.
git clone https://github.com/jarsbe/react-webpack-boilerplate test-suite
Firstly we need something to test. The application we’ll create is simply (stupid) point of sale tool. There will be two components; an
App component which contains a list of items and a
Checkout component which contains a list of all selected items. The
Checkout component also has a counter for the total number of selected items. An item can be selected by clicking on it. I told you it was simple!
If you are coding along replace the
main.js file with the following code.
Next remove the
component.js file and create the
Take 5 minutes to read how the application works. To run the application execute
webpack -w (install webpack if you need it), in another terminal change directory into the site
cd site and run a server
python -m SimpleHTTPServer. Now the application is available on
http://localhost:8000. Time to get testing.
To build a test suite we need tools. Facebook uses Jest, which is a layer upon Jasmine. Jest offers automatic mocking and uses JSDom for running tests in the command line (rather than the browser). Automatic mocking is useful since we’ll be testing components in isolation, all of our dependencies will be mocked by Jest. Take a look here for more information on automatic mocking. Along with Jest we need React Tools to transform any JSX during testing, this is optional but very helpful.
To install these tools.
npm install jest-cli react-tools --save-dev
To transform JSX a helper function is required. In a
support folder create a
preprocessor.js file to do the work.
To use the preprocessor add this configuration inside the
package.json file. It adds test script and informs Jest of the preprocessor function. It also makes sure that React itself is not automatically mocked!
Next add a folder called
__tests__ in the root directory. Jest is magical enough to automatically run any test in any files sitting in this directory.
Just for sanity run
npm test. Jest should run and everything should pass with flying colours.
The simplest component is the
Checkout. It accepts only one property
items and generates a list from those
Checkout also calculates a total
To get this component tested create a
checkout-test.js file inside the
__tests__ directory. It also needs some boilerplate code like so.
Here Jest is told not to mock the
Checkout component then all the necessary dependencies are required. Finally there are two empty tests; one to check each item is rendered, the next to make sure the item count is correct.
To get these tests running you need to create an instance of the component, give it some items to render and finally select the DOM nodes to test.
The final piece of the puzzle is to add the expectations to each test.
Nice and simple. We make sure there are two
li nodes and that the items count is correct. The nice thing about React is that it’s simple to test. The
Checkout component is given data and the tests make sure it renders as expected. You can see this pattern again after testing the
These tests follow the same create a component, give it data and expect output pattern. There’s also the added complexity of component state and function calls. Clicking an item in the
App list should add that item to the
Checkout list. This happens via a state change in
App. The only thing we need to test is that clicking on an item adds it to the state’s selected items array.
A few things that helped me was figuring out where to look in the documentation. Since I’m using 3 different tools (Jest, Jasmine & React Tools) it was confusing at first. I got started by looking at Jest specifically the React section and then reading the API (which is very concise). Next I had a look through both the Jasmine Guide and the React Test Utils. It’s a bit strange looking through 3 sets of documentation, but they work surprisingly well together.
As a final note you may have noticed everything is using CommonJS like modules. As a Rails developer this is very foreign and almost a reason to avoid testing all together. Don’t fret however, you can have your cake and eat it too. I strongly suggest reading James McCann’s post on incorporating Webpack with Rails.