Raising the Bar with Test-Driven Development and Continuous Integration


it is preempted and a new test run kicked off. Also, Infinitest optimizes the feedback provided to the developer by running tests which previously failed before tests which were previously passing.

A TDD Episode with CT
Let's see how CT complements TDD by walking through a very brief example. Let's say we're developing a very simple application to manage deposits and withdrawals to a checking account. Following the TDD process, the first step is to write a failing test that indicates the functionality we would like to add is not present yet in the system. As soon as the developer writes a failing test and enough code to make it compile, Infinitest presents the current failure directly within the IDE as shown in Figure 5. Notice that Infinitest quite visibly indicates that we are now in a failing state with a big red bar, and also shows the cause for the error.


Figure 5. Infinitest presenting an error immediately after compilation

At this point in the TDD process the developer writes just enough code to make the test pass causing Infinitest to rerun affected tests and report that all tests are now passing as shown in Figure 6.


Figure 6. Infinitest reruns affected tests, and in this case shows that all tests are now passing

In this way Infinitest specifically, and CT tools in general, facilitate the TDD workflow by providing rapid Red/Green feedback without the developer having to shift focus and run tests manually. CT tools will also run more tests in each cycle than a developer, who typically only re-runs the current test which is driving the code changes.

CT Tools Overview
Although we used Infinitest to illustrate the idea of CT throughout this article, it is not the only tool of its kind. Table 1 below lists the various CT tools currently available.



Test Selection Strategy



Dependency Analysis

JUnit Max


Runs all with prioritization

Infintest Python


Naming convention



Naming convention



Convention, metadata



Runs all with prioritization

Table 1 . Available CT toolss

Although the primary differentiator between these tools is the language they each support, they also vary in the strategy they employ to identify which tests need to be run in response to any given change. As illustrated earlier, Infinitest employs byte-code level dependency analysis to make this determination. Alternatives include analysis based on source files, conventions, project metadata, and the running of all tests in response to any change. These strategies are sometimes augmented with test prioritization to provide the most meaningful feedback fist.

An interesting technique has been added to the latest version of Clover (a code coverage tool) that allows Clover to execute only the tests that need to be run in response to any given set of changes based on code coverage metrics. Clover isn't a CT tool per se because it runs as a part of the build or with manually run unit tests from within your IDE, but the idea of using these types of metrics in test selection process is quite powerful and hopefully in the future we'll see CT tools offering this capability as well.

In this article we have seen how CT extends the practices of TDD and CI to offer the best possible feedback as quickly as possible throughout the development process. We have seen this illustrated with Infinitest and have seen a few other tools for other languages and with different strategies for test selection. My hope is that you come away with an interest in the practice and tooling around CT.

About the author

AgileConnection is a TechWell community.

Through conferences, training, consulting, and online resources, TechWell helps you develop and deliver great software every day.