Unit Testing RPG with JUnit

Preview:

Citation preview

Unit Testing RPG with JUnit

"Never in the field of software development was so much owed by so many to so few lines of code"

Martin Fowler (speaking of JUnit)

Agenda

Costs of Manual Testing Value of Automated Unit Testing The Tools We’ll Use Creating the Infrastructure Reviewing the Component to be Tested The Test Components Writing the interface code and the Tests Compiling the Java Running the Tests Automating the Process

Costs of Manual Testing

Manual testing generally occurs late, just

before integration. The cost to correct

problems at this stage are ten to a hundred

times greater than the cost to correct the

problem before the project reaches this stage.

A problem found late in the development cycle

can delay the carefully planned work of a

dozen people.

Value of Automated Testing

Writing tests before writing the application

code increases cohesion and reduces

coupling.

You won’t understand it until you’ve done it.

The tests are reusable. Reuse is free. Write

tests once; verify quality a thousand times

without lifting a finger.

The Tools We’ll Use The JUnit JAR file (junit.jar)

iSeries QSHELL and shell scripts

javac, the Java compiler

JNI, Java Native Interface

iSeries Navigator

iSeries IFS (integrated file system)

PC-based Text Editor

iSeries Source Editor

RPG Compiler

Creating the Infrastructure

Add a “Share” to your IFS folder.

Map the share to Windows Explorer.

Place a copy of the JUnit jar file in your IFS folder.

To add the file share, use iSeries Navigator and select the Integrated File System on the iSeries on which you’ll be developing.

Find or create your IFS folder. We require one to be under Root/home.

Right click and select Sharing/New Share…

Create the file system share

Be sure to select Read/Write access!

In Windows Explorer, select Tools/Map Network Drive…

Complete mapping a drive to the share created earlier.

Example: \\server\share

Getting the JAR File

Download JUnit from http://junit.org Open the Zip file, select the junit.jar and

extract it your development folder on the iSeries share drive.

Next Steps

Review the ILE RPG procedures we will test.

Create the test components. Run the tests.

Review the RPG Procedures to be Tested

* Trivial Example: Add and Subtract * h nomain h option(*srcstmt:*nodebugio) h datfmt(*ISO) * d addInts pr 15P 0 extproc('addInts')d 15P 0 CONST d 15P 0 CONST * d subInts pr 15P 0 extproc('subInts')d 15P 0 CONST d 15P 0 CONST * p addInts b EXPORT d pi 15P 0 d p1 15P 0 CONST d p2 15P 0 CONST c return p1 + p2 p e * p subInts b EXPORT d pi 15P 0 d p1 15P 0 CONST d p2 15P 0 CONST c return p1 - p2 p e

The Test Components

To create and run the tests, 4 objects are required: The service program to be tested. The service program that provides the

native interface to Java. The Java Class that accesses the RPG

service program. The class that implements the unit test.

Parameter Conversion TableThe necessary information for converting parameter values is in chapter 11 of the RPG Programmer’s Guide.

A second RPG module is required

1. the *JAVA keyword

2. the fully qualified name of the Java class that will execute this procedure.

3. the name of the Java method (marked native) which will call the ILE procedure.

For Java to access the RPG, the ILE procedures must be given a Java interface with the EXTPROC keyword.

When interfacing with Java, the EXTPROC keyword requires three parameters:

h nomain h option(*srcstmt:*nodebugio) h datfmt(*ISO) * Imported Procedures d addInts pr 15P 0 extproc('addInts')d 15P 0 CONST d 15P 0 CONST * d subInts pr 15P 0 extproc('subInts')d 15P 0 CONST d 15P 0 CONST * Exported Procedures d add pr 10I 0 extproc(*JAVA: d 'com.rpg.Math‘ : 'add') d 10I 0 value d 10I 0 value * d sub pr 10I 0 extproc(*JAVA: d 'com.rpg.Math‘ : 'sub') d 10I 0 value d 10I 0 value * p add b EXPORT d pi 10I 0 d p1 10I 0 value d p2 10I 0 value c return addInts(p1: p2) p e * p sub b EXPORT d pi 10I 0 d p1 10I 0 value d p2 10I 0 value c return subInts(p1: p2) p e

Compiling the RPG

