JXPUnit User Guide

Version 1.1.0

 

MS Word Format

April 17, 2002

Author: Sunny Liu

Email: sunnyliu2@yahoo.com

 

1.     Introduction

 

JXPUnit is an Apache ANT like Java Programming Unit Test Tool. It takes unit test instructions XML file (test descriptor) as input, and reports back test result to specified target (Log file, Swing GUI JtextArea, console etc.).

 

Ps; this user guide is not complete yet, if you have any question about JXPUnit, Please drop me an email. Thanks.

Microsoft.NET version (XPUnit.NET) here.

 

Features

·        Test Class with complicated constructor or create an instance from factory Class.

·        Dynamic load class from CLASSPATH you specified in Test Descriptor file, which is not in your system CLASSPATH.

·        Accept complicated custom data type.

·        Integrated with Test Descriptor Editor in one GUI environment.

·        Filter Unit Test Result dynamically.

·        Supports nested custom data type.

·        Supports multiple test cases.

·        Supports Setup and Teardown.

 

2.     How to use JXPUnit

 

Recent version of JXPUnit has been refactored for easier adding new function to it. You can use JXPUnit either in console mode or Swing Gui mode.

 

1.      Console mode’s command

 

User#  java com.sunny.jxp.core.JXPUnit [options]

Or

C:> java com.sunny.jxp.core.JXPUnit [options]

 

 

Use following command for console command line options help

 

User#  java com.sunny.jxp.core.JXPUnit  -help

Or

C:> java com.sunny.jxp.core.JXPUnit –help

 

2.      Swing GUI mode

 

User#  java com.sunny.jxp.gui.JXPGui

Or

C:> java com.sunny.jxp.gui.JXPGui

 

3.      How to use JXPUnit in GUI Mode

It works much like Microsoft Office’s menu and tool bar. It support unlimited undo and redo feature, as well as Cut, Copy and Paste. Here is a screen shot of JXPUnit in GUI mode

 

 

1)      Open Test Descriptor

 

There are a few approachs to open test descriptor.

a)      File menu -> Open Test Suite

b)      Toolbar Open Button.

c)      From file menu’s most recent accessed file list.

d)      Type test descriptor’s full file path or directory name in test descriptor field on tool bar. Then click “GO” button.

 

2) Run Unit Test

1)      Run menu -> Run Test Suite

2)      Toolbar -> Run Button

            3) Filter Output

Format menu-> Result Information

 

      4) Create New Test Descriptor

                  1)  File menu ->New Test Suite

2)      Toolbar -> New Button

5) Using Short-cut keys and Edit menus

                 

                  Both Edit menu and Editor pane’s popup menu will help you create test descriptor quickly and easily.

                 

 

                  Popup Menu

                 

 

 

 

 

4.     How to write a test descriptor

 

Test descriptor is a well-formed XML file. It has an only root element <test-suite>. Test-suite can contains multiple test-case element. Each test-case stands for a Java class that you want to be tested.  Please refer section 5 for elements reference. I will write some example here and show how does it works.

 

Example 1,

Target Class:

package com.sunny.jxp.test;

 

public class Testee1

{   

    public void hello()

    {

        System.out.println("Hello World");

    }    

}

 

Test Descriptor:

<?xml version="1.0" encoding="utf-8" ?>

<test-suite>

            <test-case class="com.sunny.jxp.test.Testee1">

                        <test-runner>

                                    <test-method name="hello" />                          

                        </test-runner>

            </test-case>

</test-suite>

 

Result: (report-level 2)

com.sunny.jxp.core.TestInputHandler   Test Descriptor loaded successfully.

   ----------------------------------------- Test Suite ------------------------------------------

Test Case 1   Target ->com.sunny.jxp.test.Testee1

com.sunny.jxp.test.Testee1   function test started.

Method : hello   started

Method : hello   return type  [void]

Method : hello   return value [void]

Method : hello   completed successfully

Mehtod : hello    time ellaps [0] ms

com.sunny.jxp.test.Testee1   tested method count  = 1

com.sunny.jxp.test.Testee1   succeed method count = 1

