Get started with unit and component testing using IBM Rational tools

A comprehensive guide for unit and component testing

Component testing is essential for the integration of code that enables crucial application functionality. This tutorial takes you step by step through unit and component testing specifically for Java™ code, Web services, servlets, Service Component Architecture (SCA), and Enterprise JavaBeans (EJB) beans using the JUnit and Jakarta Cactus testing frameworks and simple HelloWorld samples. Also, learn how to automate these tests using IBM® Rational® Software Architect, IBM Rational Application Developer, and IBM WebSphere® Integration Developer.

Share:

Rosaline Makar (rosaline@eg.ibm.com), Software Engineer, IBM

Rosaline photoRosaline Makar is a software engineer at IBM Egypt Cairo Technology Development Center (C-TDC). Her current work areas include SOA and Web services. She has a B.Sc. in computer engineering and is currently preparing for a M.Sc. in computer science.



11 October 2007

Also available in

Before you start

About this tutorial

This tutorial covers unit and component testing for Java code, Web services, servlets, SCA, and EJB beans through HelloWorld samples (developing a HelloWorld program is considered the easiest way to learn new concepts). Here you perform unit and component testing using the JUnit and Jakarta Cactus testing frameworks.

Objectives

Upon completion of this tutorial, you should understand how to perform unit and component testing, and automate those tests with Apache Ant using IBM Rational Application Developer, IBM Rational Software Developer, or IBM WebSphere Integration Developer.

Prerequisites

To follow along with this tutorial, you should have a basic knowledge of the technology you want to test, whether it's SCA, servlets, EJB beans, Web services, or Java code. You should also have basic technical experience with the products listed in the System requirements section.

System requirements

In this tutorial, you can use any of the following tools to test Java code, Web services, servlets, and EJB beans:

  • Rational Software Architect V6.0
  • Rational Application Developer V6.0

To perform SCA testing along with Java, Web services, servlets, and EJB testing, you need WebSphere Integration Developer V6.0.1 or 6.0.2.

Running component testing requires IBM Rational Agent Controller, which is an add-on included in the Rational Software Architect bundle.


Introduction

Testing is crucial in any software development project. It simulates several execution paths to deliver a bug-free and well-tested product that ensures its robustness and high quality for the customer. Neglecting software testing—because of tight delivery dates, planning to rely on release fixes, or other reasons—increases the costs of fixing bugs that appear later. This is because bug fix costs increase drastically as the software development cycle continues.

There are four main testing types, or phases, performed within the software development cycle, as shown in Figure 1:

  1. Unit testing is white-box testing used to test basic units of code, including Java classes, Web services, EJB beans, and servlets.
  2. Component testing tests the integration of basic units of code to perform certain functions before they are integrated into the production code base.
  3. System testing tests the overall system and ensures that a group of components are integrated together.
  4. Acceptance testing tests whether the software product meets the customer's functional and nonfunctional requirements.
Figure 1. Software testing
Software testing

Note the pyramid-like structure, which emphasizes the importance of the testing sequence. For instance, after performing unit testing on each unit of code, you execute component testing to ensure the validity of the integration of these units of code.

JUnit is a regression testing framework for Java written by Erich Gamma and Kent Beck. As described on the Apache Web site, Cactus is a simple testing framework for unit testing server-side Java code (such as servlets, EJB beans, tag libraries, and filters). Cactus, which extends JUnit, is designed to lower the cost of writing tests for server-side code, and it implements an in-container strategy, which means that tests are executed inside the container server (see Resources for a link to more information about Cactus). Throughout this tutorial, you use the JUnit and Cactus testing frameworks to demonstrate unit and component testing. All the tests illustrated in this tutorial are available in the Download section at the end of this tutorial.


Prepare your testing environment

This section introduces the environment preparations needed throughout this tutorial.

Enable capabilities

If you're using either Rational Software Architect, Rational Application Developer, or WebSphere Integration Developer, you need to enable Web service development and testing capabilities:

  1. Select Window > Preferences > Workbench > Capabilities.
  2. Check Web Service Developer in the right pane, as shown in Figure 2.
Figure 2. Enabling capabilities
Enabling capabilities

JUnit testing preparation

The project that uses JUnit framework for testing must include junit.jar in its class path, which exists in <IDE_HOME>\eclipse\plugins\org.junit_3.8.1\junit.jar. <IDE_HOME> is the Rational Application Developer, Rational Software Developer, or WebSphere Integration Developer installation directory. For example, if you're using WebSphere Integration Developer, and its installation directory is at C:\Program Files\IBM\WebSphere\601, then junit.jar should be in C:\Program Files\IBM\WebSphere\601\eclipse\plugins\org.junit_3.8.1. To add junit.jar to the project class path:

  1. Right-click the project, and select Properties.
  2. Choose Java Build Path from the left pane.
  3. Go to the Libraries tab, and click Add External JARs.
  4. Browse to junit.jar, as shown in Figure 3.
Figure 3. Adding junit.jar to class path
Adding junit.jar to class path

Cactus testing preparation

To use the Cactus framework for server-side unit testing in a dynamic Web project, you must follow these steps:

  1. Add the following .jar files to WebContent\WEB-INF\lib:
    • aspectjrt-1.2.1.jar
    • cactus-1.7.2.jar
    • commons-httpclient-2.0.2.jar
    • commons-logging-1.0.4.jar
    • junit.jar

    Note: Cactus extends JUnit, hence junit.jar must be included. (The Cactus .jar files are available in the Download section or from apache.org.)

