| By Ted Husted | Article Rating: |
|
| December 24, 2007 11:00 PM EST | Reads: |
18,767 |
An excellent way to explore an unfamiliar application is to create unit tests. Tests not only alert us when something is wrong; tests demonstrate how the code actually works. Of course, creating unit tests for existing code isn't trivial, especially when it comes to code we didn't write.
A case in point is the Spring JPetStore. JPetStore is a production-quality rendition of Sun's infamous PetStore application, originally created by Clinton Begin to showcase using iBATIS with Struts. The Spring rendition added a Spring MVC implementation and refactored the business layer for Spring. Surprisingly, the Spring JPetStore doesn't include a suite of unit tests against the business logic. The Spring JPetStore welcome page is shown in Figure 1.
We'd like to bring the Spring JPetstore up-to-date with the latest version of iBATIS and add a Struts 2 implementation. But before starting on that, we'd like to add a set of unit tests for the back-end. With a good set of tests on board, we can make changes and not worry that something will break without notice. Kent Beck, widely recognized as the father of eXtreme Programming and JUnit, tells us that we should "test until fear turns to boredom." Good advice, but being lazy, we'd rather not create all the tests by hand.
Avoid Drudgery with Generated JUnit Tests
JUnit Factory (www.junitfactory.com, shown in Figure 2) is a free test generation service offered by Agitar Software that can generate tests by analyzing source code. JUnit Factory is powered by the same technology that's behind AgitarOne, Agitar's comprehensive, server-based unit testing solution for Java.
We can submit code to the JUnit Factory service with either a Web browser or an Eclipse plug-in. JUnit Factory analyzes the code and generates unit tests based on how the code behaves.
In this article, we'll use JUnit Factory to create a suite of standard JUnit tests for the Spring JPetstore business layer, so that we can refactor or extend the business logic with confidence. As we change the JPetStore code, we'll run the tests to see whether we have broken any of the code's existing behavior. As we go along, we can update the tests by hand, generate new tests, or both.
Say Hello To Generated JUnit Tests
Before we study the JUnit tests for JPetStore, let's take a look at the JUnit tests generated for two simple examples. Of course, the first example is "Hello World!" shown in Listing 1.
A reasonable unit test for HelloWorld, as generated by JUnit Factory, is show in Listing 2.
Nothing fancy, but it shows us exactly what the application does: it says Hello World!
From now on, whenever we change the HelloWorld class, we can run testSayHello() to see if anything breaks. If a test does fail, it's a signal that a method doesn't work the same way anymore. Sometimes, a failing test means that our change had unexpected consequences and by fixing one bug we've accidentally created another. (So, it's back to the drawing board!)
Other times, a failing test means that we've changed our expectations of how the code should behave, and the failing test is now obsolete. With conventional JUnit tests, an API change means we have to update any outdated tests. With a tool like JUnit Factory, instead of rewriting obsolete characterization tests, we can regenerate those tests instead, and create a new baseline.
What about something a little more challenging like the calculation of a leap year shown in Listing 3?
Given a method with various output possibilities, JUnit Factory will generate a set of unit tests such as those shown in Listing 4.
To do unit testing right we need a lot of tests - more tests than most of us would like to write. Along with the main "success" path, we should also check boundary and edge conditions: what happens if the year is zero, or if the year is divisible by 4, or if the year is exactly 4, and so on.
In Listing 4, we can see that JUnit Factory was able to generate a decent array of tests for the LeapYear class - again far more unit tests than most of us would have the patience to devise and code, especially for code we didn't write ourselves.
Agitar calls the tests it generates "characterization tests" to emphasize that these JUnit tests reflect what the code actually does.
The generated tests always work if you run them against the original code under test. When run as regression tests, characterization tests serve as API change detectors: if we change an application and find that one or more characterization tests fail then we should consider the change "on notice." We might need to rework the change, or we may have to regenerate the tests. But, either way, characterization tests red-flag changes in public behavior.
Generate JUnit Tests for JPetStore
The JUnit Factory site is fun, but it only works with classes that have no dependencies. To generate tests for an entire application such as JPetStore, we need to use the JUnit Factory Eclipse plug-in, which is also free.
JPetStore is a shopping cart application. Visitors can browse our inventory, add items to a virtual shopping cart, and place an order for the items when ready.
To generate tests for JPetStore, we should first isolate which classes we'd like to test. Unit testing is best suited to plain Java objects that handle business logic. Other objects, including data access objects, can be tested too, but that requires more setup.
Like many applications, the core of JPetStore is represented as a set of business objects that represent entities in the problem domain. In our case, the business entities are client accounts, inventory products, product categories, inventory items, shopping carts, sale orders, and sale items. The JPetStore business objects are conveniently gathered into a package named domain.
Let's say that we've installed the JUnit Factory plug-in and created a Java project. To generate characterization tests, all we have to do is right-click in Eclipse's Package Explorer view then select Agitar/Generate Tests. The plug-in submits the classes to the JUnit Factory Web site and within a few minutes the JUnit Factory will generate and return over 100 tests, organized in separate test suites for each of the eight classes.
Published December 24, 2007 Reads 18,767
Copyright © 2007 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
About Ted Husted
Ted Husted (http://husted.com/ted/) is a software engineer and an active member of several open source projects hosted by the Apache Software Foundation, including Struts and iBATIS. His books include JUnit in Action, Struts in Action, and Professional JSP Site Design. Ted is also a consultant for Agitar Software, Inc.
![]() |
Alexander Klimuk 01/14/08 06:37:02 PM EST | |||
This article resembles the video of Alberto Savoia from Agitar, which is available as of Sep 2007 at 'theserverside.com': Well, a bit different wording, and that's all. Why haven't you just placed a link to that video and discussion on TSS site? Regards, |
||||
- Performance of Java Compilers: An Empirical Study
- Java Kicks Ruby on Rails in the Butt
- Ulitzer’s Amazing First 30 Days in Public Beta
- 1st Annual Government IT Expo: Call for Papers Deadline July 15
- REA Is Where RIA Becomes the Norm
- Why an Application Grid?
- Will Ulitzer Dominate News Content on The Web? -Gartner
- Profiling Netbeans within Amazon EC2
- Clear Toolkit 4: The Road Map
- Java Persistence on the Grid: Approaches to Integration
- Performance of Java Compilers: An Empirical Study
- Java Kicks Ruby on Rails in the Butt
- Developing Rich Client Applications Using Swing - II
- The Right Time for Real Time Java
- Xpress Suite Adds Automatic Java to iPhone Conversion
- Building Better Phone Applications with SOA and Eclipse
- Initial Thoughts on IBM Acquisition of Sun Microsystems
- Ulitzer’s Amazing First 30 Days in Public Beta
- 1st Annual Government IT Expo: Call for Papers Deadline July 15
- Maximizing Java Performance with Bespoke Programming
- A Cup of AJAX? Nay, Just Regular Java Please
- Java Developer's Journal Exclusive: 2006 "JDJ Editors' Choice" Awards
- The i-Technology Right Stuff
- JavaServer Faces (JSF) vs Struts
- Rich Internet Applications with Adobe Flex 2 and Java
- Java vs C++ "Shootout" Revisited
- Bean-Managed Persistence Using a Proxy List
- Reporting Made Easy with JasperReports and Hibernate
- What's New in Eclipse?
- Creating a Pet Store Application with JavaServer Faces, Spring, and Hibernate







