com.sunny.jxp.test.Testee1   failed method count  = 0

com.sunny.jxp.test.Testee1   time ellapes [10] ms

com.sunny.jxp.test.Testee1   function test ended.

Test Suite   tested testcase count  = 1

Test Suite   succeed testcase count = 1

Test Suite   failed testcase count  = 0

 

Example 2:

// ShyClass.java

package com.sunny.jxp.test;

 

public class ShyClass

{

    private String name = null;

   

    public ShyClass(String name, ShyClassFactory factory) throws Exception

    {

        if ( factory.identify() == false ) throw new Exception("You are not allowed to create me.");

        this.name = name;

    }

   

    public void whatIsYourName()

    {

        System.out.println("My name is " + name);

    }   

   

}

 

// ShyClassFactory.java

package com.sunny.jxp.test;

 

public class ShyClassFactory

{

    private boolean id = false;

   

    private void changeID()

    {

        id = true;

    }

   

    public boolean identify()

    {

        return id;

    }

   

    public ShyClass getShyClass(String name) throws Exception

    {

        ShyClassFactory scf = new ShyClassFactory();

        scf.changeID();

        ShyClass sc = new ShyClass(name, scf);

        return sc;       

    }   

}

 

Test Descriptor:

<?xml version="1.0" encoding="utf-8" ?>

<test-suite>

            <test-case class="com.sunny.jxp.test.ShyClass">

                        <test-constructor source="com.sunny.jxp.test.ShyClassFactory" >

                                    <test-method name="getShyClass" isStatic="true">

                                    <param>

                                    <type>java.lang.String</type>

                                     <value>SHYCLASSNAME</value>

                                    </param>

                                    </test-method>                                                

                        </test-constructor>

                        <test-runner>

                                    <test-method name="whatIsYourName">

                                    </test-method>

                        </test-runner>

            </test-case>

</test-suite>

 

Test Result:

com.sunny.jxp.core.TestInputHandler   Test Descriptor loaded successfully.

   ----------------------------------------- Test Suite ------------------------------------------

Test Case 1   Target ->com.sunny.jxp.test.ShyClass

com.sunny.jxp.test.ShyClass   function test started.

Method : whatIsYourName   started

Method : whatIsYourName   return type  [void]

Method : whatIsYourName   return value [void]

Method : whatIsYourName   completed successfully

Mehtod : whatIsYourName    time ellaps [0] ms

com.sunny.jxp.test.ShyClass   tested method count  = 1

com.sunny.jxp.test.ShyClass   succeed method count = 1

com.sunny.jxp.test.ShyClass   failed method count  = 0

com.sunny.jxp.test.ShyClass   time ellapes [20] ms

com.sunny.jxp.test.ShyClass   function test ended.

Test Suite   tested testcase count  = 1

Test Suite   succeed testcase count = 1

Test Suite   failed testcase count  = 0

 

 

Example 3:

 

//SingletonClass.java

package com.sunny.jxp.test;

 

public class SingletonClass

{

    private static SingletonClass sc = new SingletonClass();

   

    protected SingletonClass()

    {

       

    }

   

    public static SingletonClass newInstance()

    {

        return sc;

    }

   

    public synchronized void testMe(String testString)

    {

        System.out.println("FROM SingletonClass.testMe: " + testString);

    }

}

 

//Testee.java

package com.sunny.jxp.test;

 

import java.io.PrintStream;

 

public class Testee

{

    String name;

    public String displayString = null;

    public int displayInt = 0;   

   

    public Testee()

    {

        name = null;

    }

    public Testee(double d, int i)

    {

        this();

    }

    public Testee(String s)

    {       

        name = null;

        name = s;

    }

    public void display() throws RuntimeException

    {

        if (displayString == null || displayInt == 0 ){

            throw new RuntimeException("Uninitialized Exception.");

        }else{

            System.out.println("displayString = " + displayString);

            System.out.println("displayInt    = " + displayInt);           

        }

    }

 

    public int intAddition(int i, int j)

    {

        return i + j;

    }

 

    public double doubleAddition(double d, int i)

    {

        return (d + i);

    }

   

    public double doubleAdditionWronng(double d, int i)

    {

        return (d + i + 1);

    }

 

    public String concateString(String s, String s1)

    {

        return s + s1;

    }

 

    public void customTypeMethod(MyType mytype)

    {       

        System.out.print("Method with custom type parameter: >> name :");

        System.out.println(mytype.name);

        System.out.print("Method with custom type parameter: >>  age :");

        System.out.println(mytype.age);

    }

 

    public boolean boolMethod(boolean flag)

    {

        return !flag;

    }

}

 

Test Descriptor:

<?xml version="1.0" encoding="utf-8" ?>

<test-suite log="C:/ret.log">     

            <classpath location="c:\target\target.jar"/>

            <test-case class="com.sunny.jxp.test.SingletonClass">     

                        <test-constructor>

                                    <!--<param>

                                                <type>java.lang.String</type>

                                                <value>Hello world</value>

                                    </param>-->

                                    <test-method name="newInstance" isStatic="true" />

                        </test-constructor>                              

                        <test-runner>

                                    <test-method name="testMe">

                                                <param>

                                                            <type>java.lang.String</type>

                                                            <value>Hello world</value>

                                                </param>

                                    </test-method>

                        </test-runner>             

            </test-case>

            <test-case class="com.sunny.jxp.test.Testee">

                        <test-constructor>

                                    <param>

                                                <type>java.lang.String</type>

                                                <value>Hello world</value>

                                    </param>                                

                        </test-constructor>      

                        <test-runner>

                                    <test-method name="intAddition">

                                                <param>

                                                            <type>java.lang.Integer</type>

                                                            <value>10</value>

                                                </param>

                                                <param>

                                                            <type>java.lang.Integer</type>

                                                            <value>13</value>

                                                </param>                                            

                                    </test-method>

                                    <test-method name="concateString">

                                                <param>

                                                            <type>java.lang.String</type>

                                                            <value>String1</value>

                                                </param>

                                                <param>

                                                            <type>java.lang.String</type>

                                                            <value>String2</value>

                                                </param>

                                                <test-return>

                                                <param>

                                                            <type>java.lang.String</type>

                                                            <value>String1String2</value>

                                                </param>

                                                <condition>eq</condition>

                                                </test-return>

                                    </test-method>

                        </test-runner>             

            </test-case>

            <test-case class="com.sunny.jxp.test.Testee">

                       

                        <test-setup>

                                    <public-field name="displayString">

                                                <param>

                                                            <type>java.lang.String</type>

                                                            <value>Display me</value>

                                                </param>                                            

                                    </public-field>

                                    <public-field name="displayInt">

                                                <param>

                                                            <type>java.lang.Integer</type>

                                                            <value>20</value>

                                                </param>                                            

                                    </public-field>

                        </test-setup>

                       

                        <test-runner>

                                    <test-method name="intAddition">

                                                <param>

                                                            <type>java.lang.Integer</type>

                                                            <value>10</value>

                                                </param>

                                                <param>

                                                            <type>java.lang.Integer</type>

                                                            <value>13</value>

                                                </param>                                            

                                    </test-method>

                                    <test-method name="display" />

                        </test-runner>

                        <test-teardown>

                                    <public-field name="displayString" >

                                                <param>

                                                            <type>java.lang.String</type>                                                 

                                                </param>                                            

                                    </public-field>                                     

                                    <public-field name="displayInt">

                                                <param>

                                                            <type>java.lang.Integer</type>

                                                            <value>0</value>

                                                </param>                                            

                                    </public-field>                                     

                        </test-teardown>         

            </test-case>

</test-suite>

 

Test Result:

com.sunny.jxp.core.TestInputHandler   Test Descriptor loaded successfully.

   ----------------------------------------- Test Suite ------------------------------------------

Test Case 1   Target ->com.sunny.jxp.test.SingletonClass

com.sunny.jxp.test.SingletonClass   function test started.

Method : testMe   started

Method : testMe   return type  [void]

Method : testMe   return value [void]

Method : testMe   completed successfully

Mehtod : testMe    time ellaps [0] ms

com.sunny.jxp.test.SingletonClass   tested method count  = 1

com.sunny.jxp.test.SingletonClass   succeed method count = 1

com.sunny.jxp.test.SingletonClass   failed method count  = 0

com.sunny.jxp.test.SingletonClass   time ellapes [10] ms

com.sunny.jxp.test.SingletonClass   function test ended.

Test Case 2   Target ->com.sunny.jxp.test.Testee

com.sunny.jxp.test.Testee   function test started.

Method : intAddition   started

Method : intAddition   return type  [int]

Method : intAddition   return value [23]

Method : intAddition   completed successfully

Mehtod : intAddition    time ellaps [0] ms

Method : concateString   started

Mehtod : concateString   return type  [java.lang.String]

Method : concateString   return value [String1String2]

Method : concateString   completed successfully

Mehtod : concateString    time ellaps [0] ms

com.sunny.jxp.test.Testee   tested method count  = 2

com.sunny.jxp.test.Testee   succeed method count = 2

com.sunny.jxp.test.Testee   failed method count  = 0

com.sunny.jxp.test.Testee   time ellapes [20] ms

com.sunny.jxp.test.Testee   function test ended.

Test Case 3   Target ->com.sunny.jxp.test.Testee

com.sunny.jxp.test.Testee   function test started.

Method : intAddition   started

Method : intAddition   return type  [int]

Method : intAddition   return value [23]

Method : intAddition   completed successfully

Mehtod : intAddition    time ellaps [0] ms

Method : display   started

Method : display   return type  [void]

Method : display   return value [void]

Method : display   completed successfully

Mehtod : display    time ellaps [-10] ms

com.sunny.jxp.test.Testee   tested method count  = 2

com.sunny.jxp.test.Testee   succeed method count = 2

com.sunny.jxp.test.Testee   failed method count  = 0

com.sunny.jxp.test.Testee   time ellapes [20] ms

com.sunny.jxp.test.Testee   function test ended.

Test Suite   tested testcase count  = 3

Test Suite   succeed testcase count = 3

Test Suite   failed testcase count  = 0

 

Example 5: Dynamic Class path

//LoaderTestClass1.java

package test;

 

 

public class LoaderTestClass1

{

    public LoaderTestClass1(){};

   

   

    public void hello()

    {

        System.out.println("Hello World from class 1");

    }

   

     public String toString()

    {

        return ("Hello, I am LoaderTestClass1.");

    }

   

   

}

 

//LoaderTestClass.java

package test;

 

 

public class LoaderTestClass

{

    public LoaderTestClass(){};

   

   

    public void hello(LoaderTestClass1 ltc1)

    {       

        if(ltc1!=null) ltc1.hello();  

        else

            System.out.println("Hello World from LoaderTestClass");

    }

   

    public String toString()

    {

        return ("Hello, I am LoaderTestClass.");

    }

   

   

}

 

Test Descriptor:

<?xml version="1.0" encoding="utf-8" ?>

<test-suite>

            <test-case class="test.LoaderTestClass">

            <classpath location="c:\Projects\tp" />                                     

                        <test-runner>

                                    <test-method name="hello">

                                    <custom-type type="test.LoaderTestClass1"></custom-type>

                                    </test-method>

                        </test-runner>

            </test-case>

</test-suite>

 

Result (Full Detail ):

com.sunny.jxp.core.TestInputHandler   Test Descriptor loaded successfully.

   ----------------------------------------- Test Suite ------------------------------------------

Test Case 1   Target ->test.LoaderTestClass

test.LoaderTestClass   function test started.

Method : hello   started

Method : hello   return type  [void]

Method : hello   return value [void]

Method : hello   completed successfully

Mehtod : hello    time ellaps [0] ms

Method :hello Standard Output->   Hello World from class 1

test.LoaderTestClass   tested method count  = 1

test.LoaderTestClass   succeed method count = 1

test.LoaderTestClass   failed method count  = 0

test.LoaderTestClass   time ellapes [30] ms

test.LoaderTestClass   function test ended.

Test Suite   tested testcase count  = 1

Test Suite   succeed testcase count = 1

Test Suite   failed testcase count  = 0

 