Now you need to add Cactus servlets that are crucial for calling test methods on the server side (through the ServletTestRedirector servlet), and add servlets that are necessary for running tests (through ServletTestRunner servlet). To add the servlets:

  1. Open the web.xml file of the dynamic Web project.
  2. Click the Source tab, and add the following two servlets, as shown in Listing 1:
    • Servlet name: ServletRedirector, Servlet class: org.apache.cactus.server.ServletTestRedirector.
    • Servlet name: ServletTestRunner, Servlet class: org.apache.cactus.server.runner.ServletTestRunner.
    Listing 1. Adding Cactus servlets
    <servlet>
      <servlet-name>ServletRedirector</servlet-name>
      <servlet-class>org.apache.cactus.server.ServletTestRedirector</servlet-class>
    </servlet>
    <servlet>
      <servlet-name>ServletTestRunner</servlet-name>
      <servlet-class>org.apache.cactus.server.runner.ServletTestRunner</servlet-class>
    </servlet>
    
    <servlet-mapping>
      <servlet-name>ServletRedirector</servlet-name>
      <url-pattern>/ServletRedirector</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
      <servlet-name>ServletTestRunner</servlet-name>
      <url-pattern>/ServletTestRunner</url-pattern>
    </servlet-mapping>
  3. To automate Cactus test cases using Ant and to run the Cactus Ant task, add cactus-ant-1.7.2.jar and cargo-0.5.jar under WebContent\WEB-INF\lib. (These .jar files are available in the Download section or from apache.org.)

Unit testing

This section covers the following types of unit testing:

  • Java and Web service unit testing using the JUnit framework
  • Servlet and EJB unit testing using the Cactus framework

Java unit testing

Create a Java class under test

The following steps show the Java class to be tested:

  1. Import HelloWorldJava.zip (available in the Download section) as a project interchange, or create a Java project called HelloWorldJava.
  2. Create a class named HelloWorld under the package com.ibm.tdc.
  3. Paste the code from Listing 2 into the HelloWorld class.
    Listing 2. HelloWorld Java code
    package com.ibm.tdc;
    public class HelloWorld {
       public String getGreeting (String name)
       {
          return "Hello! "+name;
       }
    }

Create a JUnit test case

A test case is a set of test inputs, execution conditions, and expected results developed for a particular objective. To create a JUnit test case for a certain Java class, follow these steps:

  1. Switch to the Java perspective.
  2. Right-click HelloWorld.java, and select New > JUnit Test Case.
  3. A message box appears for adding junit.jar to the build path, as shown in Figure 4.
    Figure 4. Adding junit.jar
    Adding junit.jar
  4. Click Yes.
  5. Click JUnit Test Case, and the Test Methods dialog box appears where there's mapping between the options selected and the Java code that will be generated. This comes from the New JUnit Test Case wizard, which is displayed in Figure 5.
    Figure 5. New JUnit Test Case wizard
    New JUnit Test Case wizard
  6. In the generated code, you can edit the test method for testing logic, as shown in Listing 3.
    Listing 3. HelloWorld unit test
    package com.ibm.tdc;
    import junit.framework.TestCase;
    public class HelloWorldTest extends TestCase 
    {
       private HelloWorld helloWorld;
       public static void main(String[] args) 
       {
          // TestRunner is used to execute test cases
          // textui is used to run test cases in text mode 
    	  junit.textui.TestRunner.run(HelloWorldTest.class);
       }
    
       /*
        * @see TestCase#setUp(), It is executed before each test method
        */
       protected void setUp() throws Exception 
       {
          super.setUp();
          helloWorld = new HelloWorld();
       }
    
       /*
        * Tests the getGreeting method
        */
       public void testGetGreeting() 
       {
          // The assertion succeeds if the left argument equals to the right argument
          assertEquals("Hello! Rose", helloWorld.getGreeting("Rose"));
       }
    }

    In Listing 3, please note the following:

    • public static void main(String[] args) is optional, but used to run the JUnit test case from the command line.
    • TestRunner is used to execute test cases.
    • textui is used to run test cases in text mode, hence the test results appear in the console.
    • setUp() is one of methods of the TestCase class. It's executed before each test method, while tearDown() is executed after each test method. Both setUp() and tearDown() are optional methods. In Listing 3, setUp() is used to make a new instance of the class under test.
    • testGetGreeting() tests the getGreeting() method. JUnit naming conventions state that test methods must have the prefix test and take no arguments, that is, it should follow this signature—public void testXXX() [throws ...]—because JUnit TestRunner uses reflection to run test methods automatically. There must be at least one test method in a test case, otherwise running JUnit test case causes a failure.
    • assertEquals() is used to compare the test result and the expected value. The assertion succeeds if the expected and the actual results are equal, and fails otherwise. JUnit provides different versions of assertion to support various output checking. (See Resources for a link to more information about the Assert class.)
  7. The JUnit test case execution is illustrated in the sequence diagram in Figure 6.
    Figure 6. JUnit behavior
    JUnit behavior

Run the JUnit test case

