September 24, 2008, 11:55
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}}
);
}
September 4, 2008, 01:41
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.