The open source software (OSS) community is an anarchist's dreamno governing body, no ownership of property, freedom in speech and action. The community is practically an organized religion, with gurus around which the devoted eagerly gather. We also have templesGNU, Apache, Jakarta (the Apache sect responsible for Java), SourceForge (home of a multidenominational congregation), JBoss, ExoLab, JUnit (a small deviant sect that's growing rapidly). We even have our fair share of religious bigotswitness the attacks on followers of the church of Microsoft.
GNU is actually all about free software, not open source software.
This article is part of a project to document and connect best practices in Java development with the most popular open source tools and libraries. Eventually this will blossom into a book and a web site. For this article, however, the idea is just to describe the tools that all Java developers need to know.
JUnit and Friends
JUnit was conceived as part of extreme programming, and has now been ported to just about every platform for which a programmer exists. JUnit allows you to write and execute unit tests rapidly. These two featureslow energy costs and tests that run fastwere primary factors in JUnit's evolution. Authors Kent Beck and Erich Gamma knew that if it was hard and slow, nobody would use it.
JUnit itself only provides a framework against which to write simple tests. The concept is simple: For each Class you write, you also write a TestClass that contains all the tests for that class. The TestClass is a TestCase; that is, you must extend TestCase to create TestClass. It's possible to have multiple test cases for each class you write, but usually it's unnecessary. Test cases are gathered into test suites, and the whole thing runs at the press of a button.
When I'm writing tests, I'm constantly switching backward and forward between tests and code. I run tests multiple times each minute, making small changes between runs. If writing tests took more time, I probably wouldn't do it. I can write tests without slowing downin fact, it feels like I'm going really fast. The unit tests improve the quality of my code, which in turn increases my productivity.
JUnit has to be kept simple, so the creators haven't added the many features that developers have requested. Instead, they built the core framework so that it was easy to extend. Now developers choose just the libraries they need.
J2EE developers: All of the JUnit tools and extensions can be located through the JUnit web site.
JUnit-Addons is the first of JUnit's friends that we'll discuss. It was developed to fill a number of important gaps in JUnit's base feature set. Two of its features are helpful enough to be used almost every day:
Private parts. While it's always a good idea to treat the class you're testing as a black box, sometimes this is impossible, particularly if you're doing test-driven development. The facilities offered by JUnit-Addons are sufficient even for the most demanding of needs. It offers a simple technique for accessing private attributes and methods, even on the class (static).
Arrays. When you're comparing two arrays for equality in JUnit, you're actually only comparing the array references. JUnit-Addons extends JUnit to include the ability to iterate through the arrays, comparing elements. Although arrays have nearly been replaced by collections, there are still some places where it's good to use an arrayparticularly if you want to create an array initializer. In these places, you need JUnit-Addonsotherwise, your arrays go untested.
While many enlightened developers follow the J2EE path, some still find time for the simpler pleasures of Swing.
Industry rumor: Microsoft slipped one of their designers into Sun to gather industrial espionage. He was nearly caught, but managed to convince people that he was part of the Swing team by designing a layout controller. While he was at it, he threw in some industrial sabotage, and the result is the GridBagController.
Still oblivious to the damage, Sun later invited him back, and he designed the SpringLayout in JDK1.4.
If you write GUIs, you have to test them. To test Swing GUIs, you need jfcUnit. jfcUnit is a wonderful library that helps you gain complete access to your GUI and control it using software robots that can press buttons, move the mouse, and press keys (all simulated, of course).
jfcUnit allows you to code your GUI driver in Java. There are significant benefits to this approach versus recording human/computer interaction sessionsespecially if you're doing test-driven-development or extreme programming. If you're writing your code test-first, you'll have problems using an interaction recorder, because there's no GUI to record until you've written the tests. In this paradigm, you have no choice but to code the GUI tests by hand.
Mock Objects are a way of testing complex environmental objects and having them behave the way you want. You want to test the way your code interfaces with a database. Easy, right? But what about testing your code's behavior when the database goes down? A good solution would be to create a mock database, using Mock Objects. The idea is that you create something that conforms to the database's interface, setting it up in any way you want, which includes responding as if the database has gone down. You can forget about rolling back data; just make the mock object return the necessary figures, even allowing it to calculate them if you want.
At the Mock Objects web site, you can download a library of mocks for most of Java's complicated interfaces, such as servlets, SQL, and I/O. There are also links to a few tools that will allow you to generate interfaces so you can mock out your host integration, or resolve other difficult problems.
I can't very well talk about Java without talking about J2EEthere are no hard figures on this, but I'd guess that a very large portion of Java developers are in the J2EE space.
Of course, the enlightened use HTML for all their human/computer interaction needs. It doesn't matter how you generate itservlets, JSP, Struts, XML/XSLT, whateveryou're still going to have to test that front end. Common wisdom has it that HTTPUnit is fit for this taskbut I disagree. HTTPUnit is a powerful and useful tool, but if you're just going to test HTML forms then I recommend Canoo WebTest.
WebTest allows you to write your tests as an ANT script. (If you don't know what ANT is, scan ahead and read that section.) It includes a custom task to parse the test script and run it. The test script is in XML, and is extremely simple to write. A tag called invoke takes a URL as its parameter. This is a simple call to the web server. You can use tags such as verifyTitle, setInputField, getInputField, clickButton, and so on. It's all intuitively simple, and it works well.
Servlets, Enterprise Java Beans (EJBs), Etc.
Of course, no coverage of J2EE testing tools would be complete without discussing Cactus. Cactus, from the Apache Jakarta tribe, is probably the most well-known JUnit extension in the J2EE world.
Cactus allows you to test your code's interaction with its container. (Actually, it allows much more than this, but this is what makes it most useful.) It lets you check whether the container does what you expect it to do, and whether your code is a well-behaved member of the container's application family. It does this by running as a servlet within your container of choice, so it works well with Tomcat, JBoss, WebSphere, WebLogic, whateverit doesn't care. It allows you to test servlets and/or EJBs.
I'm not going to talk about testing JSPsthere shouldn't be anything in your JSP that needs testing. It generates HTML, so test that with WebTest or something similar.