Tuesday, September 29, 2009

Mastering Mock Objects - Advanced Unit Testing for Java

A collection of notes on the use of JMockit and JMock in Java unit testing.

Wednesday, September 9, 2009

Tips for dealing with DB2 database samples in your product

In trying to ship a sample of the ITM (IBM Tivoli Monitor) database utilized by our product, we stumbled upon the cross-platform restrictions of the backup/restore commands for DB2, which state:

The supported platforms for DB2 backup and restore operations can be grouped into one of three families:

  • Big-endian Linux® and UNIX®
  • Little-endian Linux and UNIX
  • Windows®

After hours of fiddling with DB2 manuals and succeeding partially in moving the data from an DB2 in AIX 64 bits to a Windows 32 bits, I eventually stumbled upon this great developerWorks article, fittingly titled: Using DB2 utilities to clone databases across different platforms.

Essentially it uses a combination of the “db2move” and “db2look” commands, like this

Exporting the data

To export the contents of the database, change to the directory where the exported directory where the files should be written and run:

db2move WAREHOUS export -sn ITMUSER
db2look -d WAREHOUS -e -a -o db2look.sql

where WAREHOUS is the name of the database I was exporting and ITMUSER the schema for it.

Importing the data

Copy over the files to the target machine and change to the directory where the exported files are. Then run the command:

db2 “create db WAREHOUS”
db2 –tvf db2look.sql
db2move WAREHOUS import

where WAREHOUS is the name of the database you are importing.

You can use a different database name, but you need to edit the first line of the db2look.sql file to match the name.

Thursday, September 3, 2009

Unit testing tools, a minimalist toolset.

After wading through the sea of unit testing tools out there, here is a minimalist (and so far, sufficient) set of open-source tools for testing server-side centric Java code.

----

JUnit 4.x

That is almost a given, full integration with Eclipse and Ant, standard in the industry, etc, etc. JUnit 4.1 is the last release where I did some thorough investigation of any new function, though the just released JUnit 4.7 (Aug/4th) has some function I would like to explore.

----

