a little madness

A man needs a little madness, or else he never dares cut the rope and be free -Nikos Kazantzakis

Zutubi

Archive for June, 2009

Ready to Test: Maven + TestNG + Hamcrest + Mockito

I’m no Maven fanboy, but for a new, small Java project the ultra-fast setup time is compelling. So, for my latest little application, I decided to give it a go. Sadly, the default Maven archetype lumped my project with JUnit 3.8.1. Boo. And although the TestNG website mentions an alternative archetype, it appears to have disappeared off the face of the internet.

Luckily, dragging my project into the present wasn’t difficult. Along the way I also added my essential testing libraries: Hamcrest for matchers and Mockito for mocking (well, stubbing, but that’s another story). For posterity’s sake, and for others that share my testing tastes, here’s how it’s done.

Requirements

I’m assuming that you have Maven 2 installed already. If not, it’s trivial to:

  1. Download the latest (2.1.0 at time of writing); and
  2. Install it according to the instructions provided.

You can check if you have Maven ready to go by running:

$ mvn --version
Apache Maven 2.1.0 (r755702; 2009-03-18 19:10:27+0000)
Java version: 1.6.0_12
Java home: /usr/local/java/jdk1.6.0_12/jre
Default locale: en_AU, platform encoding: UTF-8
OS name: "linux" version: "2.6.28-11-generic" arch: "amd64" Family: "unix"

Bootstrap

With the lack of an available alternative, I found it easiest to start with the default archetype. To create a new project, run something like:

$ mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-app

Remember that if you’ve just installed Maven it will take this opportunity to download the internet. Be patient. If you’re new to Maven, you might also want to check out the 5 minute guide which walks through this in more detail.

Check that your bare application has been created:

$ cd my-app
$ find . -type f
./src/main/java/com/mycompany/app/App.java
./src/test/java/com/mycompany/app/AppTest.java
./pom.xml
$ mvn package
...
$ java -cp target/my-app-1.0-SNAPSHOT.jar com.mycompany.app.App
Hello World!

Add the Dependencies

Next you need to update the project POM to add the testing libraries as dependencies to your build. This involves three changes:

  1. Removing the default dependency on JUnit.
  2. Adding new dependencies for TestNG, Hamcrest and Mockito to the “test” scope.
  3. Configuring the compiler to accept Java 5 source.

The last step is necessary as the Maven default setting assumes Java 1.3 source, which apart from being ancient doesn’t support goodies such as annotations that are required for the new testing libraries. Your updated pom.xml file should look something like:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>my-app</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>5.8</version>
      <scope>test</scope>
      <classifier>jdk15</classifier>
    </dependency>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-all</artifactId>
      <version>1.8.0-rc2</version> 
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.hamcrest</groupId>
      <artifactId>hamcrest-all</artifactId>
      <version>1.1</version> 
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>  
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

I’ve used the latest available versions of each of the libraries in this example — tweak them to suit your current reality.

Update the Sample Test

Now you’re ready to try updating the sample test case to use the trinity of TestNG, Hamcrest and Mockito. The easiest way to do this is to get Maven to generate a project for your IDE, e.g.

$ mvn eclipse:eclipse

or:

$ mvn idea:idea

Fire up your chosen IDE, open the AppTest class, and edit it to exercise all of the dependencies:

package com.mycompany.app;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.testng.annotations.Test;

import java.util.Random;

public class AppTest 
{
    @Test
    public void testApp()
    {
        Random mockRandom = mock(Random.class);
        when(mockRandom.nextInt()).thenReturn(42);
        assertThat(mockRandom.nextInt(), equalTo(42));
    }
}

What are you waiting for? Try it out:

$ mvn test
...
Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 18 seconds
[INFO] Finished at: Wed Jun 24 16:11:48 BST 2009
[INFO] Final Memory: 20M/100M
[INFO] ------------------------------------------------------------------------

If you got this far, then everything you need is in place. Now you just have to … implement your project!

Extra Credit

If you poke about a bit, you will also find that the maven surefire plugin, which manages the tests, generates some reports by default. Along with HTML output, it also produces a JUnit-like XML report at:

target/surefire-reports/TEST-TestSuite.xml

This report is ideal for integration with a continuous integration server (in my case Pulse, naturally, but many will support it).

Happy testing!

Citconf Brisbane 2009

Well, it’s that time of year again. Citconf is heading down under, this time to sunny brisvegas on the 26-27th of June. If you have been before, you know how much fun citconf can be, and if you haven’t, I strongly recommend checking it out.

Both Jason and I have been regulars at citconf over the past couple of years. Whilst we will not be there for Brisbane, we will be at citconf paris.

And as always, a big thank you to Jeffrey Fredrick, Paul Julius and the volunteers for doing the leg work to get the ball rolling.

Boost.Test Tutorial Sample Code

Given the fact that people seem to have found my short Boost.Test tutorial, I thought they might appreciate having access to the sample code. So I have cleaned up the code, added a README, and created a repository for it on GitHub:

http://github.com/jsankey/boost.test-examples/

The easiest way to access the code if you have git is to clone:

$ git clone git://github.com/jsankey/boost.test-examples.git

If you don’t have git, you can download a zip or tarball from GitHub.

Happy testing!

Agile: Methodology With Another Level of Indirection

