36
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)

Unit Testing RPG with JUnit

Embed Size (px)

Citation preview

Page 1: Unit Testing RPG with JUnit

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)

Page 2: Unit Testing RPG with 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

Page 3: Unit Testing RPG with JUnit

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.

Page 4: Unit Testing RPG with JUnit

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.

Page 5: Unit Testing RPG with JUnit

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

Page 6: Unit Testing RPG with JUnit

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.

Page 7: Unit Testing RPG with JUnit

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

Page 8: Unit Testing RPG with JUnit

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

Page 9: Unit Testing RPG with JUnit

Right click and select Sharing/New Share…

Page 10: Unit Testing RPG with JUnit

Create the file system share

Be sure to select Read/Write access!

Page 11: Unit Testing RPG with JUnit

In Windows Explorer, select Tools/Map Network Drive…

Page 12: Unit Testing RPG with JUnit

Complete mapping a drive to the share created earlier.

Example: \\server\share

Page 13: Unit Testing RPG with JUnit

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.

Page 14: Unit Testing RPG with JUnit

Next Steps

Review the ILE RPG procedures we will test.

Create the test components. Run the tests.

Page 15: Unit Testing RPG with JUnit

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

Page 16: Unit Testing RPG with JUnit

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.

Page 17: Unit Testing RPG with JUnit

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

Page 18: Unit Testing RPG with JUnit

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:

Page 19: Unit Testing RPG with JUnit

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

Page 20: Unit Testing RPG with JUnit

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)

Page 21: Unit Testing RPG with JUnit

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.

Page 22: Unit Testing RPG with JUnit

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.

Page 23: Unit Testing RPG with JUnit

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

Page 24: Unit Testing RPG with JUnit

Interaction of the Software Components

Page 25: Unit Testing RPG with JUnit

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.

Page 26: Unit Testing RPG with JUnit

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

Page 27: Unit Testing RPG with JUnit

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.

Page 28: Unit Testing RPG with JUnit

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.

Page 29: Unit Testing RPG with JUnit

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

Page 30: Unit Testing RPG with JUnit

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.

Page 31: Unit Testing RPG with JUnit

Compile and Run the Java

Page 32: Unit Testing RPG with JUnit

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.

Page 33: Unit Testing RPG with JUnit

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.

Page 34: Unit Testing RPG with JUnit

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.

Page 35: Unit Testing RPG with JUnit

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

Page 36: Unit Testing RPG with JUnit

References (continued)

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