Unit testing ALBPM and OBPM: Unravelling PUnit, CUnit and PAPI JUnit Testing
I have long been a fan of unit testing. Thus, I was full of joy when I found out that there were PUnit and CUnit objects were made available back in ALBPM version 6.
My good mood was quickly dashed when I found out that there was not much in documentation and examples. There is a paragraph or two in the manual. And the example included with the installation of Studio was equally terse.
But, over time I eventually learned the ins and outs of leveraging these objects to my benefit. While they aren't as comprehensive or as reliable as I would like, they are quite useful.
I will let everyone know what I have learned about these objects here, so others will not have to go through the pain I went through figuring this out.
PUnit and CUnit -- What they are and What they do.
First of all, let's introduce these objects to those who don't yet know them.
PUnit objects are a special kind of Business Object you can create in the Component Catalog in ALBPM 6, 6.5, or OBPM 10g Studio.
They allow you to create automated tests of your processes in the style of JUnit tests. They will even allow you to specify how you want interactive activities to respond through the use of PUnit tasks.
CUnit objects are another special kind of business object that allow you to create automated tests of your business objects in the Catalog.
Creating a PUnit Test
Creating a PUnit object is easy. It's just a matter of choosing the right menu option off of the "New" menu when you right-click on a "Module" of the Catalog. See the Image below.

Creating a PUnit Object
Now creating a test method in the PUnit object is a bit more tricky. Right-click the PUnit object in the Catalog, select "New" then "Method". Here is the tricky part. You have to begin the name of the test method with the word "test". Otherwise, OBPM will not recognize that method as a test method. So, name the method something like "testProcess" or "testBetterDocumentation" or something like that.
After you have a test method (you will know because the method icon will be green instead of blue), you can put special PUnit test object calls into the method. You can find these easily by using Eclipse's Ctrl+Spacebar feature to tell you what you can do. The operations and objects are easy to understand, especially if you know PAPI.
To get you started, I have written a sample test method in this project export you can download here.
Notice the built-in methods "setUp" and "tearDown". These should be familiar to JUnit veterans. They initiate a PAPI connection/session to the Studio engine before running a test, and shut it down gracefully afterwards. You shouldn't need to change the "tearDown" method which is written for you. But, you may want to change the participant specified in the "setUp" method. After all, the participant specified here will be the user context under which the test will be performed, and you probably won't have a participant "punit" in your Organization settings.
There is also a built-in attribute of type Fuego.Test.ProcessServiceSession named session included with the PUnit test object. This is your connection to the Studio engine, and the object from which most of your interactions with the engine will be done.
Writing and Running a PUnit Test
The example I have provided shows how you can do the following tasks in a PUnit test.
- Create an instance of a process
- Assign input arguments to a process instance
- Assert that the instance is running
- Get the current activity of a running process
- Get the value of an instance variable (only works for simple data types)
- Assert that a process instance arrives at a certain activity within a certain amount of time
You can do much more with the session object. But these are the activities I usually do in a Process test. The Fuego.Test.ProcessServiceSession has some similar methods to the PAPI ProcessServiceSession. But, the PUnit version is quite different. You don't have as much flexibility as do with PAPI.
But, you are able to interact with interactive activities. Here is how you do it. Right-click on the interactive activity you are including in your process test, select the "PUnit task" menu option.

Testing Interactive Activities
Since PUnit tests are automated, and there is no actual user interaction, you specify how the interactive activity changes the process instance (when you are running the PUnit test) in the PUnit task. So if the interactive's output parameter set an instance variable, you would set the same instance variable in the PUnit task method.
Next, in the PUnit test method, when you are sure the process instance is waiting at the interactive activity, use the session.activityExecute method to execute the PUnit task specified.
To run the test method, first start the ALBPM or OBPM 10g engine. Then right-click the method in the Catalog, and choose "Run Test". The "Test Results" pane will pop-up and you can watch the test execute.

The Test Results Pane
If you are using objects in your Catalog which have been introspected from jar files as input or output parameters of processes, you will need to modify Studio/Eclipse's classpath.
The test runner executes the tests in Eclipse's Java environment. So, while writing the test code, there are no errors (Eclipse knows what is in the Catalog), and the engine runs fine (in another Tomcat Java environment which has the jar files deployed with the BPM project), the test runner will report ClassNotFound.
This is pretty tricky, I solved it by modifying the file %BEA_HOME%\albpm6.0\studio\eclipse\configuration\config.ini and changed the osgi.frameworkClassPath value to include my custom jar files in Eclipse's classpath.
While this worked for me, occasionally I still received ClassNotFound errors. But these went away when I restarted ALBPM Studio.
Limitations of PUnit Tests
You can get the values of instance variables returned to the test method. However, this only works reliably for simple or native data types. Complex datatypes (business objects, and introspected objects) can be viewed as XML if they are serializable. Otherwise, their values can't be inspected in the test.
Testing processes which use subprocesses and Split/Join activites can be difficult. You can't get a subprocess' Id from the parent process. And targeting a specific thread in a Split/Join group can be difficult.
Those limitations aside, testing Processes with PUnit is a pretty useful feature. One of the more welcome features is the ability to change the PUnit test method and run it without having to stop the engine or redeploy the process.
Writing and Running CUnit Tests
As mentioned earlier CUnit tests can be used in the traditional fashion to test code written in Business Objects to insure they work as expected. You create and write CUnit tests in the same way as you do PUnit tests. You also have to start the names of CUnit test methods with the word "test".
CUnit tests can also be used to verify or proove that External Systems (Web Services or Databases, etc.) are returning the expected responses to your inputs. Or, they can be used to do ad-hoc testing of Business Object code.
The advantage of CUnit tests to PUnit tests is that you don't need to have an engine running or a process deployed to run them. But if you are using introspected jar's in the test code, you will need to change Eclipse's classpath as shown earlier.
Using a PAPI JUnit Java Test Environment
Sometimes you need to test your BPM project in a J2EE container because the process just does not behave the same way in Tomcat as it does in WebLogic Server. To do this, simply write JUnit test cases using PAPI. Doing this has some advantages and disadvantages to using the PUnit test cases.
- If your subprocess activity has the "Generate Events" option turned on, the PAPI JUnit test case can pick up a process' subprocess id and continue testing. You can't do this with PUnit tests.
- You can get the vales of instance variables of complex data types.
- PAPI JUnit test methods can not execute interactive activites in a process. PUnit tasks are not available ouside of ALBPM / OBPM Studio.
Once written PAPI JUnit tests can be run on both the J2EE engines as well as ALBPM / OBPM Studio engines.
You can download this example to get you started creating a PAPI JUnit test suite.












