In the beginning was the Test...

JUnit offers many features besides the standard assertTrue/assertEquals methods most programmers use. Let’s browse through the newer and more exotic features. They might come in handy at some time.

JUnit 4.9 Feature Roundup

Assuming you know something about unit testing and JUnit in particular, I won’t start at the very bottom, but talk a little about the features introduces during the last few versions:

  • Matchers
  • Assumptions
  • Categories
  • Theories
  • Rules

I hope there is something new in here for you. JUnits javadoc documentation is very good, but there is no single place describing these features. It’s not my goal to give a thorough treatment of them here, but it might be a good starting point.

Matchers

By including Hamcrest (core) into the default JUnit distribution, JUnit now allows the usage of assertThat leading to much easier to read tests and better error messages:

@Test
public void testUsingAssertThat() {
  assertThat(42, is(greaterThan(43))); // not that this will fail
}

JUnit includes only the Hamcrest core matchers, if you want/need more matchers, include hamcrest-all 1.1. Included matchers are documented here for Hamcrest and here for JUnit additions.

Output:

java.lang.AssertionError: 
Expected: is a value greater than <43>
     got: <42>

Assumptions

Assumptions allow tests to be ignored if the assumed condition isn’t met (instead of failling).

This test will be ignored if it is run on a Windows OS (for example):

@Test
public void testUsingAssumeThat() {
  assumeThat(File.separator, is("/"));
  ...
}

It is also possible to use assumptions in @Before or @BeforeClass methods.

Output (for example):

Test 'org.interlinked.junit.assumption.BasicTest.testUsingAssumeThat' ignored
org.junit.internal.AssumptionViolatedException: got: "\", expected: is "/"

Categories

Using categories it is possible to run only a subset of the tests. For example slow tests, integration tests etc.

Here, TestCategoryA and TestCategoryB are empty interfaces used to mark the tests:

@Test
@Category(TestCategoryA.class)
public void testCatA() {
  System.out.println("Category A test");
}

@Test
@Category(TestCategoryB.class)
public void testCatB() {
  System.out.println("Category B test");
}

@Test
@Category({ TestCategoryA.class, TestCategoryB.class })
public void testCatAB() {
  System.out.println("Category A and B test");
}

Using the Categories suite, we can now execute only those tests that are in “Category A”, but not in “Category B”:

@RunWith(Categories.class)
@Categories.IncludeCategory(TestCategoryA.class) // this would run tests CatA and CatAB
@Categories.ExcludeCategory(TestCategoryB.class) // now test CatAB is excluded too
@Suite.SuiteClasses(BasicTest.class)
public class CategoryASuite { }

Output:

Category A test

Theories

With theories we can write parameterized tests. We define a few theories and some datapoints. JUnit will match the types of the datapoints and the theories.

Again, we have to use a special suite class Theories:

@RunWith(Theories.class)
public class TheoryTest {
  @DataPoint public static final String POINT1 = "POINT1";
  @DataPoint public static final String POINT2 = "POINT2";

  // mind the plural!
  // uses only the items of the array, never the whole array!
  @DataPoints public static final String[] POINTS = new String[] {"abc", "cde", "efg", "ghi"};

  @DataPoint public static final String[] POINTS_ARRAY = POINTS;

  @Theory
  public void testTheory(String param) {
      System.out.println("Got: " + param);
  }

  @Theory
  public void testTheoryWithTwoParams(String param1, String param2) {
      System.out.println("Got " + param1 + " and " + param2);
  }

  @Theory
  public void testArray(String[] array) { // gets called with POINTS_ARRAY, nothing else
      System.out.println("Got called...");
      assertThat(array.length, is(equalTo(POINTS_ARRAY.length)));
  }
}

Output:

Got POINT1 and POINT1
Got POINT1 and POINT2
Got POINT1 and abc
Got POINT1 and cde
Got POINT1 and efg
Got POINT1 and ghi
Got POINT2 and POINT1
Got POINT2 and POINT2
Got POINT2 and abc
Got POINT2 and cde
Got POINT2 and efg
Got POINT2 and ghi
Got abc and POINT1
Got abc and POINT2
Got abc and abc
Got abc and cde
Got abc and efg
Got abc and ghi
Got cde and POINT1
Got cde and POINT2
Got cde and abc
Got cde and cde
Got cde and efg
Got cde and ghi
Got efg and POINT1
Got efg and POINT2
Got efg and abc
Got efg and cde
Got efg and efg
Got efg and ghi
Got ghi and POINT1
Got ghi and POINT2
Got ghi and abc
Got ghi and cde
Got ghi and efg
Got ghi and ghi
Got called...