Create the RPG modules:

crtrpgmod calculator

crtrpgmod calcjni

Create the service program with or without binding source:

crtsrvpgm jniformath module(calcjni calculator) export(*all)

Write the Java code that calls RPG

package com.rpg;public class Math { static { System.loadLibrary("JNIFORMATH"); } native public int add(int add1, int add2); native public int sub(int sub1, int sub2); }

The JNI magic necessary for Java to call RPG simply requires (1.) the name of the service program to be provided in the parameter of the call to System.loadLibrary() and (2.) the creation of the native method signatures.

Your PC’s NotePad or WordPad editor is sufficient for this task.

The Unit Test

import junit.framework.*; public class MathTest extends TestCase { Math math; protected void setUp() { math = new Math(); } public void testAdd() { Assert.assertEquals(2, math.add(2,0)); Assert.assertEquals(2, math.add(1,1)); } public void testSub() { Assert.assertEquals(0, math.sub(2,2)); Assert.assertEquals(0, math.sub(1,1)); }}

This class inherits from junit.framework.TestCase. To compile and run, junit.jar must be in the classpath.

Save the Java source to the iSeries’ IFS using the drive we mapped earlier, being careful to match folders to the package statements.

Interaction of the Software Components

Preparing to Compile the Java Source

The Java source is in folders in the iSeries’s IFS. We will compile and run the Java programs in the QSHELL environment on the iSeries.

From the command line of the iSeries system where the Java and RPG are placed, enter the command QSH to start the alternative Unix shell environment on iSeries.

Commands Useful in QSHELL

LS – list files (similar to MS-DOS DIR command)

PWD – display name of current folder

CD – change directory (just as in MS-DOS)

CAT – takes a file name as its parameter and displays file’s text

Java’s Compile Command

JAVAC is the Java compiler. It can be run by an IDE or from the command line. It is most convenient in this exercise to run JAVAC from QSHELL.

Compile Dependencies

The classes you compile in Java may be dependent on JAR files just as the compile of RPG programs can be dependent on binding directories, service programs and modules.

The Test classes will depend on junit.jar.

Compiling With JAVAC

The Math class provides the JNI interface to RPG. It was placed in the com.rpg package so the compile command is as follows:

javac com/rpg/Math.java

The MathTest class inherits from junit.framework.TestCase so, the junit.jar file must be in the classpath when it is compiled:

javac –classpath .:../lib/junit.jar MathTest.java

Running With JAVA

To execute Java Classes, the JAVA command is used instead of CALL. Note that the classpath contains the junit.jar file.

Also note that we are calling junit’s TestRunner class and passing it the name of our test class.

java -classpath .:../lib/junit.jar junit.textui.TestRunner MathTest

The entire JAVA command above wraps to two lines but it is not required that it do so.

Compile and Run the Java

Automating the Process: Run the Compile and Test in a Shell Script

if !(javac -classpath .:../lib/junit.jar src/** -d build/prod); then exit 1; fi;

jar -cf Math.jar build/prod/*.class

java -classpath .:../lib/junit.jar:Math.jar junit.textui.TestRunner MathTest

ANT is another neat tool from the Open Source community. ANT could be used to automate these tasks but, that requires quite a long discussion.

A QSHELL script also provides a means to easily compile the Java and run the tests. Create the script by placing commands similar to those below in a file.

Results of Running the ScriptA compile error interrupts the script when it is first run. After the error in the Java source is corrected, the script runs successfully, performing both the compile and the testing.

Next Steps

Don’t stop with just these tests. Create more. Find out what breaks your application’s code and attack those problems.

Implement a way for your team to share, store and version tests.

Learn Test Driven Development.

References

1. JUnit: http://junit.org 2. QSHELL for iSeries by Ted Holt and Fred A.

Kulack: http://skillport.books24x7.com3. JNI Articles: http://

www.iseriesnetwork.com/artarchive/index.cfm?fuseaction=ListArticlesByAuthor&ID=883

4. JNI RPG and the eBusiness World (ch 11) http://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/books/sc092507.pdf

References (continued)

Sun’s Tutorial – First Steps for Unix: http://java.sun.com/docs/books/tutorial/getStarted/cupojava/unix.html

Recommended