You can run the JUnit test case using one of the following two methods:

  • Right-click HelloWorldTest, and select Run > JUnit Test. A green bar appears, as shown in Figure 7, indicating the success of the test case. (A red bar indicates test-case failure or error.)
    Figure 7. Running the JUnit test case
    Running the JUnit test case
    Failures can occur due to:
    • Failure in the assertion statement.
    • The occurrence of the message, fail(String message), which is used to fail a test and may be placed inside a catch block.
    • No test methods are defined within the test-case class.
    Errors can occur due to:
    • An exception that hasn't been tested for and wasn't expected, for example, an exception that wasn't caught, such as NullPointerException.
  • Another method for running a JUnit test case is right-clicking HelloWorldTest and selecting Run > Java Application, which runs the test case as a Java application. Note that the test results, in the case of textui, appear on the console.
    Figure 8. Running the test case as a Java application
    Running the test case as a Java application

Create a test suite

A test suite is used to collect several test cases in one suite; so with one click you can run a number of test cases.

  1. Right-click the package of the test case, com.ibm.tdc, and select New > Other > Java > JUnit > JUnit Test Suite.
  2. Click Next.
  3. Select the test cases you want to include in the test suite, as shown in Figure 9, and click Finish.
    Figure 9. Creating new test suite
    Creating new test suite

The following code is automatically generated:

Listing 4. The AllTests test suite
package com.ibm.tdc;
import junit.framework.Test;
import junit.framework.TestSuite;
public class AllTests 
{
  public static void main(String[] args)
  {
     junit.textui.TestRunner.run(AllTests.suite());
  }
  public static Test suite() 
  {
     TestSuite suite = new TestSuite("Test for com.ibm.tdc");
     //$JUnit-BEGIN$
     suite.addTestSuite(HelloWorldTest.class);
     //$JUnit-END$
     return suite;
  }
}

In this case, addTestSuite() is used to add the test case classes.

Running a test suite is exactly the same as running the JUnit test case. Note that TestRunner looks for public static Test suite() to run the test suite.

Web services unit testing

What is a Web service proxy?

A Web service proxy is a set of generated classes from a Web Services Description Language (WSDL) file that are used to simplify client development by hiding lookup and invocation details in simple Java code.

You can test a Web service using JUnit by generating a proxy from the Web service. JUnit test cases are run against the proxy, which invokes the Web service under the hood. Successfully testing the proxy implies success in testing the Web service.

Create a Web service under test

To create a Web service under test, import HelloWebService.zip (available in the Download section) as a project interchange. This Web service has only one operation—getGreeting()—which functions as the HelloWorld class in the Java project that was tested previously. Listing 5 shows the Web service implementation.

Listing 5. Web service implementation
package com.yourco.www;
public class HelloPortBindingImpl implements HelloPortType
{
   public String getGreeting(java.lang.String name) throws java.rmi.RemoteException 
   {
        return "Hello! "+name;
   }
}

Create a Web service test

The following steps walk you through creating a Java project that contains the Web service client classes and the Web service unit test class:

  1. Create a Java project named HelloWebServiceTest to represent a Web service test project.
  2. To generate the Web service client (that is, proxy classes), create a folder named wsdl under the HelloWebServiceTest Java project.
  3. Paste the HelloService.wsdl file (retrieved from the HelloWebService project) in the wsdl folder.
  4. Right-click HelloService.wsdl, and select Web Services > Generate Client, as shown in Figure 10.
    Figure 10. Web service unit test
    Web service unit test
  5. In the Web Service Client wizard, follow the defaults in the wizard, then click Finish. Note that Web service run time must be indicated as IBM WebSphere in the Client Environment Configuration dialog box (see Figure 11).
    Figure 11. Client Environment Configuration
    Client Enviroment Configuration
  6. Right-click HelloPortTypeProxy.java, and select New > JUnit Test Case. It can be tested as any Java class (refer to the Create a JUnit test case section). Note that HelloPortTypeProxy contains the Web service operations.
  7. getGreeting() is the method that you test. You can complete the test case class with the code shown in Listing 6.
    Listing 6. Web service unit testing
    package com.yourco.www;
    import java.rmi.RemoteException;
    import junit.framework.TestCase;
    
    public class HelloPortTypeProxyTest extends TestCase 
    {
      private HelloPortTypeProxy helloPortTypeProxy;
      public static void main(String[] args) 
      {
         junit.textui.TestRunner.run(HelloPortTypeProxyTest.class);
      }
      
      protected void setUp() throws Exception 
      {
         super.setUp();
         helloPortTypeProxy = new HelloPortTypeProxy();
      }
      
      public void testGetGreeting() throws RemoteException 
      {
    	 String greeting = null;
         greeting = helloPortTypeProxy.getGreeting("Rosa");
         assertEquals("Hello! Rosa", greeting);			
      }
    }

Note:testGetGreeting() throws RemoteException because getGreeting() throws this exception.

Run a Web service test