Rules

Finally, rules allow us to add behaviour to tests. They can be thought of some kind of AOP for JUnit. Using rules, we can often omit class hierarchies and still reuse functionality using delegation.

JUnit includes some rules to start with, but it is very easy to write our own rules.

public class RuleTest {
  @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
  @Rule public TestName testName = new TestName();
  private static boolean fileCreated = false;
  @Rule public LoggingRule loggingRuld = new LoggingRule();

  @Before
  public void printTestName() {
    System.out.println(testName.getMethodName());
  }

  @Test
  public void testCreatingAFile() throws IOException {
    File newFile = temporaryFolder.newFile("test1");
    assertThat(newFile.isFile(), is(true));
    fileCreated = true;
  }

  @Test
  public  void testCheckIfItExists() { // depends on testCreatingAFile...
    assumeTrue(fileCreated); // just to be sure ;)
    File file = new File(temporaryFolder.getRoot().getAbsolutePath() + "/test1");
    // the file should not exist (unless we use ClassRule for the TemporaryFolder, for example)
    assertThat(file.isFile(), is(false));
  }

  @Test(expected = NullPointerException.class)
  public void testThrowException() {
    throw new NullPointerException();
  }
}

Output:

Starting: testCreatingAFile
testCreatingAFile
Finished: testCreatingAFile
Starting: testCheckIfItExists
testCheckIfItExists
Finished: testCheckIfItExists
Starting: testThrowException
testThrowException
Finished: testThrowException

The TemporaryFolder and TestName rules are included in JUnit, the LoggingRule is a simple example:

public class LoggingRule extends TestWatcher {
  @Override
  protected void starting(Description description) {
    System.out.println("Starting: " + description.getMethodName());
  }

  @Override
  protected void finished(Description description) {
    System.out.println("Finished: " + description.getMethodName());
  }
}

Other rules included (see JUnit’s javadoc):

  • ErrorCollector: collect multiple errors in one test method
  • ExpectedException: make flexible assertions about thrown exceptions
  • ExternalResource: start and stop a server, for example
  • TemporaryFolder: create fresh files, and delete after test
  • TestName: remember the test name for use during the method
  • TestWatcher: add logic at events during method execution
  • Timeout: cause test to fail after a set time
  • Verifier: fail test if object state ends up incorrect

Unfortunately, rules seem to be local to the defining class, so you can’t put the into the suite class like @Before and @BeforeClass (which is really nice for opening external resources once for all tests).

Misc additions

Infinitest

For each change you make, Infinitest runs all the dependent tests. It’s continous testing for Eclipse and IDEA - free and open source (written by inproving works)!

ClasspathSuite

Most IDEs have their own ways for finding test classes to run, but usually I like to be IDE independent. Using the ClasspathSuite it is possible to have JUnit detect all test classes (or a subset of them) within the classpath (written by Johannes Link). There are efforts to include it into the standard distribution of JUnit.

Every programmer knows they should write tests for their code. Few do. The universal response to “Why not?” is “I’m in too much of a hurry.” This quickly becomes a vicious cycle- the more pressure you feel, the fewer tests you write. The fewer tests you write, the less productive you are and the less stable your code becomes. The less productive and accurate you are, the more pressure you feel.
— Kent Beck/Erich Gamma – JUnit Test Infected

Notebooks (dead wood)

Notebooks

Moleskines were all the rage about six years ago. Whole blogs were, and still are, dedicated to them. Today, still many people carry these little black books.

I too loved these little books, but in the last few years I’ve changed some parameter of my journal every time I needed a new one. I changed the brand, the size, I used soft and hard covers, plain, square or ruled (although, they were always black).

It was a fun experiment, but now I’ve come to a conclusion of what suits my needs best: Leuchtturm 1917

either dotted or plain.

The Master is large enough for keeping full A4 pages. I use it for plannings, sketches, technical stuff etc. Most of the time it sits on my desk and waits to be filled - usually one to two pages per day.

The Medium is just the right size for a journal. It fits easily in almost every bag, is large enough for notes, quotes, thoughts and so on. The smallest format, A6, is also quite nice. But for me, the Medium is simply the best choice.

