Thread Police for your Unit Tests

October 10th, 2008

Writing the new ant I stumbled across the problem of test cases leaving threads behind, after returning control to the runner. My trusted colleague and JUnit Runner expert Mark Burnett and I, knocked up a quick and dirty junit runner that actually allows you to spot such a condition.

Consider the following testcode:

 
@Test
public void losingThreads() throws InterruptedException {
  Thread newThread = new Thread() {
    public void run() {
      for(;;);
    }
  };
  newThread.start();
}

This thing happily spawns a thread and then returns. You get a green test case, but your IDE might behave somewhat funny as there are still threads open. To help diagnose these problems we came up with this threadpolicerunner.

If you now annotate your test case like this, to use it:

 
@RunWith(ThreadPoliceRunner.class)
public class ThreadTest {
    @Test
    public void losingThreads() throws InterruptedException {
        Thread newThread = new Thread() {
            public void run() {
                for(;;);
            }
        };
        newThread.start();
    }
 
 
    @Test
    public void notLosingThreads() throws InterruptedException {
        Thread newThread = new Thread() {
            public void run() {
            }
        };
        newThread.start();
        newThread.join();
    }
 
}

Your runner will give you the following feedback:

Nice, isn’t?

Spreadsheet Driven

September 24th, 2008

I had a quite a few chats these days with people fro a more QAish background. Originally I intended just to look at selenium and webdriver. I showed some of the stuff, which I wrote in Java, to my QA colleagues. I used a demo webapp that implements a phonebook. My testcase just added a new contact and verified, that the user got a success message.

After they saw a bit of it, they asked me how they could separate out the testdata. I was a bit stunned, because, well it was all there - at least to me as a java developer. I had separated out everything into a method somewhat like this:

 
 createNewContact("Felix", "Leipold");

So I could test for other inputs as well:

 
 createNewContact("", "Invalid");
 createNewContact("Invalid", "");
 createNewContact("Holden", "Caulfield");

Obviously the expectation of QAs was to have an external file, e.g. a spreadsheet that feeds the data into the test code. I am very critical of this approach, but I felt like playing with junit 4 a bit. Junit 4 allows you to specify a runner four your test and indeed they have got one prepackaged that does parameterized tests. So I thought how about having a runner reads a spreadsheet and feeds the data into the test. As an example I use a very simplistic function:

 
    double add(double a, double b) {
        return a + b;
    }

So to test this I created this table and saved it as mathTest.xls:

Then I went on to create a test case, like this:

 
@RunWith(SpreadsheetDriven.class)
@Spreadsheet(name = "mathTest.xls")
public class MathTest {
    double a;
    double b;
    double expectedSum;
 
    public MathTest(Double a, Double b, Double expectedSum) {
        this.a = a;
        this.b = b;
        this.expectedSum = expectedSum;
    }
 
    @Test
    public void testAdd(){
        assertEquals(expectedSum, add(a,b));
 
    }
 
    double add(double a, double b) {
        return a + b;
 
    }
}

Essentially this thing parses the file specified in the annotation and passes it into the constructor. It’s not doing any fancy type conversions. All numerics are passed in as double, booleans as booleans, and everything else should be a string. Implementation and tests are to be found here and depend on apache poi being on the classpath for reading the excel file.

I am also quite proud of the reporting I get:

I am wondering, if all this is a good idea. But if it helps keeping people from using fit, it’s a start. What I realised by now is that actually table or data driven testing is much more appropriate for unit tests. Funnily enough that people actually do it the other way round. For unit tests I would actually recommend not to use a spreadsheet, but the original JUnit Parameterized runner, which lets you define your data like this:

 
    @Parameterized.Parameters
      public static List getParameters(){
        return Arrays.asList(new Object[][]
                {
                        {2,2,4},
                        {3,4,7},
                        {4,2,6},
                        {2,4,6}}
        );
    }

Poor man’s delegates

September 4th, 2008

When writing Swing applications I find myself quite often in the Situation to write action handling code like this (Why I do write this kind of code is a different albeit also interesting story):

 
public class Handler {
    Action doMyThing;
 
    public Handler() {
        doMyThing = new AbstractAction("doMyThing"){
            public void actionPerformed(ActionEvent e) {
                doMyThing();
            }
        };
    }
 
    public void doMyThing(){
        System.out.println("printlning is so my thing.");
    }
}

No this looks ok at first sight. My IDE helps me creating that anonymous inner class and all. But as soon as there are three or more actions on my presentation model things get really hard to read. C# introduced delegates for this kind of problem, but what shall the poor Java programmer do?

