Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Tools of the trade, Part 2

Jtest statically and dynamically analyzes your Java code

  • Print
  • Feedback

Page 7 of 7

Listing 2: Employee.java

// Employee.java
class Employee
{
   private String name;
   private double salary;
   Employee (String name, double salary)
   {
      setName (name);
      setSalary (salary);
   }
   public void setName (String name)
   {
      this.name = name;
   }
   /**
    * @pre salary > 0.0
    */
   public void setSalary (double salary)
   {
      this.salary = salary;
   }
}


Employee's source code presents a single precondition in the form of a Javadoc comment that immediately precedes the public void setSalary(double salary) method. Compile that source code and perform a dynamic analysis. Jtest will try to create a test case that violates setSalary(double salary)'s salary > 0.0 precondition. However, Jtest will not create a test case that directly calls setSalary(double salary) with a salary value less than 0.0, because that method states via its precondition that it must not be called with an argument value less than 0.0. But Jtest can still try to indirectly call setSalary(double salary) from another method not prefixed with the same precondition. That other method is the Employee(String name, double salary) constructor, and the results appear in Figure 6.

Figure 6. The Class Testing UI's Errors Found panel reveals a single @pre violation. Click on thumbnail for full-size image.

Jtest creates the Employee THIS = new Employee (null, 0.0); test case to violate the precondition. If you place a second copy of the precondition's Javadoc comment ahead of the Employee (String name, double salary) constructor, Jtest will not create that test case and will not report an @pre violation. The reason Jtest will not create that test case is because you document in source code the acceptable argument values for setSalary(double salary), and (after adding the precondition's second copy) that the constructor cannot call that method with a salary value less than 0.0. Because you can see these precondition Javadoc comments in source code, you are less likely to introduce a defect through code modifications, that is, a salary less than 0.0—and that is what black-box testing with DBC is all about.

Caution
When using DBC with a method, do not place the DBC Javadoc comment(s) inside the method body. Otherwise, Jtest will not black-box test the method.


Regression testing tests modified code with the same set of inputs and test parameters that previous tests used. The idea is to ensure that modifications fix previously detected errors and do not introduce their own errors.

Jtest automatically performs regression testing on a class or project after the first test session with that class or project. Listing 3 illustrates regression testing; it isn't much to look at, but proves useful for demonstration purposes:

Listing 3: RegressionTest.java

// RegressionTest.java
class RegressionTest
{
   public static void main (String [] args)
   {
      System.out.println (Math.sqrt (value ()));
   }
   static double value ()
   {
      return 4.0;
   }
}


