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 remote origin/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 in jsdom. The reason being is that browsers can be finicky and lead tests to be fragile. But, I don't deliver to jsdom.

jest runs in nodejs, 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: