Tim Burns' Personal Weblog Flavored with Math, Java, and Oracle
 
Thursday, May 20, 2004 [*]
 

Using Regular Expressions to Improve Your Unit Tests

The bane of unit test suites are false positives and false negatives. False positives are tests that fail even though the code is correct. False negatives are tests that succeed even though the code is incorrect. False negatives scare me, because I wonder what other little surprises lurk in my code. False positives are just annoying. I have to stop what I should be doing and rummage through some old code, only to find out something has changed in the database, or that the test wasn't well written in the first place.

Some people advocate using mock objects to provide a stable database interface, but they are a poor choice for database programming. They increase the chance of a false negative. Unit tests for database code should validate that everything you intended to store was stored, or everything you intended to load was loaded. If the test is simply mocking up the database interface, it isn't testing the code that will be run in the real world. Waste of time.

False positives arise when the test depends of some data in the database staying the same. Of course, the data will change, because that's why I need a database, so eventually the test will fail even though the code is still correct. Say I have a user object. The most simple test I would use is one that loads the user from the database and checks to see everthing is there. I would first write this test in JUnit:

      public void testLoadNextUser() throws SQLException {
        User user = (User) db.load(db.findNextInQueue()); 
        assertEquals("", user.toString());
      }
    
The load option loads the user for a given integer id, and findNextInQueue returns the id of the next user in some database queue. Initially the test will fail, but as long as I'm diligent and over-ride toString() in the User object, then I'll see what I'm looking for. The temptation is to just update my unit test so it succeeds, but that sets me up for a false positive on down the line, so this is what I don't want to do.
      public void testLoadNextUser() throws SQLException {
        User user = (User) db.load(db.findNextInQueue()); 
        assertEquals("User [id=1232 username='timb' fullname='Tim Burns']",
           user.toString());
      }
    

I've found that regular expressions are a great way to solve this problem.

      public void testLoadNextUser() throws SQLException {
        User user = (User) db.load(db.findNextInQueue()); 
        Perl5Util re = new Perl5Util();
        assertTrue("Expected user=" + user.toString() + " to match regular expression", 
            re.match("m/User [id=(\\d+)\\s+\\.+/", user.toString());
        // Assert the id is > 0 for sanity
        assertTrue("Id=" + id + " must be > 0", 
            Integer.parseInt(re.group(1)) > 0);
      }
    

The "assertTrue" clause in JUnit is especially useful with regular expression matching, because I can see exactly the string if it doesn't match. The ability to pull out groups and perform other logic on the group entries also is invaluable for writing tests that do not fail when something really is wrong.

 
Comments [3]
 
xml    Blogroll Me!

Personal

Discovering My Own Backyard

At Least Databases Don't Fly Away

Southwestern Baby Shower Menu

Morning of the Wolf

Autumn lingers in New England

Foraging and Shopping

 

Math, Java, and Oracle

Data Cubing Tools and the Oracle 10g Mess
Tracking Errors with JavaMail
Calculating a Moving Average In Oracle
The SVD, Benchmarking and Optimization
The Problem with Software Engineers
Fun with Optimization
Anything new under the sun?
Really Simple Tomcat, Really
J2EE with Free Software
 

Mushrooms

Coprinus Plicatilis
 

The Daily Chronic

 

References

BioInformatics

BioTech

Epicurious

Statistics

 

Archive

2004
 May 05 06 10 11 12 15 20 24 25
 April 01 04 07 09 11 16 17 18 20 22 24 25 27 29
 March 02 15 21 22 24 27
 February 13
 January 04 16 19 29
2003
 December 06 12
 November 02 23 29
 October 07 11 12 16 18 21 24 26
 September 04 09 10 12 14 28
 August 05 08 13 17 18 25 29
 July
 June
2002
2001
 

Photos

Morning of the Wolf
Phantom Farms
Providence
Baby Shower
Camden, Maine
 

Wiki

Creative Commons License
This work is licensed under a Creative Commons License