The thing I tend to ask myself in such situations is, what would I like to write? What of the above code matters? what is coincidental? So a naïve approach would look like this:

 
public class Handler {
    Action doMyThing;
 
    public void doMyThing(){
        System.out.println("printlning is so my thing.");
    }
}

I just slashed all the lines, that seem to be technicalities. And I like it. I still can exercise the doMyThing method in a unit test. And actually it doesn’t take that much to get the thing up and running. We have to do add in a constructor again. But this one is only O(1) in length:

 
public class Handler {
    Action doMyThing;
 
    public Handler() {
        ActionReflector.reflectActions(this);
    }
 
    public void doMyThing(){
        System.out.println("printlning is so my thing.");
    }
}

I like this quite a lot. But how does it work. The reflector looks for all the fields of type Action. If they are null it looks for a method with a matching name. Then it news up a new Action that calls this method and assigns it to the field. If the method lookup fails an exception is thrown. So as long as the class is instantiated at least once in a unit test - which is what one might hope for - the naming convention will actually be enforced.

Here is a a more complex example which illustrates the benefits of this approach.

 
public class Handler {
    Action doMyThing;
    Action doThisOtherThing;
 
    Action manualAction;
 
    public Handler() {
        manualAction = createManualAction();
        ActionReflector.reflectActions(this);
    }
 
 
    public void doMyThing() {
        System.out.println("printlning is so my thing.");
    }
 
    public void doThisOtherThing() {
        System.out.println("printlning is also this other thing.");
    }
 
 
    private Action createManualAction() {
        return new AbstractAction("") {
            public void actionPerformed(ActionEvent e) {
                System.out.println("Doing a manual thing.");
            }
        };
    }
}

The manualAction field is assigned, before the reflector is run. This is quite handy if you just want to delegate to another handler. So you combine the old and the new way easily. If you forget to initialise it, the reflector will fail and tell you the method is missing.

Of course this approach can be extended. One thing I do is to have a second method, that indicates whether the action is enabled. Generally speaking you could use this to implement multi-method interfaces by having a naming convention for each method on the interface.

This niceness has to be paid with some infrastructure code, which is a bit ugly - mostly due to all the declared exceptions in the java reflection.

In essence this gives you a delegate. It works very well for me. Even though you don’t have compile time security, it will blow up as soon as you new your object up, if you get the spelling wrong.

Mal wieder: Auflärung, Vernunft und so weiter

August 31st, 2008

Musste mich heute, mal wieder, ein wenig aufregen. Gerne blickt man ja nach Amerika, wo Aberglaube, Dummheit etc. fröhliche Urstände feiern, um sich dann zu erfreuen wie gut es doch in Europa zugeht. Als kleines Schmankerl sei dieser Artikel aus dem Guardian empfohlen. Der Autor berichtet, dass viele Amerikaner den Verdacht hegen Obama sei in Wirklichkeit ein als Christ getarnter Muslim und nicht die amerikanischen, sondern diese äh, anderen Werte vertritt.

Doch auch bei uns steht die Sonne des Verstands nicht viel Höher. Die gepulste Handystrahlung hat einen neuen kleinen Bruder: den Infraschall. Und der hat es in sich. Während ich mich an kein nennenswertes Gerichtsverfahren erinnern kann, in dem das Betreiben einer Mobilfunk-Basis verboten worden wäre, hat das Verwaltungsgericht Dresden mit Hinweis auf die mangelnde Dämpfung des tieffrequenten Schalls den Bau einer Biogasanlage gestoppt. Traurig - wie die Leute scharenweise so einen Unfug glauben können.

Holiday in Spain

August 27th, 2008
Very recently I had the pleasure of exploring Spain. Here are some of my Impressions:

I was climbing a bit on the Peñon d’Ifach (the spelling is probably wrong):

Futhermore I was seeing Spanish supermarkets. Luckily I stumbled across the following packaging (soy extra grueso).

I also went to see my old flatmate Andy from Hanover Gardens in Alicante.

Which is a very charming place with good mochitos.

Of course there was Barcelona. Capital of the Katalans. And famous katalan Musicians and so forth as the guide on the bus tour kept explaining. This is good old Columbus (The other day I went down to Trafalgar Square to see Nelson, who gave the Spanish a bit of a beating up - ;-) ).

There was also the Fiesta Major in Gracia.

And as you can tell from the following image I had a really good time. I also saw loads of other stuff, but that was more or less the usual: the beach, Gaudi, and all.

Verdict: Spain is a cool place.

Macht das Internet Doof?