Perform one of the following steps to run the Web service test, and different failure and error scenarios:

  • Refer to the Run the JUnit test case section to run the test case. According to the testGetGreeting() code in Listing 6, if HelloWebService is down (not deployed on the server for example), the JUnit framework catches the remote exception and generates an error with a complete stack trace for the exception—which is useful for debugging—as shown in the Figure 12.
    Figure 12. Web service down error
    Web service down error

    Note that in this case, the error emphasizes an unanticipated problem, which indicated that an uncaught exception (remote exception) occurred.

  • Another approach is to catch the RemoteException, as shown in Listing 7.
    Listing 7. Web service unit testing
    public void testGetGreeting() 
    {
       String greeting = null;
       try {
         greeting = helloPortTypeProxy.getGreeting("Rosa");
         assertEquals("Hello! Rosa", greeting);
       } catch (RemoteException e) {
         fail("Remote Exception Occurred...");
       }
    }

In Listing 7, the RemoteException call is anticipated, and the use of fail() doesn't generate a complete stack trace including the method that raised the exception; but it does generate the enclosed message.

If HelloWebService is down, fail() is executed and failure occurs, as shown in Figure 13.

Figure 13. Web service down
Web service down

Note that failure emphasizes that an anticipated problem occurred.

Servlet unit testing

This section explores HelloWorld servlet unit testing. You use the Cactus testing framework, which extends the JUnit testing framework to execute in-container testing.

Create a servlet under test

The following steps walk you through creating a simple servlet and testing it.

  1. Import HelloWorld.zip (available in the Download section) as a project interchange. Or create a dynamic Web project named HelloWorld, and create a servlet named HelloWorldServlet.
  2. Paste the code from Listing 8 into HelloWorldServlet, which:
    • Takes a name from the request parameter.
    • Sets a greeting to the session.
    • Writes the greeting to the response.
    Listing 8. HelloWorldServlet
    package com.ibm.tdc;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class HelloWorldServlet extends HttpServlet
    {
       public void doGet(HttpServletRequest request, HttpServletResponse response)
       throws IOException
       {
          PrintWriter pw = response.getWriter();
          response.setContentType("text/html");
          getGreeting(request);
          pw.print("<html><head/><body><h1>" + 
          request.getSession().getAttribute("greeting") + "</h1></body></html>");
       }
    
       public String getGreeting(HttpServletRequest request)
       {
          String name = request.getParameter("name");
          request.getSession().setAttribute("greeting", "Hello "+name+"!");
          return name;
       }
    }

If you tested this servlet on the browser by writing http://localhost:9080/HelloWorld/HelloWorldServlet?name=rosa, the result should look like Figure 14.

Figure 14. Running the servlet
Running the servlet

Create a servlet test

Follow these steps to create the HelloWorldServletTest class, which extends the Cactus ServletTestCase class and lets you test HelloWorldServlet.

  1. Perform the steps mentioned in the Cactus testing preparation section.
  2. Switch to the Java perspective.
  3. Right-click HelloWorldServlet.java, and select New > Other > Java > JUnit > JUnit Test Case.
  4. In the JUnit Test Case dialog box, choose org.apache.cactus.ServletTestCase as the superclass, then click Next.
  5. Choose the getGreeting method, and click Finish, as shown in Figure 15.
    Figure 15. Selecting the method to be tested
    Selecting the method to be tested
  6. Set the request name parameter from the client side using beginGetGreeting, as shown in Listing 9.
    Listing 9. beginGetGreeting
    public void beginGetGreeting(WebRequest webRequest)
    {
       webRequest.addParameter("name", "Rose");
    }

    Note that the following actions occur:
    • beginXXX() is executed on the client side before testXXX() on the server side.
    • endXXX() is executed at the end of a test at the client side.
    • setUp() and tearDown() are executed on the server side before and after testXXX(), respectively.
    • WebRequest contains HTTP request data for a Cactus test case.
  7. Add the code shown in Listing 10 to the body of testGetGreeting.
    Listing 10. testGetGreeting
    HelloWorldServlet helloWorldServlet=new HelloWorldServlet();
    helloWorldServlet.getGreeting(request);
    assertEquals("Hello Rose!",session.getAttribute("greeting"));

    The code in Listing 10:
    • Constructs a new object of HelloWorldServlet.
    • Calls getGreeting() and passes request to it, which is one of the implicit objects initialized automatically by Cactus. request is of the type org.apache.cactus.server.HttpServletRequestWrapper, which it inherits from javax.servlet.http.HttpServletRequest. Hence, it can be passed to the servlet method that takes a variable of type HttpServletRequest.
    • Checks the equality of the expected value and the value stored in the session attribute.

The overall code should look like what's shown in Listing 11.

Listing 11. HelloWorldServletTest
package com.ibm.tdc;
import org.apache.cactus.ServletTestCase;
import org.apache.cactus.WebRequest;
public class HelloWorldServletTest extends ServletTestCase 
{	
   public void beginGetGreeting(WebRequest webRequest)
   {
      webRequest.addParameter("name", "Rose");
   }
   
   public void testGetGreeting() 
   {
      HelloWorldServlet helloWorldServlet=new HelloWorldServlet();
      helloWorldServlet.getGreeting(request);
      assertEquals("Hello Rose!",session.getAttribute("greeting"));
   }
}

Run the servlet test

The following steps show how to run the HelloWorldServletTest class.

  1. Right-click the HelloWorldServletTest test class, and select Run > Run.
  2. Select JUnit in the Configurations list, and click New.
  3. Click the Arguments tab in the right pane.
  4. Set the Cactus context URL in the VM arguments field to -Dcactus.contextURL=http://localhost:9080/HelloWorld, as shown in Figure 16. Note that HelloWorld is the project name. cactus.contextURL represents the application context under which the test application runs.
    Figure 16. Cactus configuration
    Cactus configuration
  5. Click Run. The test should pass, and you'll see a green bar like the one shown in Figure 7, which indicates a successful test.