Despite the natural desire to find the “perfect” software development methodology, the simple fact is there is no one-size-fits-all solution. This led me to wonder: are so-called “agile” methodologies just a passing trend? Knowing that there is no silver bullet, can agile really be considered different to trends that have come before?

In fact, I think there is something different about the agile way. The problem of finding the perfect method has been solved in the same way we solve everything in programming: by adding another level of indirection.

Take the Agile Manifesto:

We are uncovering better ways of developing software by doing it and helping others do it. Through this work we have come to value:

  • Individuals and interactions over processes and tools
  • Working software over comprehensive documentation
  • Customer collaboration over contract negotiation
  • Responding to change over following a plan

That is, while there is value in the items on the right, we value the items on the left more.

I read this of a recognition of the fact that the two toughest parts of software development are:

  1. Dealing with people (communication, collaboration); and
  2. Coping with change (rather than pretending you can avoid it).

These challenges have been and always will be the key to successful projects. By defining agile in terms of these fundamental challenges, rather than specific practices, it can adapt to different circumstances. In fact, thanks to this abstraction, it is not really accurate to think of agile as a methodology — it is much more about culture than specific tools or practices.

The problem with this indirection, however, is it doesn’t give people an easy answer. If you want to try agile, where do you start? There is no secret here: the answer is simply to try things out and see what works. Just remember:

  1. If something works, that’s great, but don’t become complacent. No practice is perfect, always aim for improvement.
  2. If something doesn’t work, think about why. Can you tweak it? Has it run its course? There are no “best” practices: if you give something a proper chance and it doesn’t fit your team, cut it loose.

Put another way, the “secret” to agile is it is constant refactoring — of the process itself.

Pulse 2.0.32: Custom Continuous Integration Trend Reports

I’ve just released another Pulse 2.0 build, and the new features are still coming :). In this case, I have added the long-anticipated ability to capture custom metrics with your build results, then report trends for these metrics over time. You can capture any benchmark of your build that you can imagine, then have Pulse chart it for you. All sorts of charts are supported, with flexible configuration.

As an example, imagine capturing some simple performance measures as numbers. You can then configure Pulse to show them in a line chart:

Configure Report

Pulse stores the metric values with each build, so you can easily see how performance is changing over time:

chart

Most importantly, if performance drops, it is easily visible exactly when it happened, making it much easier to figure out why. You can learn more about how to configure custom reports in the Cookbook.

As part of this change, I also tweaked the default reports that Pulse generates for you. Now all of these reports are configured in the same way as the custom ones above, allowing you to change them to suit your preference. Not only that, but more reports come “out of the box”:

chart2

Sweet! Interested in continuous monitoring of your project’s performance? Try Pulse 2.0 today with a free small team, open source or evaluation license.

Not just good for your project

It seems to be commonly accepted that high levels of Cholesterol is a bad thing

High blood levels of cholesterol are a risk factor for coronary artery disease (heart attacks and angina).

source

So, imagine my surprise when I found out that Pulse, already known to reduce stress levels, is also good for your cholesterol levels.

Nuttelex Pulse Lowers Cholesterol

Nuttelex Pulse Lowers Cholesterol

Hiring “Rock Star” Programmers

I always groan inwardly when I see another job ad calling for a “Rock Star Programmer”. Obviously the idea is that the hiring company is after the top talent. In that sense alone it’s kind of stating the obvious. But is this a good way to attract real talent?

I’m not the only person to think asking for “Rock Stars” is a bad idea. However, several of the other posts I’ve read on the issue, while making some good points, dwell a lot on their own definition of a “Rock Star”. They ascribe several traits to such programmers, none of which directly follow from the vague term. That’s not to say that there isn’t a real point underlying these definitions, though.

To me, the big question is: Do you want to hire someone that would describe themself as a “Rock Star”?. I’ve been fortunate enough to work with a bunch of bright people, and none of them got that way by having overactive egos. On the contrary, even if they knew they had talent, they also knew their limitations. I’m certain, in fact, that this trait was key in allowing them to continue learning and improving.

Naturally job ads always ask for talent — but specifically asking for a “Rock Star” seems to go beyond that. Be careful what you ask for!

You Break (the build), You Bought It

The Pulse 2.0 feature train keeps on rolling. Latest stop: using Pulse to communicate responsibility for a build.

Breaking the build is something to avoid, but even more important is the reaction when it inevitably does break. The key is fixing it fast, before it starts breaking the team’s flow. The worst possible scenarios are:

  • Everyone assumes somebody else is responsible, so nobody fixes it. The build stays broken.
  • Multiple people assume responsibility without talking to each other. Effort is wasted as they all work on fixing the same problem.

Both of these scenarios can be fixed by the same solution: communication. Responsibility for fixing the build needs to be taken by one person, quickly, and communicated to the rest of the team. If nobody has taken responsibility, everyone needs to be aware.

Pulse now supports this directly via the take responsibility feature. When you see the build is broken, you can click a link to take responsibility, optionally adding a comment:

Take Responsibility

Everybody can see who is responsible, both on the project home page, and the summary pages for all builds for the project:

Who's Responsible

Only one person can be responsible at a time, so there’s no confusion. It’s up to the person responsible to decide when their job is done — although you can optionally have responsibility automatically cleared when a build completes successfully (a pretty good indicator that it’s fixed!).

So, start communicating today, and stop wasting time! You can download Pulse and try a free evaluation today. Happy building!