Programming Tutorials Browser Tutorials Articles Struts Tutorials Hibernate Tutorials

  Tutorial: Test infect your Enterprise JavaBeans - JavaWorld May 2000

Test infect your Enterprise JavaBeans - JavaWorld May 2000

Tutorial Details:

Test infect your Enterprise JavaBeans
Test infect your Enterprise JavaBeans
By: By Michael T. Nygard and Tracie Karsjens
Learn how to test your J2EE components live and in the wild
e can never overtest software, but we seldom test it enough. When testing does begin, system or integration testing is the norm, with formal testing and quality assurance efforts typically starting at the last minute -- when the software is nearing release. Inevitably, pressure builds on testers to rush through the testing process. Needless to say, this does not encourage thoroughness. At the same time, the development team is urged to fix defects as quickly as possible. This, too, does not promote careful attention to detail. When this process does produce high-quality software -- a rare occurrence -- it is the result of superhuman efforts by conscientious individuals.
Since a J2EE application is assembled from components, integration testing comes too late in the process. Individual components often behave differently when they are by themselves than when assembled with other components. To eliminate unexpected interactions, J2EE components must be unit tested before they are gathered into an application. This article discusses unit testing techniques and how to apply unit testing to J2EE components, particularly Enterprise JavaBeans (EJBs).
Note: The complete source code for this article, including JUnit 3.2 sources, the servlet interface, build scripts, the deployment descriptor, and the sample tests can be downloaded as a zip file in Resources .
Unit testing
If you are already test infected, skip to the next section. If not, you need to know about the benefits of real unit testing.
Unit testing is a critical, but often misunderstood, part of the software development process. Unit testing involves individually testing each small unit of code to ensure that it works on its own, independent of the other units. In object-oriented languages, a unit is often, but not always, equivalent to a class.
If developers knew for certain that each piece of the application works as it was designed to do, they would realize that problems with the assembled application must result from the way the components were put together. Unit testing tells developers that an application's pieces are working as designed.
For example, if you were building a car, you would probably construct each of its many complex components separately. Unless you tested each piece individually before assembly, you would have a lot of trouble figuring out why the car doesn't run correctly after it is put it together. For example, was the transmission built improperly, or did you hook it up incorrectly? Without having evaluated each piece beforehand, you have no way of knowing whether one or more of the pieces was built incorrectly, whether your integration was faulty, or both. Imagine the amount of time you would waste trying to analyze what was wrong with the car. And how much confidence would you have in its long-term reliability? If you had tested each component by itself before assembly, you would be able to focus your debugging efforts on the integration -- the way you assembled the car. And since you would have confidence in the individual pieces of the car, you would have more confidence in the car as a whole.
For the same reasons, it is important to unit test software. But, just as you wouldn't test the car parts without test-driving the completed car, you must also follow unit testing with integration testing and functional testing. Unit testing is just one part of a good, solid software development process.
Unit tests are typically organized into groups or suites of tests. A project's unit test suites should always execute successfully at 100 percent. Any failure in the unit tests instantly becomes a top priority for responsible developers.
These unit tests are useful for programmers long before deployment. A wide-reaching unit test suite bolsters confidence by allowing developers to change the code without fear of breaking it. Any change that would break the code will immediately be caught by a unit test that fails. Also, though unit testing does not focus on code coverage, developers know which parts of the code are most likely to break and will test those parts more rigorously.
Unit testing at this level also catches problems long before any other testing method will reveal the defects. Developers will usually run the unit tests every 10 or 15 minutes. When a test fails, developers must debug only the last 10 minutes' worth of changes at any one time. With other testing methods, developers sometimes must debug changes made over the span of several months.
Unit testing allows developers to start writing tests before writing the code.
The process works this way:
Decide what the component should do.
Design the component. This can be done formally or informally, depending on the complexity of the component.
Write unit tests to confirm that behavior. At first, the tests will not compile, since the code they test is not yet written. Your focus here is on capturing the intent of the component, not on the implementation.
Start coding the component to the design. Refactor as needed.
When the tests pass, stop coding.
Consider other ways the component can break; write tests to confirm and then fix the code.
Each time a defect is reported, write a test to confirm. Then fix the code.
Each time you change the code, rerun all tests to make sure you haven't broken anything.
By writing the test cases before producing the code, you gain clarity of purpose. This system lets you understand exactly what the requirements for that component are because you just captured those requirements in code. You also gain a unique opportunity to explore the requirements. For example, suppose you are asked to create a string parsing utility. Your requirements might specify certain tasks the string parser must perform, but they might not specify what the parser should do with an empty or null string. If you don't consider this detail while creating the component, a nasty and a difficult-to-trace NullPointerException could result at runtime. By writing the test cases in advance, you will take into account items that could cause the component to fail.
In addition to helping clarify the requirements, your test cases prevent you from overdesigning or complicating your implementation. After all, when the tests run, you simply stop coding. You also gain the freedom to change your classes more confidently. Instead of wishing you could change a particular piece of code and being unsure what effect it would have on the system, you can now make your changes without worry. Your tests will tell you what the impact of your changes is.
Maintenance also benefits from unit tests. It is often easier to figure out a component's expected use by reading its tests than by reading the object itself. As maintenance developers make changes, they use the unit tests, which give instant feedback. Regression testing doesn't have to take place immediately before release; you can test continually -- every 10 or 15 minutes. You have captured the requirements for your code in the one place guaranteed to live as long as the code -- the code itself.
The JUnit framework, written by Erich Gamma and Kent Beck, enables comprehensive unit testing by making it easy -- even fun -- to write test code. With JUnit, each test case extends the TestCase class. Any public, no-argument method in which the name starts with "test" is executed one at a time. The test methods call the component under test and make one or more assertions about the behavior of that component. JUnit reports the precise location of each failed assertion.
As an example, let's think about a simple telephone number object. What behavior should it have? At a minimum, it will have accessors for the components of a U.S. number: area code, exchange, number, and extension. We should also have a formatter that gives a nice string representation. Remember, we write the test first.
The following idiom starts a test case that can run by itself or be incorporated into a larger suite of tests:
import junit.framework.*;
public class TelephoneNumberTests extends TestCase {
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite() {
return new TestSuite(TelephoneNumberTests.class);
}
}
This test will execute. Since there are no test methods, it reports an error. What do we need to add for test methods? The rule of thumb is: If it can possibly fail, write a test for it. There are some exceptions to this rule, however. For example, since simple accessor methods rarely fail, they rarely are tested. Of course, if your accessor does more than just set an instance variable, you should write a test for it. Choosing precisely what to test takes some practice.
Here is a test method for the string formatting:
public void testSimpleStringFormatting() throws Exception {
// Build a complete phone number
TelephoneNumber number = new TelephoneNumber("612", "630", "1063",
"1623");
assertEquals("Bad string", "(612) 630-1063 x1623",
number.formatNumber());
}
The assertEquals() method takes a message string, the expected value, and the actual value. Internally, if expected.equals(actual) returns false, the assertion fails.
This method verifies the basic case, but we can think of many ways for string formatting to fail. What happens if any or all of the parts are null? toString() must do something reasonable. Let's say the area code and extension are optional, but the exchange and number must be present or a NullPointerException will be thrown. Notice that we are defining the contract of the TelephoneNumber object well before writing the object itself. We are focused on its expected behavior, not on what is easiest to implement.
Here are the new test methods:
public void testNullAreaCode() throws Ex


 