The following sounds like an advertisement, but the tagline of the Leuchtturm 1917 company is “Details machen den Unterschied” (“Details make all the difference”), I have to include some of their noteworthy details:

  • Ink proof paper - earlier editions of the notebooks used a thinner paper (much like the paper used in Moleskine notebooks), but recent editions use a 80g/qm paper - perfectly suited for a fountain pen.
  • The “Dotted” variant is a nice compromise between plain and square, it’s unobtrusive and still provides enough guidance.
  • Numbers and Index - the pages are numbered and a small index is printed on the first few pages.
  • Detachable sheets - some companies offer notebooks with detachable sheets, sometimes you can rip out half of the notebook. Leuchtturm only has 8 sheets which is more than I ever ripped out of a notebook, so I consider this a plus.
  • Labelling stickers - quite nice for organisation-fanatics, during usage we have the slick plain look of the black notebook we all love, but for archiving purposes there are a few labelling stickers in each notebook package.

Even though we’ve access to email, note-taking applications, the Web etc. almost all the time, I still love the old classy feeling of a notebook and (in my case) a fountain pen.

I’ll end this post with a few links for your reading/tinkering pleasure.

So often is the virgin sheet of paper more real than what one has to say, and so often one regrets having marred it.
— Harold Acton

How to Hide Google's "Google Plus Notification Count"

To hide the Google Plus notifications on the upper right of Google’s services, install Adblock (Adblock Plus for Firefox or Adblock for Chrome) and add this rule to your ruleset:

##A#gbg1

The notification count is a link (A) with id gbg1, this rule hides that element. Let me know if it works for you, or not.

Hapiness can only be found if you can free yourself of all other distractions.
— Saul Bellow

JavaScript

Few languages are so clearly worth learning as JavaScript.
– It’s an interesting language that doesn’t restrict how you use it.
– It’s a language you get paid for developing in.
– It’s still cool (who cares about Java anymore?).
– It’s here to stay (for some time, though).

So, to sum it up, I believe investing in JavaScript pays off. Even if you’re an “enterprise developer” or something. JavaScript will get you, sooner or later, so get it first!

Continue to full post...

How to dive into Legacy Code

Diving into legacy code written some time ago can be a daunting task. It doesn’t even matter much if we’ve been writing it ourselves, or somebody else, code rots faster than we’d like to admit.

Currently faced with such a task I tried to do it in a systematic and repeatable manner.

My steps

First try to find the modules and their dependencies. I used IntelliJ IDEA for my current Java project. Since it also uses Maven, finding the dependencies was easy.

Create a graph of module interdependencies. Which modules depend on which? Find the “edges” of the system (modules that do not depend on other modules). I found them to be the best starting point for a more detailed analysis.

Find out what the purpose of each module is. Is it a layer in the system (like a DAO-module)? Is it a cross-cutting concern (model classes)?

The next step is to analyse each module by itself. For this step I recommend using doxygen. It can generate a very good documentation of the software at hand, even if no doxygen (or any other type of markup) was used, by analysing the dependencies, class hierarchies, call graphs of the program. doxygen supports many languages, chances are high yours will be too.

To get the most out of doxygen, I’ve used the following configuration file which enables many of the advanced analysis features (like call graphs etc): doxygen.config.

You have to edit the file and provide - at least - the input and output directories! After that, it’s simply a doxygen doxygen.config.

To generate this kind of documentation easily from Maven, here is a similar doxygen-maven-plugin configuration:

 1     <build>
 2         <plugins>
 3             <plugin>
 4                 <groupId>com.soebes.maven.plugins.dmg</groupId>
 5                 <artifactId>doxygen-maven-plugin</artifactId>
 6                 <configuration>
 7                     <projectName>${project.artifactId}</projectName>
 8                     <projectNumber>${project.version}</projectNumber>
 9                     <optimizeOutputJava>true</optimizeOutputJava>