EJB unit testing

This section explains how to create a HelloWorld stateless session EJB bean and how to perform unit testing using the Cactus testing framework.

Create an EJB under test

Follow these steps to create a HelloWorld stateless session EJB bean:

  1. To create the stateless session EJB bean to be tested, import HelloEJB.zip (available in the Download section) as a project interchange. Or select File > New > Project > EJB > EJB project, enter HelloEJB as the name of the project, then click Finish.
  2. Right-click HelloEJB, select New > Other > EJB > Enterprise Bean, then click Next.
  3. Enter the values shown in Figure 17, where you select Session bean as the EJB type and define the basic properties of the bean. Then click Next.
    Figure 17. Creating a new EJB bean
    Creating a new EJB bean
  4. From the Session type drop-down list, choose Stateless, as shown in Figure 18, then click Finish.
    Figure 18. Filling in EJB details
    Filling in EJB details
  5. Paste the code from Listing 12 in HelloBean.
    Listing 12. EJB method implementation
    public String getGreeting(String name)
    {
       System.out.println("stateless session bean ...");
       return "Hello! "+name;
    }
  6. Promote the getGreeting() method to the remote interface, as shown in Figure 19.
    Figure 19. Promote to the remote interface
    Promote to the remote interface
    Promoting the getGreeting() method to the remote interface (Hello) generates the line of code shown in Listing 13 in the Hello remote interface.
    Listing 13. The remote interface generated code
    public String getGreeting(String name) throws java.rmi.RemoteException;

    The remote client calls this remote method.

Create an EJB test

The testing of HelloEJB occurs in the HelloWorld dynamic Web project that you previously created in the Servlet unit testing section.

  1. Open the deployment descriptor of HelloWorldEAR.
  2. Go to the Module tab, and add HelloEJBClient.jar to the Project Utility Jars list, as shown Figure 20.
    Figure 20. Project Utility JARs
    Project Utility JARs
  3. Right-click the project HelloWorld, and select Properties > Java JAR Dependencies.
  4. Select HelloEJBClient.jar in the right-hand list, then click OK. Figure 21 shows what the JAR dependencies look like.
    Figure 21. JAR dependencies
    JAR dependencies
  5. Perform the steps mentioned in the Cactus testing preparation section on the HelloWorld Web project if you haven't already (see Create a servlet test).
  6. Create a JUnit test case named HelloEJBTest for HelloEJB, and insert the code from Listing 14 in HelloEJBTest.
    Listing 14. HelloEJBTest
    package com.ibm.tdc;
    import java.util.Hashtable;
    import java.rmi.RemoteException;
    import javax.ejb.CreateException;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    import javax.rmi.PortableRemoteObject;
    import org.apache.cactus.ServletTestCase;
    
    public class HelloEJBTest extends ServletTestCase 
    {	
       public void testGetGreeting() 
         throws NamingException, RemoteException, CreateException
       {
          Hashtable env = new Hashtable();
          Object obj = null;
          Context ctx = null;
          String strUrl = "iiop://localhost:2809"; 
          env.put(Context.PROVIDER_URL, strUrl);	
    	  
          ctx = new InitialContext(env);
          obj = ctx.lookup("ejb/com/ibm/tdc/HelloHome");
          HelloHome bfmh = (HelloHome) PortableRemoteObject.narrow(obj, 
            HelloHome.class);
          Hello defaultSession = bfmh.create();;
          assertEquals("Hello! Rosa", defaultSession.getGreeting("Rosa"));
       }
    }

Run an EJB under test

Refer to the Run the servlet test section to run HelloEJBTest.


Component testing

Component testing tests the integration of basic units of code to perform certain functionality before they are integrated into the production code base. This section walks you through using the component testing feature in WebSphere Integration Developer, Rational Software Architect, and Rational Application Developer to perform automated component testing on Java code and Web services. The automated component testing features extend the JUnit framework.

There are a few requirements: You need to install Rational Agent Controller before running a component test. And to test Java code and Web service components, you must first create a component test project (in either WebSphere Integration Developer, Rational Software Architect, or Rational Application Developer), which represents a container for test components (see Figure 22).

Figure 22. Component testing
Component testing

Create a component test project

Perform the following steps to create a component test project in which you group the test artifacts generated when you create a component test:

  1. Import CompTest.zip (available in the Download section) as a project interchange. Or create a component test project by selecting File > New > Project > Component Test > Component Test Project, then click Next, as shown in Figure 23.
    Figure 23. Web service component test
    Web service component test
  2. Name the component test project CompTest, and click Next.
  3. Define the component test project scope (the projects to be tested inside this component test project) by selecting the HelloWebService and HelloWorldJava projects, as shown in Figure 24.
    Figure 24. Test scope
    Test scope
  4. Click Finish.

Java component testing

