My Secret Life as a Spaghetti Coder
home | about | contact | privacy statement
Have any of you Java guys or gals seen or tried JUnit Factory from Agitar? It generates functional unit tests for each method in a given class. A good description of how this can be used (since it can't detect how you expect the code should work, only how it does work) is provided in the FAQ:
What do these so-called tests actually test? Don't they just check that the code is doing what it's doing?
You are absolutely right. The tests that JUnit Factory generates are best described as characterization tests. These are tests that characterize the actual behavior of the code. They record and test not what the code is supposed to do, but what it actually does. The term characterization tests was introduced by Michael Feathers in his book Working Effectively With Legacy Code – a great book by the way.

How are these characterization tests useful?
Characterization tests are change detectors and are particularly useful when working with legacy code. In Working With Legacy Code (you should really get this book), Michael Feathers defines legacy code as code without tests. When modifying legacy code you are working without a safety net. You make specific changes but you don't know if those changes have some unwanted or unexpected side effects. A good set of characterization tests can serve as a safety net because these tests will show you when you have changed some existing behavior. Of course, only you – the developer - can decide if the change is what you had intended or not. In many cases, the tests will show that your changes have some intended effects and some unintended side-effects.

Can I use the generated tests in some other ways?
Sure. Since the test generator does not know how you meant your code to be used, it tries all sorts of things and uses a wide range of valid and invalid inputs – including things that you did not plan for or anticipate. By reading the generated tests you will often discover behavior that you did not want or expect. Seeing a generated test method called testFooThrowsArrayIndexOfBoundException for example, lets you know that method foo() throws an AIOOBException. Is this exception something that you expected? If the answer is yes, then fine, you now have a test for that. If the answer is no, you can fix your code accordingly.
I tried a simple MathFunctions class in the online demo:

public class MathFunctions {

public int add(int x, int y){
return x+y;
}
public int subtract(int x, int y){
return x-y;
}

public int multiply(int x, int y){
return x*y;
}

public int divide(int x, int y){
return x/y;
}
}

and it responded with the following tests (pardon the lack of formatting - I'm just lazy at the moment):

/**
* Generated by Agitar build: Agitator Version 1.0.4.000276 (Build date: Mar 27, 2007) [1.0.4.000276]
* JDK Version: 1.5.0_09
*
* Generated on Apr 7, 2007 2:19:39 PM
* Time to generate: 00:03.788 seconds
*
*/

import com.agitar.lib.junit.AgitarTestCase;

public class MathFunctionsAgitarTest extends AgitarTestCase {
static Class TARGET_CLASS = MathFunctions.class;

public void testConstructor() throws Throwable {
new MathFunctions();
assertTrue("Test completed without Exception", true);
}

public void testAdd() throws Throwable {
int result = new MathFunctions().add(100, 1000);
assertEquals("result", 1100, result);
}

public void testAdd1() throws Throwable {
int result = new MathFunctions().add(0, 0);
assertEquals("result", 0, result);
}

public void testDivide() throws Throwable {
int result = new MathFunctions().divide(0, 100);
assertEquals("result", 0, result);
}

public void testDivide1() throws Throwable {
int result = new MathFunctions().divide(100, -1);
assertEquals("result", -100, result);
}

public void testMultiply() throws Throwable {
int result = new MathFunctions().multiply(100, 0);
assertEquals("result", 0, result);
}

public void testMultiply1() throws Throwable {
int result = new MathFunctions().multiply(100, 1000);
assertEquals("result", 100000, result);
}

public void testSubtract() throws Throwable {
int result = new MathFunctions().subtract(2, 2);
assertEquals("result", 0, result);
}

public void testSubtract1() throws Throwable {
int result = new MathFunctions().subtract(100, 1000);
assertEquals("result", -900, result);
}

public void testDivideThrowsArithmeticException() throws Throwable {
try {
new MathFunctions().divide(100, 0);
fail("Expected ArithmeticException to be thrown");
} catch (ArithmeticException ex) {
assertEquals("ex.getClass()", ArithmeticException.class, ex.getClass());
assertThrownBy(MathFunctions.class, ex);
}
}
}

It looks pretty promising.

Hey! Why don't you make your life easier and subscribe to the full post or short blurb RSS feed? I'm so confident you'll love my smelly pasta plate wisdom that I'm offering a no-strings-attached, lifetime money back guarantee!


Comments
Leave a comment

Steve Bate had some first-impressions comments after using the Eclipse plugin version that I consider useful reading:

http://blog.technoetic.com/2007/04/08/junitfactory...

Posted by Sam on Apr 09, 2007 at 07:07 AM UTC - 5 hrs

Hi Sam,

Thank you for trying and blogging about JUnit Factory. But I am sure you can challenge it with something a bit more challenging that those simple arithmetic methods. How about trying some of that famous spaghetti code of your yours. Perhaps you get back some saucy meatballs tests to go with it :-).

Alberto

Posted by Alberto Savoia on Apr 09, 2007 at 09:52 AM UTC - 5 hrs

Alberto - Oh believe me, I plan to. =) I'm just pressed for time at the moment because its the end of the semester and everything's due this month.

I thought I might bust out some of the smelly code from an old Java project, or else write something at least a bit more challenging than elementary math functions =). Look forward to it at some point at least.

In any case, when did you guys release this? I just happened across it the other day (I didn't see an announcemment, but I haven't been keeping up with the usual venues for those things either) I just saw it in a sig file from someone on one of the agile-related lists and decided to check it out.

Cheers, and thanks for the challenge. =)

Posted by Sam on Apr 09, 2007 at 10:47 AM UTC - 5 hrs

Leave a comment

Leave this field empty
Your Name
Email (not displayed, more info?)
Website

Comment:

Subcribe to this comment thread
Remember my details
Google
Web CodeOdor.com

Me
Picture of me

Topics
.NET (19)
AI/Machine Learning (14)
Answers To 100 Interview Questions (10)
Bioinformatics (2)
Business (1)
C and C++ (6)
cfrails (22)
ColdFusion (78)
Customer Relations (15)
Databases (3)
DRY (18)
DSLs (11)
Future Tech (5)
Games (5)
Groovy/Grails (8)
Hardware (1)
IDEs (9)
Java (38)
JavaScript (4)
Linux (2)
Lisp (1)
Mac OS (4)
Management (15)
MediaServerX (1)
Miscellany (76)
OOAD (37)
Productivity (11)
Programming (168)
Programming Quotables (9)
Rails (31)
Ruby (67)
Save Your Job (58)
scriptaGulous (4)
Software Development Process (23)
TDD (41)
TDDing xorblog (6)
Tools (5)
Web Development (8)
Windows (1)
With (1)
YAGNI (10)

Resources
Agile Manifesto & Principles
Principles Of OOD
ColdFusion
CFUnit
Ruby
Ruby on Rails
JUnit



RSS 2.0: Full Post | Short Blurb
Subscribe by email:

Delivered by FeedBurner