DDTUnit (http://ddtunit.sourceforge.net/)

This is the best alternative for data-driven testing, where the test code is small but has to use different data inputs.

Side comment:This presentation cross-compares DDTUnit with other data-driven approaches:

Tip: The syntax for the test XML data can be a chore, but this Eclipse snippet (with instructions) can help:
http://sourcepatch.blogspot.com/2009/08/ddtunit-and-eclipse-snippets.html

----

JMock (http://www.jmock.org/)

This library allows you to pre-program objects in the JUnit testcase with the "right" responses to exercise the target code.

----

JMockit (https://jmockit.dev.java.net/)

This library is used to replace Java calls ordinarily not under your control with code under your control.

For instance, you can intercept a call to DriverManager.getConnection and return your own implementation of java.sql.Connection.

Tip 1: This library requires you to add -java.agent=build_dir/libraries/test/jmockit/jmockit.jar to the unit execution path.
Tip 2: Avoid it if you can, it makes tests slower and harder to follow. If you have another entry point to pass a JMock object, such as setter method, do it.



Links I have bookmarked about unit testing recently: http://delicious.com/nastacio/unit-testing

Monday, August 31, 2009

DDTUnit and Eclipse Snippets

One of the tedious aspects of using the excellent DDTUnit library is the creation of the Java class for the test case and the XML data sets. There is no nice Eclipse wizard to do that for you, but today I started to create a set of Eclipse snippets for it. My productivity went to the ditch for the first three hours, but it should pay off sometime between today and tomorrow.

I just select some complicated block of DDTUnit source code or XML on Eclipse, right-click it and choose "Add to snippets". I then replace some hard-coded values, such as the name of an input object, with a variable and save it.

Later, when I need a similar snippet, I just position the cursor where I need the new source code or XML, double-click the snippet from the toolbar, fill out any variables associated with the template (usually one or two) and goodbye round-trips to the DDTUnit reference guide.

image

The snippets library master: http://drop.io/dnastacio/asset/ddtunit-eclipse-snippets-xml

Code comments are for newbies

I am sure you have seen or participated in a debate about how much or how little comments one should put in his own code.

Now look at this pearl I found while writing a presentation about the excellent JMock library.

Just think of the possibilities in terms of team communication: “Jim, can you unlock ThatClassThatFixesThatBugWeDiscussedLastThursday.java?”

image

Thursday, July 30, 2009

Distributed Java code inspection

As a requirement of our current project, we wanted to establish a minimum criteria of code quality ahead of formal code inspections. No point in wasting valuable brain capacity at spotting simple problems such as using “==” instead of “equals” and so on.

Static code analysis is a good starting point, though it can be a bit intransigent about false-positives, where the developer had good cause to write code in a way that the rule developer could not have anticipated.

Being that our main development tool is Eclipse, this was the one criteria that made me give up on the excellent FindBugs, in that there was no way to mark up the source code to tell FindBugs to ignore the problem in future scans.

Enter the Eclipse built-in code analysis, which not only allows scanning source code, but also has a simple way of marking false-positives inside the source code using a Java comment, so that further scans will not flag the problem again.

Sharing a rule base

The first step in sharing a rule base is to create one, which can be done from the “Run –> Analysis…” menu.

Set the “Scope” to “Analyze selected projects”, without actually checking any project box. This will allow you to right-click any project and then run the analysis only on the selected project.

Under “Rules”, pick the ones you consider the most important. It took me a couple of scans on pre-existing code to weed out the faulty ones (there are a few) and the overly conservative ones. Once I was satisfied, I clicked on the “Export…” button to save it to a file I could share with my colleagues.

image

Importing a rule base

Starting from the “Run –> Analysis…” menu again, click on the “New launch configuration” button, give it a name. Again, set the “Scope” to “Analyze selected projects”, without actually checking any project box.

In the “Rules” tab, click on the “Import…” button and select the “.dat” file exported in the previous step, which is stored in a location shared with the entire team.

Scanning the code

Right-click a Java project and select “Analysis –> [Name of your launch configuration]”. In a few seconds, the results will be displayed in the “Analysis Results” view.

image

Right-clicking any of the individual results shows a menu with options for a “Quick Fix” (available for some rules) or the selection of “Ignore Result”. The latter option will add a Java comment next to the flagged line of code, instructing the analyzer to not flag the problem in future scans.

image

image

Monday, May 18, 2009

AspectJ for Java logging: suppressing System.out debugging calls - part 7

We have all been there, adding a few System.out calls here and there to our Java code during development to help debug something that defies (bad) logic.

It seems all too common to, ahem, leave some of those calls behind, which introduces several problems in a product. Don't we love to see the occasional "WE ARE HERE!!" graffiti in the server console, or a 50MB trace file that cannot be opened by any text editor?

One way to prevent this problem is to continuously demand that developers pay attention to it, either deleting the offending statements or converting them to a Logger.log call. That approach also has drawbacks in that mistakes are, well, mistakes. A complementary approach to pleading with developers is to intercept the requests to System.out and System.err and route the "println" commands to a trace call.

Here are the changes to the Logging serviceability aspect. I still want to find a way to use the name of method calling System.out.println in the trace calls, but for now, here are the interesting bits:

...

public aspect Logging pertypewithin((my..*) && !Exception+){

/**
* Trace handler for each type.
*/
private static Logger trace = Logger.getLogger("my.project" ) ;

private static TracePrintStream sysoutTrace = null;

...

/**
* After the initialization of all classes in this project.
*/
after(): dcofpClassInitializer() {
String classname = thisJoinPointStaticPart.getSourceLocation()
.getWithinType().getName();
classname = LoggingUtil.normalizeClassName(classname);
trace = Logger.getLogger(classname);
sysoutTrace = new TracePrintStream(trace, "System.out", System.out);
}

...

/**
* Replace calls to SystemOut with trace calls
*/
PrintStream around(): dcofpSystemOutPrintln() {
return sysoutTrace;
}

...

/**
* Inner class used to convert System.out.println calls to trace calls.
*/
public class TracePrintStream extends PrintStream {
...
public void println(String str) {
trace.logp(Level.FINER, trace.getName(), method, str);
}
...
}
}