devxlogo

jDefend: One Configuration File for All Your Test Scenarios

jDefend: One Configuration File for All Your Test Scenarios

very developer, at some point, has implemented a test driver to test his or her code. The alternative is writing a custom test driver for each test scenario. The custom driver would have to read the input data, parse it, turn it into objects, and then use those objects for each test scenario. How would you like to have a test driver that you don’t need to recompile every time input parameters change?

With the open source jDefend test driver suite, you can configure all the input parameters and pass them to your test driver using a single XML-based configuration file. jDefend’s parser class parses the configuration file and prepares all the test drivers listed for execution. It then executes each test driver?even on a different thread?for faster execution of the test scenarios. (Figure 1 shows the various components of the jDefend suite.)

Figure 1. jDefend Components: The jDefend suite is made up of various components.

In this article, I’ll demonstrate how the jDefend test suite can make your Java code testing quicker and simpler, and I’ll discuss how it also can simplify security testing.

jDefend in Action
To better understand jDefend’s functionality, follow the test procedure for a simple class. Begin with a Java object called Student.

Listing 1: Student.java
package example;public class Student{ private String name; private Address addr; public void setName(String n) { System.out.println(“setName called”); name = n; } public String getName() { return name; } public void addressIs(Address a) { addr = a; }}

Next, load a class called StudentManager, which has three operations: add, remove, and find Student.

Listing 2: StudentManager.java
package example;import java.util.Vector;public class StudentManager{ Vector students = new Vector(); public void add(Student s) { System.out.println(“Entering StudentManager::add(Student s) “); students.add(s); } public void remove(Student s) { System.out.println(“Entering StudentManager::remove(Student s) “); students.remove(s); } public Student findStudent(String name) { System.out.println(“Entering StudentManager::findStudent(String name) “); Student stud = null; for(int i=0; i

Test the StudentManager Class with jDefend
To test the functionality of the StudentManager class, you ordinarily would take one of the following three approaches:

  • Hard code the test data inside your test driver. That is, create the Student object by hard coding all the data fields.
  • Write a test driver class that accepts command line parameters.
  • Read the data from a file.

    Not only do all these approaches require a good bit of coding, they also are inflexible. If you added a new attribute to the Student class, you’d have to re-code and re-compile the test driver to accommodate the new change.

    To see how jDefend offers a better solution for this situation, add a new attribute called Address (see Listing 3: Address.java below) to the Student class. Address is another java class, which has the address details of the Student object.

    Listing 3: Address.java
    package example;public class Address{ String street; String state; String city; String zip; public void setStreet(String val) { street = val; } public void setState(String val) { state = val; } public void setCity(String val) { city = val; } public void setZip(String val) { zip = val; }}

    With jDefend, you need to change only the XML-formatted configuration file to accommodate this new class. You set all your input values, method participation attributes, etc. in this one file.

    Implement a test driver class called StdMgrTestDriver to test the StudentManager class. To write your test driver class, just extend it from the jDefend.TestDriver.

    StdMgrTestDriver.java
    package example;import testSuite.*;public class StdMgrTestDriver extends TestDriver{ StudentManager mgr = new StudentManager(); public boolean testAdd(Student s) { mgr.add(s); return true; } public boolean testRemove(Student s) { mgr.remove(s); return true; } public boolean testFindStudent(String name) { Student std = mgr.findStudent(name); if (std == null) { return false; } return true; }}
  • The XML Config File
    Your configuration file should now look like TestDriver.xml. The following are all the possible configuration parameters you can set for your own test scenarios:

  • TestDrivers

    Within the context of , you can have as many TestDriver classes as you want using the tag.
  • TestDriver
    testAdd” Method_Id=”ADD” Participate=”YES” Return_Type=”boolean“>
    For a description of the Method attributes, see the Method Attribute Descriptions table.

    Method Attribute Descriptions

    NameName of the method in the TestDriver
    E.g., testAdd, testFindStudent, etc.
    Method_IdUnique identifier within the scope of
    E.g., ADD, FIND
    ParticipateIf set to YES, the method participates in the test run.
    By default, all methods participate.
    E.g., YES/NO
    Return_TypeThe return type of the method.
    By default, this value is “void.”
    OrderOrder in which the methods should be executed.
    This will be used when the Method_Dependency flag is set to Yes.
    Number_Of_ThreadsIf you want your method to be run on more than one thread, set the number_of_threads.
    E.g., 1, 2, etc.
    Is_ParentSetting this value to YES makes the method run as a top-level method. You can set up a dependency order between various methods; for example, you can say Method2 should be executed after Method1. In this case, Method1 will be a parent method and Method2 will not.
    By default this value is NO and hence you must set this value to YES if you want the method to participate in the test run (even when there are no dependencies).
    Next_Method_IdReferring to the Is_Parent description above, the Next_Method_Id value for Method1 will be the Method_Id value of Method2. This tells jDefend that Method2 has to be executed after it executes Method1.

  • Arguments

    Within the context of , you can list all the arguments that a Method accepts using the tag.
  • Argument
    A simple argument (testFindStudent scenario) looks like this:
    1” Type=”example.Student” VALUE=”CustomType” Id=”StudentX” />
    For a description of the Argument attributes, see the Argument Attribute Descriptions table.

    Argument Attribute Descriptions

    NumIndicates the argument order.
    If Num is 1, the method accepts the argument type as the first argument.
    E.g., 1, 2, etc.
    TypeIndicates the type of argument.
    This attribute supports all simple data types. For complex data types, this would be a fully qualified class name such as java.util.Vector.
    E.g., String, int, java.util.Vector, Student
    ValueIndicates the value to be passed.
    E.g., DolphinNose, for the method testFindStudent.
    If the Type is a user-defined type or complex data type, Value should be set to CustomType.
    IdA unique Id for the given Argument.
    This is required only for CustomTypes.

  •  

    Custom Arguments
    Custom arguments are used to describe custom objects. Custom argument tags take place within the scope of . The custom arguments can be nested to any number of levels. As an example, our StudentManager has a method add that takes a Student object, which is itself a custom object. So to describe the Student object, you will have to write the following XML format:

    	

    You should replace “Id” with the actual Id defined as part of the tag attributes. Remember the tag for the testAdd method:

    name” Type=”String” Value=”Subbu” />  

    However, the Address object also has another custom object, Address, as an instance variable. Also, the method to be invoked to set this address object value does not follow the standard “set” convention. That is, you don’t have a standard setAddress method; you have addressIs(Address a) instead. You can handle this situation using your XML tags.

    street” Type=”String” Value=”1 Adams Ave” /> Author Note: jDefend is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 

    This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    Copyright (C) 2001 Subbu Vedula

    devxblackblue

    About Our Editorial Process

    At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

    See our full editorial policy.

    About Our Journalist