Wednesday, July 11, 2007

Extending Fit with a New Fixture

Fit is a very flexible tool for testing due in large part to the pre-defined fixture types (ActionFixture, ColumnFixture, RowFixture, fitlibrary’s DoFixture, etc.) This flexibility means it’s usually possible to write test tables in a way that is intuitive and easy to read. However, we’ve come across a situation where the test tables we want to write aren’t executable by any of Fit’s built-in fixture types.

The feature we’re working with is a Fit HTML table builder. Our test provides a fixture classname as input and expects a Fit HTML table as output. Here’s an example of what we wanted to test:



Unfortunately, when we ran this test using a ColumnFixture, Fit interpreted the nested table as more parsable cells rather than expected HTML output. And, while there are other ways to structure the test, such as using raw HTML, none of them seem very easy to work with.

What we really need is a new type of fixture, which interprets the table data in the last column as HTML content to be compared with the result of the fixture’s verification method (in the case above, table()).

public class HtmlTableFixture extends ColumnFixture {

@Override
public void check(Parse cell, TypeAdapter adapter) {
String expected = cell.body;
try {
String result = (String) adapter.get();
if (expected.equals(result)) {
right(cell);
} else {
wrong(cell, result);
}
} catch (Exception e) {
exception(cell, e);
}
}

@Override
protected Binding createBinding(int column, Parse heads)
throws Throwable {
Binding binding = super.createBinding(column, heads);
if (column == columnBindings.length - 1) {
binding = new HtmlTableBinding(binding);
}
return binding;
}

private static final class HtmlTableBinding
extends Binding {

private final Binding internalBinding;

private HtmlTableBinding(Binding binding) {
this.internalBinding = binding;
}

@Override
public void doCell(Fixture fixture, Parse cell)
throws Throwable {
Unparse unparse = new Unparse(cell.parts);
String html = unparse.text;
cell.body = html;
internalBinding.doCell(fixture, cell);
}
}
}


Our fixture creates a custom binding, called HtmlTableBinding, which gets bound to the last cell in each row. This binding unparses the cell’s contents and stores them in the body of the cell’s Parse object. When the cell is later evaluated by check(), our fixture gets the expected value from the body of the cell's Parse object and compares it with the result from executing the method (via the TypeAdapter).

Running the test now gives us:



So, Fit is not only a flexible testing tool, it's also easily extensible for those corner cases where you might find that it doesn't give you exactly what you want.


* To understand why we need to unparse it helps to know how Fit reads HTML tables. When Fit is run on a file, the first thing it does is create a model of all of the table information, which it stores in a composite object called Parse. Each part of a table (i.e., <table>, <tr>, or <td>) is a nested Parse object within the composite. Unparsing is achieved by traversing the composite Parse and appending the HTML parts to a buffer.

public class Unparse {

public String text;

public Unparse(Parse parse) {
text = unparse(parse);
}

private String unparse(Parse parse) {
StringBuffer sb = new StringBuffer();
sb.append(parse.tag);
if (parse.body != null) {
sb.append(parse.body);
}
if (parse.parts != null) {
sb.append(unparse(parse.parts));
}
sb.append(parse.end);
if (parse.more != null) {
sb.append(unparse(parse.more));
}
return sb.toString();
}
}

4 comments:

Anonymous said...

Sounds interesting, but the Eclipse update link is broken and the downloadable zip file does not contain a usabel local update site.

I really would like to give it a try , so pls fix it!

Amanda (Mandy) Wilson said...

We are unable to reproduce your problem with the Eclipse updater.
As per downloading the custom fixture, go to
http://sourceforge.net/project/showfiles.php?group_id=201686 and
scroll down - there's a seperate download listed for " Custom Fixture - Table Fixture".

Anonymous said...

The eclips plugin update site at http://fitpro.sourceforge.net/ and the downloadable zip files seem to be broken, not your test fixture. Sorry for the confusion.
The link to the Bug Database on http://fitpro.sourceforge.net/ also is brocken, it points to checkstyle.
I really would like to try out your FITpro eclipse plugin, so it would be nice if the problems with plugin and download will be fixed.

Amanda (Mandy) Wilson said...

Yeah, I understood what you mean.
It says on the site that the eclipse plugin update site it at http://fitpro.sourceforge.net/EclipseUpdate/, not http://fitpro.sourceforge.net.
It seems to work fine for me and several other people told me they got it to work. But I'll look at it again.
I will fix that bug database link, thanks.
How is the zip file "broken"?
I think I zipped those up wtih the windows zip, not winzip, so I'll have a look - i noticed before that winzip often says there's an error when you zip up with the windows OS zip.
If you wanted to send comments directly to us, the email is fit@luxoft.com or you can use the FITpro usergroups on sourceforge.
Thanks