Testing BPEL in the Real WorldBy Lonneke Dikmans
Use the Oracle BPEL Test Framework to improve the quality of your BPEL processes.
One of the big benefits of service-oriented architecture (SOA) development is that it approaches design from a business, as opposed to a technical, point of view. Unfortunately, SOA development projects can be more complicated than "regular" Java Platform, Enterprise Edition (Java EE) projects. With SOA projects, there are often more stakeholders, more disparate technologies to integrate, and more possible misunderstandings about overall project goals.
Testing in such an environment can be complicated—from both a technical and an organizational perspective. To properly test an SOA deployment, you need to test the set of Web services, the individual applications that implement the Web services, and the business processes that handle the orchestration of these services.
This article describes how to test a BPEL process by using the Oracle BPEL Test Framework. This framework, part of Oracle BPEL Process Manager, provides a way to create and execute a set of repeatable tests on a BPEL process. In addition, this article also offers some best practices borrowed from traditional integration and agile development projects to help developers, project managers, and testers working in an SOA environment.
The examples in this article are all based on a simplified BPEL process that manages automobile loan applications. As Figure 1 shows, the process contains the following steps:
1. A potential customer applies for a loan.
A single BPEL process and two services are used to implement the business process described above. One service implements a credit rating, and the other provides loan advice.
In our walk-through, we will build these components by modifying an AutoLoanFlow sample project, which is part of the AutoLoanDemo BPEL demo that is installed by default with Oracle BPEL Process Manager.
Before getting started, make sure you have Oracle SOA Suite installed and configured and that you have the AutoLoanFlow project running in Oracle JDeveloper. Follow the steps below to complete this setup.
1. Install Oracle SOA Suite 10g Release 3 (10.1.3.1) or later, along with Oracle JDeveloper 10g Release 3 (10.1.3.1) or later. These products, with installation and configuration instructions, are available at the Oracle SOA Suite download page, at otn.oracle.com/software/tech/soa. When installing Oracle SOA Suite, be sure the BPEL and business rules components install (they should be installed by default). Also note the SOA application Oracle Application Server Containers for Java Platform, Enterprise Edition (OC4J) instance name specified by the installer, because you'll need it in the next step when configuring an Oracle Application Server connection.
2. In Oracle JDeveloper, set up Oracle Application Server and Oracle Integration Server connections to the newly installed Oracle SOA Suite components. Open the Connections Navigator tab, and double-click Application Server to launch the Create Application Server Connection wizard. After completing the wizard and testing the connection, double-click Integration Server in the Connections Navigator tab and complete the Create Integration Server Connection wizard.
3. In Oracle JDeveloper, open the AutoLoanFlow.jpr project file. It is located in [SOASUITEHOME] -> bpel -> samples -> demos -> AutoLoanDemo -> AutoLoanFlow , where [SOASUITEHOME] is the directory in which you installed Oracle SOA Suite. In the Create Application to Contain Project dialog box, which appears, enter AutoLoanFlowTest as the application name. Note that we'll be making changes to this project, so if you'd like to keep the original project for another use, make a copy of the AutoLoanDemo folder and use the copy for this walk-through.
4. In the Applications Navigator tab, open AutoLoanFlow.bpel to bring up the Diagram view in the main edit pane. Expand the GetLoanAdvise icon, and change the name of the Invoke activity to InvokeLoanAdvisor . Next, expand the GetCreditRating icon and change the name of the Facts_To_BPEL_Var activity to CreditRatingFacts_To_BPEL_Var . These steps are necessary because the Oracle BPEL Test Framework requires unique names for each activity.
5. Remove the loan approval part of this process. To keep this example simple, delete the SetupTaskPayload activity, the LoanApproval_1 scope, and taskSwitch.
6. Finally, deploy the modified AutoLoanFlow process to the SOA instance. In the Applications Navigator tab, right-click the AutoLoanFlow project and select Deploy -> BPEL Process Deployer . In the dialog box that appears, click OK to deploy the process by using the Oracle Integration Server connection created earlier in your setup.
Testing the Process Steps
Now it's time to create a suite of test cases that test the BPEL AutoLoanFlow process. As these test cases execute, they don't actually call the credit rating and loan advisor services specified in the process flow. Instead, they emulate these services and execute the entire process flow as if these services had actually been called. This approach makes it easier to test the integrity of the process prior to deployment in a production environment.
Create the test suite. Begin by creating a test suite in Oracle JDeveloper. Note that a BPEL test suite is simply a logical collection of test cases. In the Applications Navigator tab, right-click AutoLoanFlow.bpel and select Test -> Create Test Suite . In the dialog box that appears, name the test suite logicSuite .
Create a baseline test. A baseline test is a test that does not run on its own but exists to be included within other tests. Baseline tests make it possible to reuse parts of a test in multiple test cases. Although you could build a test case from scratch (without using a baseline test), it's often easier to use Oracle BPEL Process Manager to build a baseline test for you. The latter approach is recommended when you have existing BPEL processes or are new to the BPEL testing framework.
Perform the following steps to create a baseline test:
1. Open a browser window, and navigate to the Oracle BPEL Process Manager console, using this URL syntax:
2. Enter the username and password of the SOA administrator. By default, the administrator username is oc4jadmin.
3. On the console dashboard that appears, click the AutoLoanFlow process. (Note: if the process does not appear under Deployed BPEL Processes , check your preliminary setup to make sure you deployed the process to the SOA instance.)
4. In the "Initiating a test instance" form area, select XML Source . Then copy the code from Listing 1 into the message box that appears.
Code Listing 1: XML source for test
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header/> <soap:Body xmlns:ns1="http://www.autoloan.com/ns/autoloan"> <ns1:loanApplication> <ns1:SSN>12345</ns1:SSN> <ns1:email>firstname.lastname@example.org</ns1:email> <ns1:customerName>Irving Stone</ns1:customerName> <ns1:customerAge>41</ns1:customerAge> <ns1:customerAnnualIncome>45000.0</ns1:customerAnnualIncome> <ns1:city>Redwood</ns1:city> <ns1:state>CA</ns1:state> <ns1:country>United States</ns1:country> <ns1:loanAmount>60000.0</ns1:loanAmount> <ns1:carMake>Toyota</ns1:carMake> <ns1:carModel>Toyota 4Runner</ns1:carModel> <ns1:carYear>2005</ns1:carYear> <ns1:creditRating></ns1:creditRating> <ns1:creditRisk></ns1:creditRisk> <ns1:creditMaxAmount></ns1:creditMaxAmount> </ns1:loanApplication> </soap:Body> </soap:Envelope>
5. Click Save Test.
6. Click Post XML Message to create a new test instance. A message saying that a test instance is being processed asynchronously should appear.
7. In the upper right corner of the Web page, click the Instances tab. In the list of BPEL process instances that appears, click the test instance you just created. Then click the Test tab to get to the Test Case Information page.
8. Click Save as unit test (.xml) to save this instance as a unit test case. Save the generated XML, using the filename baseline.xml on your local file system, into the bpel/testsuites/logicSuite/includes subdirectory of the AutoLoanFlow project directory. Note that this file must appear in the includes subdirectory to be used as a baseline case.
9. Import the baseline test into Oracle JDeveloper, by selecting the logicSuite test suite in the Applications Navigator tab and selecting Refresh from the View menu. The baseline.xml test case should now appear in the Includes directory in the tree.
Design the test cases. The next task is to design the test cases that will be used to test the BPEL process. Oracle BPEL Process Manager test cases contain several key components:
Initiate action. Every test case starts with an initiate action that calls the BPEL process and defines the initial payload. See Listing 2 for the initiate action we will use in all of our test cases.
Code Listing 2: Initiate operation
<BPELTest processName="AutoLoanFlow" xmlns="http://xmlns.oracle.com/bpel/instancedriver"> <initiate operation="initiate"> <inboundMessage> <part name="payload"> <content> <ns1:loanApplication xmlns:ns1="http://www.autoloan.com/ns/autoloan"> <ns1:SSN>12345</ns1:SSN> <ns1:email>email@example.com</ns1:email> <ns1:customerName>Irving Stone</ns1:customerName> <ns1:customerAge>41</ns1:customerAge> <ns1:customerAnnualIncome>45000.0</ns1:customerAnnualIncome> <ns1:city>Redwood</ns1:city> <ns1:state>CA</ns1:state> <ns1:country>United States</ns1:country> <ns1:loanAmount>60000.0</ns1:loanAmount> <ns1:carMake>Toyota</ns1:carMake> <ns1:carModel>Toyota 4Runner</ns1:carModel> <ns1:carYear>2005</ns1:carYear> <ns1:creditRating/> <ns1:creditRisk/> <ns1:creditMaxAmount/> </ns1:loanApplication> </content> </part> </inboundMessage> </initiate>
Emulations. When executing a BPEL process, the test cases don't actually call the partner services included in the process definition. Instead, the test cases in our example emulate the services' activity. As part of the emulation, the test cases also specify the data to be returned by each service being emulated. Listing 3 shows the part of baseline.xml (which we created earlier) that emulates invoking the CreditRatingAgent.
Code Listing 3: Emulating the CreditRatingAgent
<activityDriver name="Invoke" firstIteration="1" lastIteration="1"> <emulate> <inboundMessage> <part name="payload"> <content> <ns0:assertExecuteWatchStatelessDecision xmlns:ns0="http://xmlns.oracle.com/AutoLoanFlow/CreditRatingAgent"> <ns0:resultList> <rating xmlns="http://samples.otn.com/bpel/demo"> <SSN>12345</SSN> <rating>500</rating> <risk>Medium</risk> <maxAmount>50000.0</maxAmount> </rating> </ns0:resultList> </ns0:assertExecuteWatchStatelessDecision> </content> </part> </inboundMessage> </emulate> </activityDriver>
Assertions. Assertions are used to validate a variable or an entire XML document at any point during a BPEL process execution. Three types of assertions are available. Simple Value Assert checks the value of a variable, XML Assert compares the elements of an entire XML document with their expected values, and Activity Executed Assert checks the number of times an activity is invoked.
When you are designing test cases, it is important to decide how many assertions to put into a single test case. Because one execution of a test case (or test run) corresponds to one BPEL process instance, only one execution path is possible per test case. You can, however, divide test cases based on the activities you want to assert. This approach might be useful if you have a large BPEL process and you want to check certain transformations or activities within single test cases.
Because our example is more straightforward, let's instead divide the test cases according to possible outcomes. One outcome is that the loan will be approved, and the other is that the loan will be rejected. So for this example, we'll create two test cases. For each test case, we will emulate invoking the CreditRatingAgent and assert the value of the credit rating.
First, let's create the test case in which the loan is approved:
1. In the Applications Navigator tab, right-click the logicSuite test suite and select Create BPEL Test... . In the dialog box that appears, name the test case testApprove and click OK.
2. Include the baseline test case baseline.xml. Make sure the Diagram view is open for testApprove.xml, and click the Included BPEL Tests button in the upper left corner of the edit pane. In the dialog box that appears, click Add and select baseline.xml to add it to the set of included BPEL tests.
Next, add the assert value to CreditRatingFacts_To_BPEL_Var.
1. In the Diagram view for testApprove.xml, expand the GetCreditRating icon and double-click the CreditRatingFacts_To_BPEL_Var icon. Make sure the Asserts tab is selected, click Create , and select Value Assert... from the menu that appears.
2. In the Create Value Assert dialog box, click the flashlight icon to the right of the Variable field to open the Variable XPath Builder dialog box. Navigate to /ns3:loanApplication/ns3:creditRating of inputVariable , and click OK.
3. Enter 500 as the expected value for the rating.
4. Enter an error message that will appear if the assertion fails. (Do not leave this field blank.)
5. Uncheck the Fatal check box so that the test will continue even if this assertion fails. At this point, the Create Value Assert dialog box should appear, as in Figure 2. Click OK twice to close the dialog boxes and complete the assertion definition.
Next, override InvokeLoanAdvisor.
1. In the Diagram view for testApprove .xml, expand the GetLoanAdvise icon and double-click the InvokeLoanAdvisor icon. Click the Emulate tab.
2. Check Override Included Emulation , and in the message field body, change <approved>false</approved> to <approved>true</approved> . Click OK to save your changes.
Next, assert that the loan is approved.
1. In the Diagram view for testApprove.xml, double-click the callbackClient icon.
2. As you did above with CreditRatingFacts_To_BPEL_Var, create a Value Assert to check that the loan is approved. In this case, navigate to /ns3:loan/ns3:loanOffer/ns3:approved of the taskPayload variable and enter true for the expected value. As before, enter an error message to appear in case the assertion fails and uncheck the Fatal check box.
3. Save the test.
The first test case is now finished. Now let's create the second one.
1. As before, create a new test case within the logicSuite test suite. Call this test case testReject.
2. Include the baseline test case baseline.xml.
Next, override the Invoke activity.
1. In the Diagram view for testReject.xml, expand the GetCreditRating icon and double-click the Invoke activity. Click the Emulate tab.
2. Check Override Included Emulation , and in the message body, change the value of the rating from 500 to 400. Click OK to save changes.
Next, assert the creditRating.
1. While the GetCreditRating icon is still expanded, double-click the CreditRatingFacts_To_BPEL_Var icon.
2. As you did before, create a new Value Assert. In this case, navigate to /ns3:loanApplication/ns3:creditRating of inputVariable . Set 400 as the expected value. As before, enter an error message to appear in case the assertion fails and uncheck the Fatal check box.
Next, assert that the loan is rejected.
1. In the Diagram view for testReject.xml, double-click callbackClient.
2. Create another Value Assert, this time to check that the loan is rejected. In this case, check that /ns3:loan/ns3:loanOffer/ns3:approved of taskpayload equals "false." Again, enter an error message to display in case the assertion fails and uncheck the Fatal check box.
3. Save the test.
Now that the two test cases are finished, the next step is to deploy the test cases.
1. In the Applications Navigator tab, right-click the Test Suites folder and select BPEL Test Deployer....
2. In Test Suites to Deploy , expand the logicSuite test suite and the Tests folder and select both the test suite and the two new test cases. In Servers to Deploy Into , select the Oracle Integration Server connection created during the preliminary setup.
3. Click Deploy. After a few seconds, the test suite should be deployed to the Oracle BPEL Server.
Now run the test suite. You can automate the execution of the test suite by either using Ant or using the Oracle BPEL Process Manager console. Ant tasks are very useful when you want to automate the test process and create nightly builds. The console is often more convenient when you develop new test cases or if you are more comfortable using a GUI.
The following steps describe how to use the console to run the test suite.
1. Open a browser window, and navigate to the Oracle BPEL Process Manager console. Log in with the username and password of the SOA administrator.
2. In the upper right corner of the BPEL Control console, click the BPEL Processes tab. From Deployed Processes , select the AutoLoanFlow process. Then click the Test Suites tab.
3. On the Test Suites page, expand the logicSuite test suite and select the two new test cases. Click Execute Tests to run the tests.
4. A BPEL test report will appear.
Testing the Entire System
After testing the functional integrity of the BPEL process, it is important to do an integration test. Several tools—both commercially available and open source—are available to assist with this task. A comprehensive integration test needs to address many issues, including the following:
Functional correctness. The earlier tests included emulations of the underlying services. The integration test needs to ensure that the process works correctly in a real-world environment as well.
Availability. Integration tests should ensure that high-availability criteria, preferably based on some kind of service-level agreement (SLA), can be met.
Interoperability. Services can be invoked by different services residing on different platforms (such as Java EE or .NET). Interoperability tests ensure that services work properly under different operating scenarios.
Security. Some services require that the client invoking the process perform authentication. This kind of security requirement should be considered as part of an integration test.
Load and performance testing. These tests help identify technology components—such as the infrastructure, the services, and the BPEL process itself—that may need tuning.
Recovery. Tests should be performed to determine how services should recover as a result of various kinds of failures.
These aspects of testing are often overlooked in many organizations, because they are harder to test in an SOA environment than in a "regular" Java EE environment. These tests can require many different tools as well as cooperation from teams in other departments that manage the different services being called by the process. However, the impact of ignoring these testing issues can be very significant. In many cases, Web services run fine in a controlled development environment, only to fail in a real-world environment when exposed to unforeseen scenarios. As a result, these integration tests should be designed and run in the early stages of a project as well as during the entire lifecycle of a service. Doing so makes it possible to quickly discover degradation of the service in any aspect described above.
To deliver the promise of agility within an SOA, it is important to develop automated tests that cover both the services and the processes that orchestrate those services. This article has shown how this can be accomplished with the Oracle BPEL Test Framework.
The Oracle BPEL Test Framework, which is part of Oracle BPEL Process Manager and is integrated into Oracle JDeveloper, provides features similar to those that developers would expect when practicing test-driven development in Java EE projects. Along with Ant tasks that deploy, execute, and provide reports on tests, this test framework can easily be combined with testing tools and an automated deployment process to meet the most-demanding SOA testing needs.
Lonneke Dikmans (firstname.lastname@example.org) is a managing partner at Approach Alliance (www.approach-alliance.com), a Netherlands-based information and communications technology consultancy focusing on SOA and business intelligence.