-
Notifications
You must be signed in to change notification settings - Fork 0
/
testing-continuously.html
46 lines (46 loc) · 4.5 KB
/
testing-continuously.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<head><title>Testing, Continuously</title><link href="tufte-css/tufte.css" rel="stylesheet" /><script src="http:https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script></head><body><h1>Testing, Continuously</h1><p class="subtitle"><a href="about-me.html">John Jacobsen</a></p><div><p><strong>This is the fourth post in a series about Clojure workflows.</strong></p><p>In my last post, I laid out a workflow based on TDD but with the
addition of “literate programming” (writing prose interleaved with
code) and experimentation at the REPL. Here I dive a bit deeper into
my test setup.</p><p><span>Even before I started developing in Clojure full time, I
<a href="http:https://eigenhombre.com/testing/2012/03/31/ontinuous-testing-in-python-clojure-and-blub/">discovered</a>
that creating a configuration that provides near-instant test
feedback made me more efficient as a developer. <strong>I expect to be able to run all relevant tests every time I
hit the “Save” button</strong> on any file in my project, and to see the
results within “a few” (preferrably, less than 3-4) seconds. Some
examples of systems which provide this are:</span></p><p><ol><li>Ruby-based <a href="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/guard/guard#readme">Guard</a>, commonly used in the Rails community;</li><li><a href="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/eigenhombre/continuous-testing-helper">Conttest</a>, a language-agnostic Python-based test runner I wrote;</li><li>in the Clojure sphere:<ol><li><a href="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/marick/Midje">Midje</a>,
using the <code>:autotest</code> option;</li><li>Expectations, using the autoexpect plugin for Leiningen;</li><li><a href="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/slagyr/speclj">Speclj</a>,
using the <code>-a</code> option;</li><li>clojure.test, with <a href="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/jakepearson/quickie">quickie</a> (and
possibly other) plugins</li></ol></li></ol></p><p><span>I used to use Expectations; then, for a long time I liked Midje for
its rich DSL and the ability to develop functionality bottom-up or
<a href="https://github.com/marick/Midje/wiki/The-idea-behind-top-down-development">top-down</a>. Now, I pretty much just use Speclj because it’s
autotest reloader is the most reliable and trouble-free.</span></p><p>(Earlier versions of this post had details for setting up Midje,
now omitted — see the Speclj docs to get started.)</p><p>Running your tests hundreds of times per day not only reduces
debugging time (you generally can figure out exactly what you broke
much easier when the deltas to the code since the last successful
test are small), but they also help build knowledge of what parts of
the code run slowly. If the tests start taking longer than a few
seconds to run, I like to give some thought to what could be
improved — either I am focusing my testing effort at too high of a
level (e.g. hitting the database, starting/stopping subprocesses,
etc.) or I have made some questionable assumptions about performance
somewhere.</p><p>Sometimes, however, despite best efforts, the tests still take
longer than a few seconds to run. At this point I start annotating
tests with metadata indicating that those tests should be skipped
during autotesting (I still run the full test suite before
committing (usually) or pushing to master (always)). In this way, I
can continue to get the most feedback in real time as possible —
which helps me develop quality code efficiently. The exact
mechanism for skipping slow tests depends on the test library you’re
using; I haven’t had to do it with Speclj yet.</p><p>In the next post, we’ll switch gears and talk about literate
programming with Marginalia.</p></div><div><p><a href="about-me.html">about</a>|<a href="content.html">all posts</a></p><p>© 2016 <a href="about-me.html">John Jacobsen</a>. Created with <a href="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/eigenhombre/unmark">unmark</a>. CSS by <a href="https://edwardtufte.github.io/tufte-css/">Tufte-CSS</a>.</p></div><script type="text/javascript">var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-40279882-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http:https://www')
+ '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();</script></body>