8 Testing Business Rules

This chapter describes how to test rules from Rules Designer of Oracle JDeveloper by using the Rules Test Framework provided by Oracle Business Rules. It also discusses how to test rules and Decision Tables by creating an Oracle Business Rules Function. In addition, it covers at runtime, how to test a SOA Application that uses Oracle Business Rules through a decision service by using Oracle Enterprise Manager Fusion Middleware Control Console.

8.1 Testing Oracle Business Rules at Design Time

Oracle Business Rules provides a test framework that allows you to test rules with complex input parameters. This framework enables you to test rules at the time of designing so that you can validate or refine the rules as per your requirement.

Another way of testing rules is by defining a test function, where you can construct the input, execute rules, and validate the output. Because inputs are constructed and outputs are validated programmatically, test functions are typically used for simple tests, and the test framework is used for comprehensive tests. In addition, this test function is active only for functions that do not take any parameters and only return boolean values.

8.1.1 How to Test Rules Using the Rules Test Framework

Oracle Business Rules provides an 'out-of-the-box' functionality that enables you to test whether the rules you are defining works fine with a given set of inputs at the time of designing. The granularity of testing provided is at the level of decision functions. When you define decision functions in a dictionary, you can define test suites and execute those test suites for each of the decision functions.

Oracle Business Rules supports multiple types of facts, such as Java facts, XML facts, RL facts, and ADFBC facts. The test framework currently only supports XML facts. So, if the decision function, which you have defined, have inputs or outputs referring to non-XML facts, the test framework cannot be used to test the decision function. If you use non-XML facts, a warning or error message is displayed indicating that you cannot use the test feature for that decision function.

To test rules, you need to create a decision function as the prerequisite.

8.1.1.1 Creating a Decision Function

Open Oracle JDeveloper.

From the Application Navigator, open the project file containing the dictionary whose rules you want to test, say BaseDictionary.rules under Business Rules.

In the dictionary section, click Decision Functions to open the list of decision functions.

In the decision functions section, click the Create icon (the plus sign) to display the Edit Decision Function dialog box.

Enter the name of the decision function in the Name field, say TestDF.

In the Input tab, enter the input name under Name and press Enter. In this example, enter songs.

Select the fact type from the Fact Type list. Ensure that you select XML facts. In this example, select Song as the fact type. Similarly, another input variable with the name as artists and fact type as Artist has been added.

In the Output tab, enter an output name under Name and press Enter. In this example, enter songs.

Select the fact type from the Fact Type list. Ensure that you select XML facts. In this example, select Song.

Under Rulesets & Decision Functions, select the ruleset that you want to invoke from the Available box, and use the shutter (>) icon to move it to the Selected box. In this example, SongArtistRules has been selected.

When you create a decision function, two XML schemas (xsd files) get automatically generated to help in testing the decision function. These schemas have suffixes _TestSuite and _Types respectively. Further, these schemas are stored in an xsd folder under the testsuites folder, which can be seen in the Application Navigator as shown in Figure 8-2.

You need to define the test suites, which are created for the decision function, based on the schema with the suffix _TestSuite.

<DictionaryName>_<DecisionFunctionName>_TestSuite.xsd: This file contains the test suite schema for the decision function. Test Suites created for this decision function should conform to this schema. The following is a sample of the TestSuite.xsd file:

As you can see in the preceding sample, the schema contains a master testSuite element, which in turn contains an element called decisionFunction that defines to which decision function does this test suite corresponds.The testSuite element also contains one or more testCase elements. Each testCase contains a testInput and expectedOutput elements and a name. The testInput values are the ones that are used as inputs to the test cases and expectedOutput values are the ones against which the actual outputs are matched. The types of testInput and expectedOutput (parameterList and resultList respectively) have been defined in the subsequent XSD.

<DictionaryName>_<DecisionFunctionName>_Types.xsd: This schema contains two complexTypes elements, parameterList and resultList. These two types are used in the TestSuite schema but are defined here. The parameterList type corresponds to the decision function input and the resultList type corresponds to the decision function output. This is because a decision function has specific inputs and outputs. When you write a test case for a decision function, then the test case input need to correspond to the inputs accepted by the decision function and the expected output need to correspond to the decision function outputs. paramaterList and the resultList are single complexTypes. For example, a decision function requires 10 inputs and 5 outputs, then the parameterList type will be a single ComplexType that collectively defines 10 different elements that need to be provided as the decision function input.

Every time there is an update to the decision function, the corresponding two schemas get updated. For example, if you change the name of the decision function, then the names of the associated schemas are changed. If you delete the decision functions, the corresponding schemas get deleted.Even changes to the inputs and outputs of the decision function results in the associated schemas getting changed. So a decision function and its corresponding test schemas are always in sync.

In case you make any changes to the decision function, for example delete the decision function, typically the schemas get deleted. When you click the Undo icon on the dictionary toolbar, the decision function is retrieved. However, the corresponding schemas remain deleted. You need to manually regenerate the schemas for the decision function in this case. So the sync between the decision function and its corresponding test schemas is not supported in undo and redo operations.