5.     Test Descriptor Elements/Attributes reference

 

Dynamic class path loading are still under test. It expected to be available in next a few days. (Completed)

 

Convention:

0..*                              means zero or more

0..1                              zero or one

1..*                              one or more

1                                  at least one is required

[], or other                    either one is required

[], with option               either one in brack with or without option

 

Element test-suite

 

test-suite

Root Element

Attributes

name

String

Name of this test suite

log

String

Full path to log file

report-level

int

 

verbose

boolean

 

Sub Element

classpath(0..*), test-case(1..*)

 

Element test-case

     

test-case

A test case against a Java class. Child of test-suite.

Attributes

class

String

Name of class of this test case against to.

Sub Element

classpath(0..*), test-constructor(0..1), test-setup(0..1), test-runner(1), test-teardown(0..1)

     

Element classpath

           

classpath

Global or specific test-case’s class path

Attributes

location

String

semicolon(windows)/colon(unix or linux) separated string for classpath

Sub Element

 

 

Element test-constructor      

           

test-constructor

A constructor used to instantiate test-case’s class. without a test-constructor, JXPUnit will use Java Object Default No parameter constructor to instantiate class.

Attributes

source

String

If this test-case’s class is getting from other class. source Attribute specifys which class is.

Sub Element

[custome-type(0..*), param(0..*)], or test-method(0..1)

 

Element test-setup

           

test-setup

Setup test-case public field and some initial method calls

Attributes

 

 

 

Sub Element

public-field(0..*), test-method(0..*)

 

Element test-teardown

           

test-teardown

reset test-case public field and some clean method calls

Attributes

 

 

 

Sub Element

public-field(0..*), test-method(0..*)

 

 

Element test-runner

           

test-runner

A collection of test-method elements that will be tested against.

Attributes

 

 

 

Sub Element

test-method(1..*)

 

 

Element test-method

 

test-method

Stands for a definition of a method of test-case’s class

Attributes

name

String

Name of this test method

isStatic

boolean

Is this a static public method

Sub Element

custom-type(0..*), param(0..*), test-return(0..1)

 

Element custom-type

 

custom-type

Stands for a non-standard java type in java.lang package

Attributes

type

String

Java type of this parameter

source

String

Source class name, getting this parameter instance from this source class. it require a test-method present in sub element.

Sub Element

[custom-type(0..*), param(0..*)], or test-method(1)

 

Element param

           

param

Stands for a java default type parameter for test-method or test-constructor or public-field ,  that is exist in java.lang package.

Attributes

 

 

 

Sub Element

type(1), value(1)

 

 

Element public-field

           

public-field

Represents a public field in test-case’s class (not recommended, you shoud use setter/getter accessor method to do so).

Attributes

name

String

Name of this field in test-case’s class

Sub Element

custom-type(1),  or param(1)

 

Element type

           

type

Java type which exists in java.lang package.

Attributes

isArray

boolean

Array of this type(default false)

isWrapper

boolean

Exactly type of primitive type parameter. (default true)

Sub Element

Text string represents a default Java type in java.lang package

java.lang.String

java.lang.StringBuffer

java.lang.Integer

java.lang.Long

java.lang.Double

java.lang.Float

java.lang.Byte

java.lang.Short

java.lang.Boolean

java.lang.Character

 

Element value

           

value

Value of specific default paramter represents in text string.

Attributes

delimiter

String

Only need for array type(not implemented yet)

Sub Element

Text string, array may represents in comma separated fashion or with delimiter in specified attribute.

 

Element test-return

           

test-return

Expected return from a method under test.

Attributes

 

 

 

Sub Element

[custom-type(1), or param(1)], with condition(0..1)

 

Element condition

           

condition

JXPUnit use it to compare returned result with expected result.

Attributes

 

 

 

Sub Element

Text string representation of compare condition

eq, equals ------ compare equals or not

lt, less than ----- less than(not implemented yet)

gt great than ---- great than(not implemented yet)

lteq ----- less than equals(not implemented yet)

gteq ----- great than equals(not implemented yet)

default is NO ACTION, does not compare at all.