August 22nd, 2008

So titelte der Spiegel großspurig am 11.8.2008.

Ich habe das Heft im Urlaub gekauft, da ich was zu lesen brauchte. Der Titel hat mich schon etwas genervt. Doch es kam noch besser. Den Artikel über das Internet brauchte ich gar nicht zu lesen (habe ich bis heute nicht getan). Stattdessen machte ich mich an einen Artikel über das Gladbecker Geiseldrama. Die Spiegel-Leute haben zwar artig die Rolle der Medien kritisiert, aber natürlich ihren siebenseitigen Bericht mit allen entscheidenden Fotos verziert. Doch das Beste am Schluss des Artikels:

Denn 20 Jahre sind nur eine Sekunde. Und eine Sekunde dauert ein ganzes Leben.

Ich weiß zum Glück das 20 Jahre ca. 631 Millionen Sekunden dauern. Von wegen Spiegel-Leser wissen mehr und so. Aber ganz ernsthaft hat so eine Teenagerpoesie in einem Nachrichtenmagazin, für das ich EUR 4,50 beim Händler gelassen habe, nix zu suchen.

“Hallmark of the Stupid”-Series - First Instalment - Velocity

July 31st, 2008
There is a lot of nasty stuff to be said about velocity, but today I complain about it’s stupid whitespace-ridden syntax and it’s equally stupid error messages. I just got this one:
Parser Exception: templates/myoldtemplate.vm 
    Encountered "}" at line 19, column 101. 
    Was expecting one of: "," ... "}" ...  ...  ...

A Screen Camera in Java

July 12th, 2008

Today I wrote a little class that allows to repeatedly capture the screen content and write the result to a flash file. It created a flash video with one frame per second (this is a bit crude) with one frame per screen shot taken. It is based on JavaSWF2 a nice wrapper around the SWF file format. To run you need to get the JavaSWF2 jarfile. Then you go:

 
camera = new ScreenCamera(new File("test.swf"));
doStuff();
camera.takeScreenShot();
doMoreStuff();
camera.takeScreenShot();
camera.close();

It might be useful for testing and creating tutorials.

Implementing Custom Quicksilver Actions

July 12th, 2008

As it was a nice London day today - wind, rain, sunny spells and a cosy 15ËšC all that, I spent the day with my Mac learning how to get more out of Quicksilver. I was wondering for some time how to implement my own actions. The task at hand was to have a single action that allows me to push files to the dropbox folder on my server out in the internet. So all this thing has to do is to create the right command line call. Unfortunately there is no way easy way just to add command using placeholders (or none that I am aware of).

So what you have to do to write an Actions is to write an AppleScript (which has a very idiosyncratic syntax, but feels a bit TCLee ) and put it into the right folder, something like /Users/USERNAME/Library/Application Support/Quicksilver/Actions/MyAction.scpt

So this is the thing I hacked up. It uses growl to notify the user, when the transfer is completed. Unfortunately it doesn’t display an error on failure. I would have to spend more time with AppleScript, but perhaps one of the readers comes up with a solution.

on open these_items
   repeat with i from 1 to the count of these_items
      set target to "user@host.com:/home/user/dropbox"
      set filename to the quoted form ¬
         of the POSIX path of (item i of these_items)
      set theResult to ¬
         do shell script "scp -q " & filename & " " & target
      growl((filename & theResult))
   end repeat
end open


on growl(theText)
   tell application "GrowlHelperApp"
      set the allNotificationsList to ¬
         {"Test Notification", "Another Test Notification"}
         set the enabledNotificationsList to ¬
            {"Test Notification"}
            register as application ¬
               "Growl AppleScript Sample" all notifications allNotificationsList ¬
                default notifications enabledNotificationsList ¬
                icon of application "Script Editor"
                
            notify with name ¬
               "Test Notification" title ¬
               "Drop done" description ¬
               theText application name "Growl AppleScript Sample"
        end tell
end growl


Useful links: QS wiki on scripting, QS google group

Verdict: QS rocks!

Käse-Ä

July 1st, 2008
Wenn sich der aktuelle Sprachtrend fortsetzt, wird man den Kindern in der Schule wohl bald sagen müsssen: “Päckchen mit Käse-Ä” - ganz analog zum Vogel-V. Interessant ist, dass die Rechtschreibung den umgekehrten Weg geht, z.B. aufwändig. Man könnte natürlich auch meinen, dass dies die schludrige Aussprache des Äs noch begünstigt.


You are viewing a mobilized version of this site...
View original page here

Mobilized by Mowser Mowser