10                     <extractAll>true</extractAll>
11                     <extractStatic>true</extractStatic>
12                     <recursive>true</recursive>
13                     <exclude>.git</exclude>
14                     <excludePatterns>*/test/*</excludePatterns>
15                     <inlineSources>true</inlineSources>
16                     <referencedByRelation>true</referencedByRelation>
17                     <referencesRelation>true</referencesRelation>
18                     <hideUndocRelations>false</hideUndocRelations>
19                     <umlLook>true</umlLook>
20                     <callGraph>true</callGraph>
21                     <callerGraph>true</callerGraph>
22                     <generateLatex>true</generateLatex>
23                 </configuration>
24             </plugin>
25         </plugins>
26     </build>

The generateLatex option is nice if you wish to produce PDF files (for viewing on a Kindle for example).

With this plugin configured in you pom.xml, mvn doxygen:report is your workhorse.

If you’re unsure if the generated documentation is worth it, take a look at the doxygen documentation of JUnit 4.8.2 (zip file, 7.6MB).

Everybody writes legacy code.
— Eric Ries

Haskell Books and Tutorials

Haskell is really a language very worth knowing. It does many things so different than most other languages which I really enjoy.

I’d like to use this post to mention a few really good resources for learning Haskell:

Learn you a Haskell

Learn you a Haskell is a very fun and entertaining tutorial for Haskell very much in the spirit of Why’s poignant guide to Ruby.

It isn’t finished yet, but it’s really good to start with. (Via Wadler’s Blog)

Real World Haskell

Real World Haskell is a upcoming book I really look forward to. It is freely available on its website, so check it out.

Wikibook

There is also a good collection of Haskell topics on Wikibooks – Programming/Haskell

Wikibook is more interesting if you already know a bit of Haskell and would like to understand it more in depth.

Others

I liked Yet another Haskell Tutorial very much, this aims at people with a bit of background, though.

Another more recent book on Haskell is Programming in Haskell which is nice, but also quite basic IMO.

Of course there is always the Gentle introduction to Haskell

Enjoy.

Haskell is doomed to succeed.
— Sir Tony Hoare

Git Overview

My version control journey started with CVS, after that I looked at SVN, but never really used it. The shortcomings of centralized repositories were too obvious and with my increasing interest in Haskell I jumped on the distributed version control train with Darcs. I really, really liked it, but it had some nasty things too. After a while I was looking for something different and stumbled over Mercurial, again I was really happy with it but somehow my journey wasn’t over yet.

Continue to full post...

Mercurial Version Control Status in the ZSH Command Line Prompt

I sometimes forget to push or pull changes to or from a remote repository. To remedy the problem I wrote myself a little script to show me the status on the prompt.

Continue to full post...

Free and Open Source Math Programs

In this post I’ll go through some of the most prominent math programs available with source code.

This is by no means “original” work, I just collected the headlines and links to various mathematical software projects out there. This started with an offer of my University (Mathematica for 13 Euro), but I don’t want to invest time in a tool I won’t have (free, or almost free) access to for the rest of my life.

Continue to full post...

Emacs Basics

It’s been a while since I wrote my Vim Introduction and Tutorial (exactly one year). A lot happened between now and then, I chose to get a better feeling about Emacs for example.

The reasons aren’t easily explained; The most prominent reason is the awesome AucTex-mode since I’m working heavily with LaTeX lately.

Anyways, learning Vim and Emacs is better than learning only one of them :-).

Continue to full post...

Addendum to "Time Machine for every Unix out there"

My article about using rsync to mimic the behavior of Apple’s Time Machine generated a lot of traffic, and more important, a lot of feedback.

In this article I’ll summarize and try to clarify a few things.

Continue to full post...

Time Machine for every Unix out there

rsync is one of the tools that have gradually infiltrated my day to day tool-box (aside Vim and Zsh).

Using rsync it’s very easy to mimic Mac OS X new feature called Time Machine. In this article I’ll show how to do it, but there is still a nice GUI missing – for those who like it shiny.

Continue to full post...

XML as human interface and DSLs

While reading “The Definitive ANTLR Reference” by Terence Parr I encountered this quote. I’m a bit sceptic about XML beyond its use of data exchange, so the quote has completely won me over for the book.

Don’t be afraid to build a human-readable configuration file (I implore everyone to please stop using XML as a human interface!) or to build domain-specific languages to make yourself more efficient. Designing new languages and building translators for existing languages, when appropriate, is the hallmark of a sophisticated developer. — Terence Parr, The Definitive ANTLR Reference, Page 23.

Being an expert in XML is like being an expert in comma-separated values.
— Terence Parr

Linux peripheral devices configuration

This weekend I tried to get my new keyboard (Microsoft Ergonomic Keyboard 4000) and my Logitech MX1000 Laser mouse to work properly. The Keyboard has many extra-keys I didn’t bother to count, and the mouse has 12 buttons which can be very useful at times.

Almost accidently I solved a bugging performance problem with the Firefox browser. It was incredibly slow when opening Google Spreadsheets, well the whole system was incredibly slow while loading the spreadsheet… .

Continue to full post...

Challenge Response Spam Filter

The challenge-response spam-filter troubles me lately. If you don’t know it, here is how it works if both parties have a challenge-response spam-filter:

  1. I write an email to someone@domain
  2. The address gets whitelisted on my machine
  3. The receiver doesn’t get my message
  4. I get a message from the receivers mail-server to which I should reply
  5. I reply to the automatic message
  6. The receivers mail-server whitelists my address and delivers my initial mail

So far so good. Three questions pop up:

  • What if the spammer uses my whitelisted email address to send his spam?
  • What if only one of the two has a challenge-response spam-filter?
  • What if spammers start to automatically reply to those messages?

Continue to full post...