Complete the following steps to regression test RegressionTest:

  1. Compile Listing 3's RegressionTest source code.
  2. Click the toolbar's New icon to start a new test session.
  3. Use the Browse button on the Class Testing UI's Class Name panel to locate and highlight RegressionTest.class.
  4. Right-click the Start icon and select the Dynamic Analysis menu item to start a new dynamic analysis. Jtest prompts you to save class test parameters, which you should do because Jtest needs them for future regression tests.
  5. Once the dynamic analysis completes, change 4.0 to -4.0 in RegressionTest.java and recompile.
  6. Right-click the Start icon and select the Dynamic Analysis menu item to start a second dynamic analysis. (If you perform tests on other classes or projects before RegressionTest's second dynamic analysis, load previously saved RegressionTest class test parameters from the appropriate .ctp file before starting the second dynamic analysis.)


Figure 7 reveals, on the Class Testing UI's Errors Found panel, a single regression error and the test case that reveals that error.

Figure 7. The Class Testing UI's Errors Found panel reveals a regression error. Click on thumbnail to view full-size image.

The regression error involves the 4.0 change to -4.0. That change results in a negative argument passed to the square root method. Because the square root method does not throw an exception (which white-box testing would automatically detect and report), when passed a negative argument, regression testing helps you catch this subtle defect.

Customize Jtest

Jtest provides many customization features that enhance your experience with this testing tool. We'll look at two categories of Jtest's customization features: the Preferences menu and global test parameters:

  • Preferences menu: The Class and Project Testing UIs each display a Preferences menu that establishes your Jtest configuration and user interface preferences. The Preferences menu contains two menu items: Configuration Options and UI Preferences. Use Configuration Options to establish a third-party editor (unless you prefer Jtest's built-in editor), whether you want information on all accessed classes and test cases included in a report, and the report format (HTML or ASCII). Use UI Preferences to establish the starting UI, look and feel, the title bars' background colors on various panels, the notion of working (a visual indication in the status bar that Jtest is performing its tests), and font type/size information used to display context-sensitive help.
  • Global test parameters: Jtest lets you customize global test parameters, configurable test settings common to classes and projects. Examples include whether dynamic analysis occurs during each test session and various directory locations. Both the Class and Project Testing UIs inherit some of these test parameters and add additional test parameters to achieve either class test parameters or project test parameters. You can localize your changes to a specific class by changing class test parameters, localize your changes to a specific project by changing project test parameters, or establish default settings that apply to all classes and projects by changing global test parameters.

    Jtest supplies appropriate windows for changing class, project, and global test parameters. For example, the Global Test Parameters window, which you access by clicking the Global icon on either testing UI's toolbar, lets you establish default settings that apply to all classes and projects. Figure 8 illustrates the Global Test Parameters window.

    Figure 8. The Global Test Parameters window lets you customize test parameters that apply to both class and project testing. Click on thumbnail to view full-size image.

    Tip
    Some test parameters in either the Class Test Parameters or Project Test Parameters windows display inherit beside the test parameter name. That means either the class or project test parameter inherits its setting from an equivalent global test parameter. To override this setting, click the test parameter value until it displays the appropriate override setting (such as a Boolean test parameter's true or false).


Review

Test your Java code to ensure success as a Java developer. Failure to test leads to unhappy customers and a poor reputation. When testing, you want to perform static and dynamic analyses. And when doing dynamic analysis, you'll want to complete white-box testing, black-box testing, and regression testing. You can either manually test your code or use Jtest (or similar testing tools) to automate much of that work.

Jtest presents Class and Project Testing UIs that let you test either single classes or class sets that represent projects. Each testing UI's toolbar presents a Start button that lets you perform static and dynamic analysis tests. Depending on the UI you use, either the Class Testing UI's Errors Found panel or the Project Testing UI's Results panel displays the test results. If Jtest's default configuration does not meet your needs, use its various customization features to personalize Jtest. For example, change global test parameters to fine-tune static/dynamic analysis tests.

For brevity, this article does not discuss various tasks, such as the creation of your own test cases and stubs, and features, such as the DBC language. I suggest you acquire an evaluation copy of Jtest and explore those features on your own. After using Jtest, I think you'll agree that it is one tool you definitely must add to your toolkit.

I encourage you to email me with any questions you might have involving either this or any previous article's material. (Please keep such questions relevant to material discussed in this column's articles.) Your questions and my answers will appear in the relevant study guides.

Next month's exploration of the InstallAnywhere installation tool will conclude this series.

About the author

Jeff Friesen has been involved with computers for the past 20 years. He holds a degree in computer science and has worked with many computer languages. Jeff has also taught introductory Java programming at the college level. In addition to writing for JavaWorld, he has written his own Java book for beginners? Java 2 by Example, Second Edition (Que Publishing, 2001; ISBN: 0789725932)?and helped write Using Java 2 Platform, Special Edition (Que Publishing, 2001; ISBN: 0789724685). Jeff goes by the nickname Java Jeff (or JavaJeff). To see what he's working on, check out his Website at http://www.javajeff.com.

Read more about Tools & Methods in JavaWorld's Tools & Methods section.

  • Print
  • Feedback

Resources