TDD Workflow in Clojure using Emacs with CIDER

Free Beginner Workshop

From OO to Clojure Workshop!

Watch my free workshop to help you learn Clojure faster and shift your paradigm to functional.

Summary: TDD is about fast feedback. CIDER tightens the feedback loop with quick commands for running tests and a powerful test reporting system.

Introduction

I've always been into flow. One of the key aspects of flow is a short feedback loop. Test Driven Development (TDD) is partially based on flow, too. You write a new test, then you write code to satisfy the test, then you refactor. You cycle quickly with very small steps. Great for flow!

Now, I'm not going to be a pedant in this post about what is and what is not TDD. Sometimes I like to adhere to a strict discipline of TDD. And sometimes I like to code fast and loose. But as a working definition, for the purposes of this article, I'll define TDD as writing code and tests incrementally, and running the tests fairly often. The last thing you want is to have to wait for those tests to run.

Luckily, CIDER^1 has been optimized to make the whole process smooth, fast, and feedbacky. You can learn about installing CIDER here. Or

ask me any time for help (eric at lispcast dot com)

if you run into trouble.

What you need to know

First, you'll need CIDER connected to the REPL (usually just C-c M-j).

Besides the basic commands for switching buffers (C-c b), I use just one command a ton while I'm TDD'ing:

  • C-c C-t n (That's Control-c Control-t n.) While you're in a buffer, it will run the tests for that buffer. It could be that you're in production code, in which case it will try to find the corresponding test namespace and run tests there.

That will give you just the feedback you need: a green status report in the status bar if everything passes. And a new buffer with a failure and error report if it's not passing. You can do some cool stuff in that buffer, like jumping to the test definition, rerunning individual tests, and seeing diffs of actual vs. expected output. Look here for a quick reference to the available key bindings.

But mostly I'm editing code, compiling it (with C-c C-k), and running the tests (C-c C-t n) to make sure they pass now. Unlike with running lein test at the command line, this command only runs the tests for that specific namespace. This is usually what you want while you're editing code in the namespace. After you're done, you'll want to rerun all of the tests in a fresh JVM at the command line.

Conclusions

Getting a productive workflow set up is really important. It's hard on our nerves to be waiting through long feedback cycles. CIDER tightens those loops down to human scale so we can focus on the work of making the world better.

If you'd like to learn more about testing in Clojure, including how to write tests so that they work seamlessly with Leiningen and CIDER, I have to recommend my LispCast Intro to clojure.test course. It covers the most important and fundamental concepts and skills for testing in Clojure. You should not miss the free clojure.test cheat sheet below.


  1. [CIDER is an Emacs package for rocking Clojure code.]{#fn1}