Read Tutorial at: Click here to view the tutorial

Rate Tutorial:
Test infect your Enterprise JavaBeans - JavaWorld May 2000

View Tutorial:
Test infect your Enterprise JavaBeans - JavaWorld May 2000

Related Tutorials:

JSP best practices
Follow these tips for reusable and easily maintainable JavaServer Pages
 
Connect the enterprise with the JCA, Part 2
Connect the enterprise with the JCA, Part 2
 
Step into the J2EE architecture and process
Step into the J2EE architecture and process
 
Test networked code the easy way
Test networked code the easy way
 
J2ME devices: Real-world performance
J2ME devices: Real-world performance
 
Get the inside track on J2EE architect certification
Get the inside track on J2EE architect certification
 
Unwrap the package statement's potential
Unwrap the package statement's potential
 
Servlet 2.4: What's in store
Servlet 2.4: What's in store
 
Test email components in your software
Test email components in your software
 
Finally, getting hands in !
Finally, getting hands in !
 
Object-relation mapping without the container
If you follow the latest developer buzz then you\\\\\'ve likely heard of IOC (Inversion of Control) containers and AOP (aspect-oriented programming).
 
Control your test-environment with DbUnit and Anthill
The inception of the Extreme Programming methodology has brought test-driven development and continuous integration into mainstream Java development practices. Applying these techniques to Java server-side development can quickly become a nightmare if you
 
Developing Swing Components Using Simulators
Developing Swing Components Using Simulators In this article, you'll learn about a technique for developing encapsulated components. You'll also learn about how to test graphical parts of your application that JUnit can't, such as layouts and other visua
 
Turn EJB components into Web services
Summary Web services have become the de facto standard for communication among applications. J2EE 1.4 allows stateless Enterprise JavaBeans (EJB) components to be exposed as Web services via a JAX-RPC (Java API for XML Remote Procedure Call) endpoint, al
 
Developing Your First Enterprise Beans, Part 1
One of the most important features of EJB is that enterprise beans have the ability to work with containers from different vendors. However, that doesn't mean that selecting a server and installing your enterprise beans on that server are trivial processe
 
A lightweight nonintrusive EJB testing framework
A lightweight nonintrusive EJB testing framework Summary This article presents a simple, easy-to-deploy framework that enables fine-grained tests to be run on the container, making it possible to develop and maintain Enterprise JavaBeans components usin
 
Testing Your Enterprise JavaBeans with Cactus
Enterprise JavaBeans provide many advantages. But each server-side/back-end developer knows that development of EJBs is sometimes painful, time-consuming, and requires a lot of patience while creating assembly descriptors, application-server-specific conf
 
Developing Distributed application using Enterprise Java Beans, J2EE Architecture, EJB Tutorial, WebLogic Tutorial.
Developing Distributed application using Enterprise Java Beans, J2EE Architecture, EJB Tutorial, WebLogic Tutorial. Distributed Architecture Two-tier application: In the past two-tier applications were used. Two-tier applications are also know as
 
developing a Session Bean and a Servlet and deploy the web application on JBoss 3.0
developing a Session Bean and a Servlet and deploy the web application on JBoss 3.0 Writing Stateless Session Bean and Calling through Servlet Previous Tutorial Index Next In this lesson I will show you how to develop a Stateless Session Bean and
 
NetBeans IDE 4.1
Out-of-the-box support for J2EE 1.4 and Web Services. Check out what early access release 2 can do for you!
 
Site navigation
 

 

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright © 2006. All rights reserved.