Our Simple ReactJS-Redux App to Unit Test (UT)
Our app is going to get head start as a fork of David Zukowski's excellent react-redux-starter-kit that he has provided on GitHub.1
My fork, gkedge/ReactJS-Redux-Unit-Testing, leaves David's master branch intact. I have added section-specific branches that provide you a starting point for each section. E.g.: checking out the unit-test-start
branch will provide all the source files and test files, but they are escentially empty to start.
The unit-test-*
branches replace David's route examples with a route that will do real service calls to mockey.io that I have set up to return some Computer Science 'universal truths'.
Info
Though running the app in the browser will hit the remote mockey.io server for our data, all unit testing will 'mock' those remote service calls; mocking-the-mockey, if you will. Thou shalt not slow down any UT's for service calls! Ever. {mic drop}
David's unchanged work is always available on the master
branch. I intend to update that master
on occasion and merge his updates into the unit-test-*
branches.
--- Footnotes ---
1. David's kit separates itself from the many other 'starter' kits available in the public space by demostrating through example routes how to load just enough JS/CSS to support a given page or route. Justin Greenberg collaborated with David to introduce a file heirarchy to the kit they call 'Fractal Project Structure' that logically infers each route and scales well.
tl;dr
The unit-test-complete
branch on my gkedge/ReactJS-Redux-Unit-Testing fork is a complete version of what we are working through in this tutorial.
Clone and install npm
packages
Substitute the unit-test-complete
branch for unit-test-start
if you want the finished, fully tested and implemented solution.
clone my fork to your working space
$ git clone --progress https://github.com/gkedge/ReactJS-Redux-Unit-Testing.git $ cd ReactJS-Redux-Unit-Testing
checkout the
unit-test-start
branch following my remoteorigin/unit-test-start
$ git checkout -b unit-test-start origin/unit-test-start
Note
After that one-time local branch creation you just added to your local Git repository that will henceforth 'follow' my remote
origin/unit-test-start
, you can flip between locally created branches by simply checking out that local branch. E.g.:$ git checkout unit-test-start
Just commit local changes to your repository for your active branch prior to checking out a different branch. Don't worry, git will remind you if you forget. To commit local changes:
$ git commit
install the kit's dependent packages listed within
package.json
$ npm install
UT support packages within react-redux-starter-kit
…
… and therefore in my fork, are now all installed. I don't want to spend a lot of time covering all the tool support that David's kit includes, but for our unit testing purposes, we will take advantage of a number or unit test focused packages he provides.
package | part played in UT ecosystem |
---|---|
mocha | A feature-rich JavaScript test framework. Cheat Sheet |
chai | a BDD \/ TDD assertion library. Cheat Sheet |
sinon | isolation through spies & stubs. Cheat Sheet |
sinon-chia | extends Chai with assertions for the Sinon.JS mocking framework. Cheat Sheet |
fetch-mock | mock fetch to mock service calls |
enzyme | makes it easier to assert, manipulate, and traverse React Component content. |
chai-enzyme | Chai assertions for enzyme |
redux-mock-store | mock store for testing redux action creators and middleware. |
Istanbul | code coverage |
karma | test runner exersizing browsers in parallel. |
The TDD Magic of karma
and File Watchers
We will be using karma
to enable us to rerun our test suite simply by saving a source or test file. [Most config file changes require a restart of karma.]
jest
was considered but there were trade-offs that I am unwilling to make. The trade-offs are intentional and therefore appeal to a great many of teams interested in testing their ReactJS apps.
jest
does not run tests in real browsers; they run injsdom
. The reason being is that browsers can be finicky and lead tests to be fragile. But, I don't deliver tojsdom
.
jest
runs innodejs
, not the cozy confines of a Chrome debugger. To understand what is failing in a test, currently, you need to attach Node Inspector, the node debugger. Karma offers a much easier and familiar debugging pattern to me. I am testing; debugging tests seems important.If
jest
runs in its default parallel tests mode, it can run very slooooow in CI environments. Forcing it to run tests serially to make it run faster seems to be a remedy for a desirable, fundamental feature that is half-baked at this point.
This video will show the desired effect of having karam
run the test suite at launch and automatically rerunning the test suite on a file save. This allows the developer to write tests that fail and the add the expected behavior being tested to the real code in rapid Test Driven Development (TDD) style: