I’m a big fan of TDD in my teams for back-end dev; things like cider’s auto-test mode make it all the better. I have yet to settle on a good approach for the front-end, though. Have any of you found a good way to do TDD for CLJS/front-end development, or do you have favored alternatives?
For front end, I find that trying to do full blown unit tests isn’t worth the effort. There’s too much that needs to be mocked and most issues tend to be due to integration stuff, anyway. I use Selenium with Jest. I run the Node version and plan on trying to figure out a pure Clojure(script) way of doing it in the near future.
What I do is always try to control my page with Selenium instead of with the browser. Instead of bringing up the browser by hand and clicking on a button, I go to my tests and write findButton().click() or whatever. That way, the tests are written as I go and I don’t forget to add ID’s and whatnot to the necessary elements. It’s a little tedious, and sometimes I side step it to get something done faster, but I end up with a solid regression suite by the time the features are done.
I try to write tests for all internal libraries and core business logic functions. If I know a library like re-frame already has passing automated tests then I try not to tread the same ground and test the functions in isolation.
At work we also take a similar approach to Richard Heller’s expect we use CodeceptJS + Puppeteer https://codecept.io/helpers/Puppeteer. They run pretty quick in headless mode, runs in a version of chrome directly, but Codecept provides a normalized abstraction so we can switch to something else as more options come about. I don’t love the OOPy interface but it’s simple enough to delegate to people that may not have a strong programming background.
CLJS testing for me falls into 2 categories: unit testing my cljs functions in isolation, and doing stateful UI testing by automating a browser pointed at the live app. There’s probably something in between those two as well but I haven’t yet found it The first category is relatively easy to to set up auto test running, for example using https://github.com/bhauman/cljs-test-display, but for UI tests it’s more challenging.
For UI tests I really enjoy using Cypress, I find it an infinitely less painful way to automate my browser than using Selenium, and the test runner is very nice. It’s also excellent at getting rid of complexity by e.g. mocking backend calls so that you don’t need to have a full backend setup for every test (though of course you should have a least 1 full end to end test including a real backend, you don’t need to do it every time). I haven’t played around with doing so but since the tests run in JS in the browser, you can have access to your cljs app state and could theoretically put it into certain configurations (probably requires some exported js functions added to the cljs code for interop).
I also personally like to use the Cucumber plugin for Cypress to write my test cases in Gherkin, as I’m a fan of BDD.