Component testing is the ability to test the integration of basic units of code that have undergone the unit testing to perform a specific functionality before they are integrated into the production code base. Suppose that the HelloWorldJava project, which you created in the Java unit testing section, has another class called GoodMorning. This class has one method, sayGoodMorning(), that takes a string in the format Hello! name, parses it to retrieve the name, and returns Good Morning name. This class has passed through unit testing as the HelloWorld class. Now you want to integrate the two classes to form a certain scenario that takes name and returns Good Morning name. Here's how:

  1. Select File > New > Other > Component Test > Java > Java Component Test, then click Next.
  2. Select the CompTest component test project with which the new Java component test will be associated.
  3. When the Select the components under test dialog box appears, select the HelloWorld and GoodMorning classes (the classes to be tested).
  4. Enter HelloFlow for the test name, as shown in Figure 25, then click Next.
    Figure 25. Components under test
    Components under test
  5. To create a test based on a sequence of method calls, select Scenario-based testing, then click Next.
  6. To start testing, you must first instantiate a new object from the class using the constructor; then any sequence of methods can be called on this object. The Define a test scenario dialog box (see Figure 26) simulates exactly this sequence of steps where you do the following:
    1. To create an object of the HelloWorld class, select HelloWorld() from the Constructors list, then click Add.
    2. To add any sequence of method calls, select and add each method from the Testable Methods list in any desired sequence. In this case, select getGreeting(String), and click Add.
    3. Select GoodMorning() from the Constructors list, and click Add.
    4. Select sayGoodMorning(String), and click Add.
    5. Click Finish.
    Figure 26. Scenario-based testing
    Scenario-based testing
  7. Click the Test Overview tab, and click HelloFlow.java next to Behavior (see Figure 27) to view and start editing the test code.
    Figure 27. Test overview
    Test overview
  8. Modify the code to implement the desired tests, and click the test method testClassCluster() in the Java editor to show the Test Data Table.
  9. Fill this table with the input data and the expected output shown in Figure 28, then click Save.
    Figure 28. Java component test
    Java component test
  10. From the Test Navigator, expand the CompTest component test project.
  11. Right-click the HelloFlow test suite, and select Run > Component Test, as shown in Figure 29.
    Figure 29. Running component test
    Running component test
  12. Observe the Actual column versus Expected column in the Test Data Comparator view. Figure 30 shows that the test passed successfully and that the actual and expected results match. (This is indicated by the green color of the results in the Actual column; if there's a mismatch between the actual and the expected results, the results appear red in the Actual column).
    Figure 30. Java test results
    Java test results

Web services component testing

This section discusses Web services component testing by testing the HelloWebService. To create a Web service component test inside the CompTest you created previously (in the Create a component test project section), do the following:

  1. Select File > New > Other > Component Test > Web Services > Web Service Component Test, then click Next.
  2. Select the CompTest component test project with which the new Web service component test will be associated, then click Next.
  3. In the Select the Web service under test dialog box, browse to HelloService.wsdl, then choose the port type to be tested, as shown in Figure 31. This dialog box is responsible for generating the proxy classes from the selected WSDL file.
    Figure 31. Web service under test
    Web service under test
  4. In the Select a test pattern dialog box, select Operation-level Web Service Testing to create a test for each individual operation in the class to be tested. Then click Next (see Figure 32).
    Figure 32. Selecting a test pattern
    Selecting a test pattern
  5. Select the getGreeting(String) method (the method to be tested), then click Finish, as shown in Figure 33.
    Figure 33. Selecting a Web service method
    Selecting a Web service method
    In the Web perspective, client classes are generated, as shown in Figure 34.
    Figure 34. Proxy classes
    Proxy classes
  6. Switch to the Test perspective, and fill the Test Data Table.
    Figure 35. WS component test
    WS component Test
    Note that webServiceUrlString (in the In column) is set to be http://localhost:9080/HelloWebService/services/HelloPort, which is the value specified in the HelloService WSDL file inside the <soap:address> tag.
  7. Right-click the project, and select Run > Test Component.

<soap:address>

The <soap:address> tag content is the Web service endpoint that represents the network physical address on which the Web service is deployed and running. (See Resources for more information about soap:address.)

  1. Observe the Actual versus Expected column in the Test Data Comparator view. Figure 36 shows that the test passed successfully and that the actual and the expected results match. (This is indicated by the green color of the results in the Actual column; if there's a mismatch between the actual and the expected results, the results appear red in the Actual column).
    Figure 36. Web service test results
    Web service test results

Service Component Architecture testing

SCA is a new programming model designed specifically for building and assembling business solutions in a Service-Oriented Architecture (SOA) and for integrating and composing services. (For more information, refer to "Building SOA solutions with the Service Component Architecture" [developerWorks, Oct 2005].)

You perform SCA component testing using a ServletTestCase. This test case uses the Cactus framework to externally invoke the SCA component using a stand-alone reference. In this section, you create a HelloWorldModule module with SCA components that are connected to a stand-alone reference. Then you create a dynamic Web project called HelloWorldModuleTest that tests the SCA components.

Create an SCA module

Perform the following steps to create and test the SCA module:

  1. Import HelloWorldModule.zip (available in the Download section) as a project interchange. Or create a module by clicking File > New > Project > Module. Then click Next.
  2. Enter HelloWorldModule as the project name.
  3. In the Business Integration perspective, navigate to and right-click HelloWorldModule > Interfaces.
  4. Select New > Interface, and name the interface HelloInterface.
  5. When the Interface Editor opens, add the getGreeting operation that takes name as input and greeting as output, as shown in Figure 37.
    Figure 37. HelloInterface
    HelloInterface
  6. Open the Assembly Editor.
  7. Drag and drop Java SCA component, name it HelloJava, and add HelloInterface to it as a component interface.
  8. Drag and drop Process SCA component, name it HelloProcess, and add HelloInterface to it as a component interface and reference.
  9. Wire HelloProcess to HelloJava.
  10. Double-click HelloJava (this implements it), and add the following line in the getGreeting() operation: return "Hello! "+name;.
  11. Implement HelloProcess, as shown in Figure 38.
    Figure 38. HelloProcess
    HelloProcess

    As you can see in Figure 38, Invoke is used to invoke HelloJava, and Snippet is used to change the value of the greeting.

  12. Drag and drop Stand-alone References, and wire the Stand-alone References to HelloJava and HelloJavaProcess, as shown in Figure 39.
    Figure 39. HelloWorldModule
    HelloWorldModule
    The partner reference names shown in Figure 39 are the entry points to the SCA components. These names are used to call the SCA components during testing.

Create an SCA test

The following steps walk you through creating a dynamic Web project, HelloWorldModuleTest, that tests HelloWorldModule:

  1. Switch to the J2EE perspective, and expand Enterprise Applications in the Project Explorer view.
  2. Right-click HelloWorldModuleApp, and select New > Dynamic Web Project.
  3. In the New Dynamic Web Project dialog box, enter a name, such as HelloWorldModuleTest, which is the project you use to test HelloWorldModuleApp.
  4. Click Finish.
  5. Perform the steps covered in the Cactus testing preparation section for the HelloWorldModuleTest project.
  6. HelloWorldModuleTest—which is dependent on HelloWorldModule—must be added to HelloWorldModule. To do this, switch to the Business Integration perspective, select HelloWorldModule, and right-click to open the Dependency Editor.
  7. Expand J2EE, and click Add to add the HelloWorldModuleTest dynamic Web project to the SCA module, as shown in Figure 40.
    Figure 40. Dependency Editor
    Dependency Editor
  8. Switch to the Web perspective, go to the Project Explorer view, and expand HelloWorldModule > Java Resources > JavaSource.
  9. Create a new class named HelloWorldTest inside the package com.ibm.tdc, and paste the code from Listing 15 in it.
    Listing 15. HelloWorldTest
    package com.ibm.tdc;
    import org.apache.cactus.ServletTestCase;
    import com.ibm.websphere.sca.Service;
    import com.ibm.websphere.sca.ServiceManager;
    public class HelloWorldTest extends ServletTestCase 
    {
    public void testHelloJava() 
    {	
    Service service=(Service)ServiceManager.INSTANCE.locateService
      ("HelloInterfacePartner");
    String greeting = (String)service.invoke("getGreeting", "Rosa");
    assertEquals("Hello From First Java Component! Rosa", greeting);
    }
    
    public void testHelloProcess() 
    {	
    Service service=(Service)ServiceManager.INSTANCE.locateService
      ("HelloInterfacePartner1");
    String greeting = (String)service.invoke("getGreeting", "Rosa");
    assertEquals("Hello From Process! Rosa", greeting);
    }
    }

    The previous code tests both the HelloJava and HelloProcess SCA components using the testHelloJava() and testHelloProcess() methods, respectively. Each method uses the service manager to access the SCA component through the partner reference name, invokes the getGreeting() operation, then validates the result through assertion.

Run SCA module under test

Refer to the Run the servlet test section to run HelloWorldTest.


Test automation using Ant scripts

Ant is a Java-based tool used for build automation; in this case Ant is used to automate JUnit and Cactus test cases, and generate the test results in XML files (see Resources for a link to more information about Ant).

JUnit Ant script

The following steps show how to use the JUnit Ant task to run the HelloWorldTest (created earlier). This lets you perform the unit test for the HelloWorld Java class, as explained in the Java unit testing section.

  1. Create an XML file named build.xml, and place it in the Java project.
  2. Paste the code from Listing 16 in the build.xml file.
    Listing 16. JUnit Ant script
    <?xml version="1.0" encoding="UTF-8"?>
    <project name="Workspace" default="junitTest">
     <target name="junitTest">
      <junit printsummary="yes" haltonfailure="no">
       <classpath>
        <pathelement location="bin" />
       </classpath>
       <formatter type="xml"/>
       <batchtest todir="C:/temp/">
        <fileset dir="C:/Workspace/HelloWorldJava">
         <include name="**/*Test*.java" />
        </fileset>
       </batchtest>
      </junit>
     </target>
    </project>

Ant and build automation

Ant can automate your build procedure to improve productivity and quality using the built-in support of Ant for the IBM Rational Software Development platform. For more information, refer to "Automatically generate project builds using Ant" (developerWorks, Jan 2007).

In Listing 16, note that:

  • <pathelement location="bin"/> refers to the place of the .class files (the classes under test and the test cases).
  • <junit printsummary="yes" haltonfailure="no"> runs the JUnit test cases and prints a summary.
  • <formatter type="xml"/> sets the test results format.
  • <batchtest todir="C:/temp/"> specifies the location of the generated test results reports.
  • <fileset dir="C:/Workspace/HelloWoldJava"> refers to the location of the Java project.
  • <include name="**/*Test*.java"> refers to test case with the word Test in it under any package. Note that **/*Test*.java can be replaced by com/ibm/tdc/HelloWorldTest.java.
  1. To run Ant, drag and drop the build.xml file in the Ant view.
  2. Right-click junitTest, and select Run Ant, as shown in Figure 41.
    Figure 41. Run Ant
    Run Ant
  3. Select the JRE tab, and choose Run in the same JRE as the workspace (this is the JRE in which Ant will run), as shown in Figure 42.
  4. Click Run.
    Figure 42. JRE selection
    JRE selection

The test results appear in the Console, and the test reports are generated at the location you specified earlier.

Cactus Ant script

Follow these steps to use the Cactus Ant task to run HelloWorldServletTest (created earlier) to perform the unit test for the HelloWorldServlet servlet, as covered in the Servlet unit testing section.

  1. Add cactus-ant-1.7.2.jar and cargo-0.5.jar under WebContent\WEB-INF\lib to run the Cactus Ant task. (You can download these .jar files from the Download section of this article or from apache.org.)
  2. Right-click HelloWorldEAR, select Export > EAR file, and choose C:/temp/test/HelloWorldEAR.ear as the destination.
  3. Create an XML file named build.xml, and place it in the HelloWorld dynamic Web project.
  4. Paste the code from Listing 17 in the build.xml file.
    Listing 17. Cactus Ant script
    <?xml version="1.0" encoding="UTF-8"?>
    <project name="Workspace" default="cactusTest">
     <property name="server.lib" value="C:/WebSphere/ID/602/runtimes/bi_v6/lib"/>
     <property name="project.lib" value="WebContent/WEB-INF/lib"/>
     <path id="test.classpath">
      <fileset dir="${server.lib}">
       <include name="j2ee.jar" />
      </fileset>
     <pathelement location="WebContent/WEB-INF/classes" />
     </path>
     <path id="cactus.classpath">
      <pathelement location="${project.lib}/cactus-1.7.2.jar"/>
      <pathelement location="${project.lib}/cargo-0.5.jar"/>
      <pathelement location="${project.lib}/cactus-ant-1.7.2.jar"/>
      <pathelement location="${project.lib}/commons-httpclient-2.0.2.jar"/>
      <pathelement location="${project.lib}/commons-logging-1.0.4.jar"/>
      <pathelement location="${project.lib}/aspectjrt-1.2.1.jar"/>
     </path>
     <target name="cactusTest">
      <taskdef resource="cactus.tasks" classpathref="cactus.classpath"/>
       <cactus printsummary="yes" haltonfailure="no" 
          earfile="C:/temp/test/HelloWorldEAR.ear">
        <classpath refid="test.classpath" />
        <formatter type="xml"/>
        <batchtest todir="C:/temp/">
         <fileset dir="C:/Workspace/HelloWorld/JavaSource">
          <include name="com/ibm/tdc/HelloWorldServletTest.java" />
         </fileset>
        </batchtest>
       </cactus>
     </target>
    </project>

In Listing 17, note that:

  • <property name="server.lib" value="..."/> refers to the place of the server library.
  • <path id="test.classpath"> refers to the j2ee.jar file.
  • <path id="cactus.classpath"> refers to the Cactus .jar files.
  • <taskdef resource="cactus.tasks" classpathref="cactus.classpath"/> defines the Cactus task and refers to the Cactus .jar files.
  • <cactus ... earfile="C:/temp/test/HelloWorldEAR.ear"> refers to the dynamic Web project EAR file that was exported above in step 2.
  1. Drag and drop build.xml in the Ant view, then right-click cactusTest > Run Ant.
  2. Select the JRE tab, and choose Separate JRE.
  3. Select the server on which your dynamic Web project is running. For example, if you're using WebSphere Process Server, choose WPS Server v6.0 JRE. (Note that the WebSphere Process Server test environment is available with WebSphere Integration Developer.)
  4. Set the VM arguments to -Dcactus.contextURL=http://localhost:9080/HelloWorld, as shown in Figure 43.
    Figure 43. Separate JRE
    Separate JRE
  5. You need to add junit.jar, because it's needed by the Cactus Ant task. Select the Classpath tab, and click User Entries.
  6. Click Add JARs, browse to HelloWorld\WebContent\WEB-INF\lib\junit.jar, and click OK. junit.jar is added to the User Entries list, as shown in Figure 44.
    Figure 44. Adding junit.jar to User Entries
    Adding junit.jar to User Entries
  7. Click Run. The test report appears in the destination specified in the Ant script.

Conclusion

In this tutorial, you learned how to perform unit and component testing using the JUnit and Cactus frameworks. You also walked through the automation of tests with Ant scripts using IBM Rational tools.


Acknowledgements

The author would like to thank Ahmed Abbas, Dr. Alaa Youssef, and Mahmoud Ouda for reviewing the tutorial and for their valuable suggestions.


Download

DescriptionNameSize
Test files for this tutorialsample.zip2.7MB

Resources

Learn

Get products and technologies

  • Download a free trial version of Rational Software Architect. Note: IBM Rational Agent Controller is included in the for-purchase version, not in the trial version.
  • Innovate your next development project with IBM trial software, available for download or on DVD.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into SOA and web services on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and web services, Rational, Open source, DevOps
ArticleID=261251
ArticleTitle=Get started with unit and component testing using IBM Rational tools
publish-date=10112007