I thought I’d share the React testing tool I’ve been building this past week: rehook-test.
Personally, testing front end apps has been a pain point for me (in any language). However, I think Clojurescript has a pretty nice story here, where you are able to test the data layer easily.
But I often find that over time the view goes out of sync with the data layer.
So this is the initial cut of a library aimed to solve the above problem. It is built on top of the rehook library.
Basically, you write tests using a DSL on top of cljs.test
and get both headless nodejs tests + an interactive test report. The end result is something between devcards and Kafka’s TestTopologyDriver, I guess.
Tests comprise of two basic primitives: io
and is
:
-
io
- some side-effect that will produce another render (eg HTTP call, DOM event) -
is
- likecljs.test/is
– an assertion about the current state of the mounted component
An example test looks like this:
(ns todo-test
(:require [rehook.test :refer-macros [defuitest is io initial-render next-render]
[todomvc.core :as todo]])
(defuitest todo-app--add-new-item
[[scenes {:keys [dispatch subscribe]}] (test-ctx todo/todo-app)]
(-> (initial-render scenes
(let [items (subscribe [:todos])]
(is "Subscription should contain 5 items"
(= items todo/initial-items)))
(io "Dispatch :add-todo"
(dispatch [:add-todo "Write more tests"])))
(next-render
(let [items (subscribe [:todos])]
(is "After adding item, there should be 6 TODOs"
(= 6 (count items)))))))
We use the initial-render
and next-render
macros to scope our test body to a particular snapshot in time.
I made a video demonstrating the features of the library:
You can view the unit tests for the todomvc example here
The above unit tests generated this demo report. And you can see the same unit tests running in a CI environment here
All source code is available here
The test DSL + report UI is still a WIP, but I’m keen for any feedback!
A few notes on where I’d like to take this project:
- I want Git-like diffs between the previous scene and the next scene’s hiccup. react-diff-viewer?
- How can we use property based testing to put this thing on steroids? Eg render shrunk result
- This tool could be used to instrument running app. Eg, something similar to reframe10x
- This tool could lint/detect various problems with React use. Eg, when a :key on a component is required, when state/effects are setup incorrectly, etc.
- It should be possible to test async effects (
js/setTimeout
,core.async
etc) - explore and document.