"I never make stupid mistakes. Only very, very clever ones." - John Peel

Unit Test Automator for Oracle SOA Suite

Testing a Complex Business process could get more complex than the Business Process itself. The Code Quality challenges are depicted below.

Oracle SOA Code Quality Challenges.

While Automated Build Tools like Jenkins and Hudson ensure that the code check-ins are devoid of any compilation issues. We can also ensure that the Check-ins are not breaking the existing functionality, with the approach discussed below.

Oracle SOA Unit Testing ‐ As Is Approach

Oracle SOA Suite provides customized form of JUnit Test Case functionality. The testing Methodology is as below.

Oracle SOA Unit Testing ‐ As automated nightly builds.

The Process of Unit testing can be automated as well, so that everyday morning we know we have a report on Code Quality, just like Build automation. The approach is depicted as below.

Oracle SOA Code Quality Framework.

Henceforth, the above approach, resolves the Code Quality challenges as depicted below.

Oracle SOA Code Quality Resolution.

Let us now focus on implementing the approach.

Execution Step 1 : Generate Unit Test Cases.

The Unit Test Case generation involves the following steps.

Execution Step 2: Execute the Test Case as Automated Build.

The Ant Task executes the Test Case for the BPEL Project passed.

<!-- test with composite tests --> 
	<target name="unit-test-composite" 
		description="test the composite, via sca-test">
		<taskdef resource="net/sf/antcontrib/antlib.xml" />
		<echo>Running sca-testing for ${composite.name} against ${wls.mgd.server.url}</echo>
		<!-- api expects a file - so we create one on demand -->
		<property name="tmp.jndi.properties" value="${basedir}/tmp-jndi.properties"/>
		<echo file="${tmp.jndi.properties}">
		<delete file="${test.results.dir}/${testsuite.name}/antRun-TestFwk"/>
		<ant antfile="${oracle.home}/bin/ant-sca-test.xml"
			target="test" inheritall="false">
			<!-- connection information -->   
			<property name="oracle.home" value="${oracle.home}"/>
			<property name="java.passed.home" value="${java.home}"/>
			<!-- name of the composite -->
			<property name="scatest.input" value="${composite.name}"/>
			<!-- name of the testsuite -->
			<property name="scatestsuite.input" value="${testsuite.name}"/>
			<!-- api is bad, hence default ones -->
			<property name="jndi.properties.input" value="${tmp.jndi.properties}"/>
			<!-- result dir -->
			<property name="scatest.result" value="${test.results.dir}"/>
			<!-- partition name -->
			<property name="scatest.partition" value="${soa.partition.name}"/>       
		<echo>Results written to: ${test.results.dir}</echo>
		<!-- clean up beforehand -->	
		<delete file="${tmp.jndi.properties}" />
			<echo>In <finally>.</echo>
			<path id="class.path">
				<fileset dir="${jars.directory}">
					<include name="**/*.jar" />
			<java classname="com.tester.UnitTestCaseReporter">
				<sysproperty key="TesterPropertiesFile" value="${tester.properties.location}"/>
				<arg line="-e ${unit.testenv} -p ${composite.name} -f ${test.results.dir}/antRun-TestFwk.xml -o ${test.results.dir}"/>
				<classpath refid="class.path" />

The java.naming.provider.url will be of the format t3://host:port/soa-infra and java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory The Ant Task can be configured to execute from Jenkins, scheduled as per needs.

Execution Step 3 : Generate Test Report.

The Ant Task generates the report. It has few limitaitons, like the Assert Comparison feature from the product has limited options. In case we want to add custom Assertions and override the standard comparison, we can generate a similar report by accessing the Audit trail of the Composite. We can also add more feaures like direct access link to the Composite Instance Flow and Flow trace for easy analysis and debugging.

The XSL file transforms the above report to HTML with simple XSL. The HTML file can be linked to the Jenkins Build Result.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:test="http://xmlns.oracle.com/sca/2006/test">
  <xsl:template match="/">
<link rel="stylesheet" type="text/css" href="./css/tablestyle.css" />
	  <h1> Test Report</h1>
	  <xsl:for-each select="/test:testRunResults/test:testSuite/test:testResult">
			<h2><span><xsl:value-of select="concat( ./@suiteName , ' Scenario : ' , ./@testName )"/></span></h2>
			<h6 id="HEADLINEOUTCOME">  Test Outcome : 
				<a target="_blank" href="{./test:compositeLink[1]}">
					<xsl:value-of select="./@outcome"/>
			<table id="hor-zebra">
                  <th scope="col">Component Wire</th>
                  <th scope="col">Assertion Outcome</th>
			<!--For Value-->
			<xsl:for-each select="./test:wireActionResults">
				<xsl:variable name="css-class">
					  <xsl:when test="position() mod 2 = 0">even</xsl:when>
                  <tr  align="Justify" class="{$css-class}">
                      <xsl:value-of select="./@wireSource"/>
					<xsl:text disable-output-escaping="yes"><![CDATA[<button onclick="window.open('./mergely/compare/compare.html?actual=../../]]></xsl:text> 
					<xsl:value-of select="./@actualFile"/> 
					<xsl:text disable-output-escaping="yes"><![CDATA[&expected=../../]]></xsl:text> 
					<xsl:value-of select="./@expectedFile"/> 
					<xsl:text disable-output-escaping="yes">');"><![CDATA[<code>]]></xsl:text> 
					<xsl:value-of select="./test:assertionOutcome/@outcome"/>
					<xsl:text disable-output-escaping="yes"><![CDATA[</code></button>]]></xsl:text>