To manually regenerate the schemas:

Click the Generate test suite schemas for all decision functions icon on the dictionary toolbar as shown in Figure 8-3.

Figure 8-3 Manually Regenerating Test Suite Schemas

When you click the icon to regenerate the test suite schemas, a bulk regeneration activity takes place, and all the test suite schemas pertaining to all the available decision functions in the dictionary gets regenerated. If the schemas already exist, those are overwritten.

This activity is particularly used in the following cases:

When you have deleted or modified the decision function and have undone the changes: This results in the decision function and the associated schemas getting out of sync. To get them in sync, you use this option so that the schemas are regenerated to correspond to the decision function.

When you migrate old dictionaries: Consider a situation when you already have dictionaries from earlier releases with a number of decision functions defined and you want to use the rules testing feature for defining test suites for those decision functions to test them. In this case, either you have to open each decision function in the editor window after migrating, and then click the OK button. This would generate the corresponding test suite schemas. However, this is time-consuming when you have hundreds of decision functions. In this case, you can use the option of regenerating the schemas at one go.

Note:

You need to ensure that the migrated decision functions have XML facts as inputs and outputs, else the inputs and outputs defined in the test suite schema files will be empty.

8.1.1.2 Testing the Rules

Once you have created the decision function for testing the rules, you can test rules.

To test rules:

Select the decision function name, say TestDF in this case, in the dictionary page and then click the Test button to display the Decision Function Test dialog box.

When you create a test suite, a <test suite name>.xml file gets automatically generated and gets stored in the <base dictionary name> folder under the rules folder inside the testsuites folder. You can view the file in the Application Navigator window. For every test suite that you create, a corresponding XML file gets generated.

However, the newly created test suite file is empty, which does not contain any test case, input definitions, or output definitions.

Open the <test suite name>.XML and write the required test cases that conform to the test suite XSD file, in this case the TestDF XSDs corresponding to the decision function under test.

The Comments section in the Results page displays any error details in case a test case fails.

8.1.2 What You Need to Know About Validation of Test Suites

You may have a situation where your test suite XML file does not conform to the test suite XSD file. In that case when you open the Decision Function Test window, in the Test Suite list, adjacent to the test suite name, a yellow warning triangle appears as shown in Figure 8-7.

If the test suite XML file is malformed, then the test suite name does not appear in the list of test suites in the Decision Function Test window. In addition, for an invalid dictionary , when you test the Decision Function, the following error message is displayed:

Dictionary is invalid, fix validation errors and try again.

8.1.3 What You Need to Know About Testing Linked Dictionaries

Consider a situation, where you have a base dictionary and a custom dictionary. The custom dictionary has a link to the base dictionary.

Now, navigate to the Decision Functions section of the custom dictionary. Note that the list of decision functions in the custom dictionary includes the decision functions from the linked/base dictionary. You can test the decision functions of the base dictionary from the custom dictionary.

8.1.4 What You Need to Know About Failure of Test Suites

In case your test case fails, the Results page displays the probable reasons of failure in the Comments section.

A test case can fail due to the following reasons:

The expected output specified for the test case is different from the actual output as the following:

The Comments section clearly states that there is a mismatch between the expected output and the actual output.

The test case executes, but no output is generated as the following:

You can see that the Comments section displays that the test generated no results and some more details on the probable cause.

The test case executes, but multiple outputs are generated as the following:

The Comments section displays that multiple outputs were generated on test execution along with some details on the probable cause.

The test case does not fire any rule as the following:

This can be because the asserted fact failed to activate any rule resulting in no rules getting fired. So, the Comments section indicates that this may be due to a rule modelling error, because in all probabilities, the provided input failed to match any rule condition.

8.1.5 How to Test a Decision Function Using an Oracle Business Rules Function

In the Arguments table, confirm that there are no arguments. For a test function, you cannot specify any arguments.

In the Body area, enter the test function body.

In the body of the test function you can call a decision function using assign new to call and get the return value of the decision function (in the body of the test function you create input facts, call a decision function, and validate the facts output from the decision function).

A decision function call returns a List. Thus, to test a decision function in a test function you do the following:

You create the input data as required for the decision function input arguments.

You call the decision function with the arguments you create in the test function.

8.1.6 What You Need to Know About Testing Decision Functions

You can use Oracle Business Rules Functions to test decision functions from within Rules Designer. Keep the following points in mind when using a test function:

The Test Function icon is gray if the dictionary associated with the test Oracle Business Rules Function contains any validation warnings. The TestFunction icon is only shown when the dictionary validates without warnings.

As an alternative to the example shown in Figure 8-8, you can enter the function body that is shown in Example 8-1. This function runs and shows the RL.watch.all() output. The dialog shows "Test Passed" when the grade is in the B range as shown in Figure 8-10. The dialog shows "Test Failed" when the grade asserted is not in the B range, as shown in Figure 8-11.