Thursday, April 25, 2013

Surefire maven plugging configuration for testng

The Surefire Plugin is used during the test phase of the build lifecycle to execute the unit tests of an application. once you write the test classes under test directory you can use following surefire configurations in pom.xml to run you test classes while building the source.


If you want to run all test classes which name end with TestCase


<build>  
     <plugins>  
       <plugin>  
         <artifactId>maven-surefire-plugin</artifactId>  
         <version>2.12.3</version>  
         <inherited>false</inherited>  
         <configuration>  
           <argLine>-Xms512m -Xmx1024m -XX:MaxPermSize=128m</argLine>  
           <testFailureIgnore>true</testFailureIgnore>  
           <disableXmlReport>false</disableXmlReport>  
           <parallel>false</parallel>  
           <includes>  
             <include>**/*TestCase.java</include>  
           </includes>  
         </configuration>  
       </plugin>  
     </plugins>  
   </build>  

Other option is that you can create a test suite by defining test classes or test packages in a xml file called testng.xml


<build>  
     <plugins>  
       <plugin>  
         <artifactId>maven-surefire-plugin</artifactId>  
         <version>2.12.3</version>  
         <inherited>false</inherited>  
         <configuration>  
           <argLine>-Xms512m -Xmx1024m -XX:MaxPermSize=128m</argLine>  
           <testFailureIgnore>true</testFailureIgnore>  
           <disableXmlReport>false</disableXmlReport>  
           <parallel>false</parallel>  
           <suiteXmlFiles>  
             <suiteXmlFile>src/test/resources/testng1.xml</suiteXmlFile>  
           </suiteXmlFiles>  
         </configuration>  
       </plugin>  
     </plugins>  
   </build>  

your testng.xml file should be defined as bellow. you can defined your test classes or or package to be run

<suite name="MyTestSuite" parallel="false">   
   <test name="Test1" preserve-order="true" verbose="2">   
    <classes>   
     <class name="com.test.MyTestClass1"/>  
     <class name="com.test.MyTestClass2"/>   
    </classes>   
   </test>   
  <test name="Test2" preserve-order="true" verbose="2">   
    <packages>   
     <package name="com.test.*"/>   
    </packages>   
   </test>   
  </suite>

JMS Proxy service using WSO2 ESB



WSO2 ESB is capable to communicate with JMS transport as well. In this blog post you can see how to configure a proxy service with JMS transport.

Please refer  How to enable ESB for JMS transport for ESB server configuration to work with ActiveMQ JMS Broker.

Bellow proxy service is expose via jms transport by defining the transports="jms". so deploy the proxy service in WSO2  ESB

 <proxy name="JmsProxy" transports="jms" startOnLoad="true" trace="disable">
        <target>
            <endpoint>
                <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
            </endpoint>
            <inSequence>
                <property name="OUT_ONLY" value="true"/>
                <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
                <header name="Action" value="urn:placeOrder"/>
            </inSequence>
        </target>
        <parameter name="transport.jms.ContentType">
            <rules>
                <jmsProperty>contentType</jmsProperty>
                <default>text/xml</default>
            </rules>
        </parameter>
 </proxy>  

Once you deploy the above proxy service, you can see a queue named jmsProxy is created in JMS broker. then the proxy service is listening to the  jmsProxy queue. whatever a message is put into that queue, the proxy service pick the message from the queue and send it to the endpoint definded in the proxy service. as this proxy service message is route to the SimpleStockQuoteService.

if you want to test this proxy service, you can put a soap message in to the jmsProxy queue using a JMS client or you can create another http proxy service to put a message to the jmsProxy queue.

Bellow proxy service configuration is a http proxy service which route a incomming message to jms queue.

<proxy name="StockQuoteProxyToJMSQueue" transports="http" startOnLoad="true" trace="disable">  
     <description/>  
     <target>  
       <inSequence>  
         <property name="OUT_ONLY" value="true"/>  
         <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>  
         <send>  
           <endpoint>  
             <address  
                 uri="jms:/jmsProxy?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&amp;java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&amp;java.naming.provider.url=tcp://127.0.0.1:61616&amp;transport.jms.DestinationType=queue"/>  
           </endpoint>  
         </send>  
       </inSequence>  
     </target>  
   </proxy>  

 then you can send to soap message to StockQuoteProxyToJMSQueue proxy service. then it will put your message to jmsProxy queue. so jmsProxy service pick the message form the queue and send it the actual back end service running on a axis2 server.

 you can use soapui to send the message to http proxy

http://localhost:8282/services/StockQuoteProxyToJMSQueue

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples" xmlns:xsd="http://services.samples/xsd">  
   <soapenv:Header/>  
   <soapenv:Body>  
    <ser:placeOrder>   
      <ser:order>   
       <xsd:price>20</xsd:price>    
       <xsd:quantity>1000</xsd:quantity>  
       <xsd:symbol>WSO2</xsd:symbol>  
      </ser:order>  
    </ser:placeOrder>  
   </soapenv:Body>  
 </soapenv:Envelope>  







How to send http messages to jms topic using WSO2 ESB Proxy Service


As the previous blog post How to send http messages to jms Queue using WSO2 ESB. WSO2  ESB has the capability to send messages to Queue in JMS broker. Now I am going to show you how to route the incomming message to  Topic in ActiveMQ JMS broker instead of a Queue using WSO2 ESB proxy service. That can be done easily by changing the endpoint configuration only.

Please refer How to send http messages to jms Queue using WSO2 ESB. for ESB server and ActiveMQ broker configurations for ESB to work with JMS Broker 

Bellow HTTP Proxy service is configured to route incomming message to the topic called TestTopic. Deploy the bellow proxy in WSO2 ESB


<proxy name="StockQuoteProxyToJMSTopic" transports="http" startOnLoad="true" trace="disable">  
     <description/>  
     <target>  
       <inSequence>  
         <property name="OUT_ONLY" value="true"/>  
         <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>  
         <send>  
           <endpoint>  
             <address  
                 uri="jms:/TestTopic?transport.jms.ConnectionFactoryJNDIName=TopicConnectionFactory&amp;java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&amp;java.naming.provider.url=tcp://127.0.0.1:61616&amp;transport.jms.DestinationType=topic"/>  
           </endpoint>  
         </send>  
       </inSequence>  
     </target>  
   </proxy>  

Since this is a one-way message, the property “OUT_ONLY” is set to true and “FORCE_SC_ACCEPTED” property is defined to send a 202 response to the client who invokes this proxy.

Once you send to a message to StockQuoteProxyToJMSTopic service via http transport, It will route your message to topic called TestTopic.




How to write WSO2 ESB Integration using WSO2 Test Automation Framework


Your First WSO2 ESB Integration test experience ....

This blog illustrate how to write a simple ESB Integration test class. Most of ESB Integration test is based on synapse configuration or synapse artifacts. so that try to write a test class to test proxy service deployment and undeployment. below is the synapse configuration we are going to test.


<?xml version="1.0" encoding="UTF-8"?>    
  <definitions xmlns="http://ws.apache.org/ns/synapse">    
   <proxy name="simpleProxy" transports="https http"  startOnLoad="true" trace="disable">  
    <target>    
     <inSequence>    
       <send>    
        <endpoint>  <address uri="http://localhost:9000/services/SimpleStockQuoteService" />  </endpoint>    
       </send>    
     </inSequence>    
     <outSequence>   <send />  </outSequence>    
    </target>    
   </proxy>    
  </definitions>  

above proxy service simple rout the incomming message to SimpleStockQuote service and get back the response to the client

Before writing the test case we have to make sure that there must be a ESB instance up and running. as well as another server which has a actual backend service running. Test Automation Framework look after all the preconditions which needed to run the test class successfully. Before running the test class, ESB server and axis2 server with SimpleStockQuoteService are started by framework using the testng listeners. and populate the users defined in userlist.csv(tenantlist.csv) files which are located in resources directory.


within the test class, we should focus on the test scenario only. you can start writing your tests in the following location according to your esb server version :

platform/branches/x.x.x/products/esb/x.x.x/modules/integration/tests

eg:
all the test classes are placed in one module called tests and found under integration module.

Then create a proper packaging and add a java class extending ESBIntegrationTest. then put the synapse configuration file in artifact/ESB under resources folder.

package org.wso2.carbon.esb.proxyservice.test.passThroughProxy;   
  import org.apache.axiom.om.OMElement;   
  import org.testng.annotations.AfterClass;   
  import org.testng.annotations.BeforeClass;   
  import org.testng.annotations.Test;   
  import org.wso2.carbon.esb.ESBIntegrationTest;   
  import javax.xml.namespace.QName;   
  import static org.testng.Assert.assertEquals;   
    
 public class ProxyServiceDeploymentTestCase extends ESBIntegrationTest {   
   @BeforeClass(alwaysRun = true)   
   public void deployService() throws Exception {   
    /* initializing server configuration with the user id 2*/   
    super.init(2);   
    /* deploying the artifact defined in the proxy_service.xml */   
    loadESBConfigurationFromClasspath( "/artifacts/ESB/proxyconfig/proxy/passThroughProxy/proxy_service.xml");   
   }   
   
   @Test(groups = "wso2.esb", description = "Pass through proxy service invocation test")   
   public void testPassThroughProxy() throws Exception {   
    /* invoking the proxy service and getting the response using a service client */   
    OMElement response = axis2Client.sendSimpleStockQuoteRequest(getProxyServiceURL("StockQuoteProxy"), null, "WSO2");   
    /* response assertions */   
    String symbol = response.getFirstElement().getFirstChildWithName(new QName("http://services.samples/xsd", "symbol"))  .getText();   
    assertEquals(symbol, "WSO2", "Fault: value 'symbol' mismatched");   
   }   
   
   @AfterClass(alwaysRun = true)   
   public void unDeployService() throws Exception {   
    /* undeploying deployed artifact */   
    super.cleanup();   
   }   
  }  


ESBIntegrationTest class abstract most of useful method for esb testing and once it is inherited it will ease your work by providing important features.

init(userid) will build the esb server configuration such as backend url, service url, etc.. and authenticate user which is defined in userlist.csv with the server and it is called under @BeforeClass(). then it will runs before all the test methods.

loadESBConfigurationFromClasspath("/artifacts/ESB/$path/synapse_config.xml") will deployed the artifact defined in the file(proxy, endpoints, sequence, message store, etc..) using admin services. it go through the configuration and deployed artifact one by one. if the same artifact name is already in the system, it is deleted and new one is deployed.

getProxyServiceURL("StockQuoteProxy") will returns the proxy service url http

cleanup() will undeploye the deployed artifact and it is called under @AfterClass(). then it will runs after all the test methods.

Above flow will executes your test scenario clearly and if any exception thrown an assertion failure happens, it will indicate as a test failure.

as above we can write lot of test cases and there are more other utility methods provided by automation framework.

to run the test class you have to add your test classes in testng.xml( can be found under resources directory)

 <test name="first-test" preserve-order="true" verbose="2">   
   <classes>   
    <class name="org.wso2.carbon.esb.proxyservice.test.passThroughProxy.ProxyServiceDeploymentTestCase"/>   
   </classes>   
  </test> 

or you can add the all classes to run by adding package name
<test name="first-test" preserve-order="true" verbose="2">   
   <packages>   
    <package name="org.wso2.carbon.esb.proxyservice.test.passThroughProxy"/>   
   </packages>   
  </test>  

Then issuing mvn clean install execute your test classes and generated the reports in target/surefire-reports

Running Test on Different Environments....
Once you write a test case you can run that test case in different environments. Just need to change the property file called automation.properties (can be found under resources directory) and executing.  

Executing test on integration Environment as a user
By default test runs on the integration environment(while building the product from source) as a user . Setting builder.enable=true will handle the ESB and axis2 servers startups.
 stratos.test=false   
 #execution.environment = integration|platform|stratos   
 execution.environment=integration   
 #execution.mode = user|tenant|all   
 execution.mode=user   
 port.enable=true   
 carbon.web.context.enable=false   
 builder.enable=true 


Executing as a tenant
if you want to run the test as a tenant. setting below will execute the test as tenant.

 execution.mode=tenant   

Executing test on Platform Environment
if you want to run the test against the ESB instance already up and running, you can do it by changing the below properties as mentioned.

 execution.environment=platform  
 builder.enable=false  

once you change the execution environment to platform, you need to change the server configurations too.

 esb.host.name=192.168.1.10   
 esb.http.port=9763   
 esb.https.port=9443   
 esb.nhttp.port=8280   
 esb.nhttps.port=8243   
 #esb.webContext.root  

when execution environment is changed to platform, we host the actual backend services(which were available in axis2 server for integration environment) in WSO2 Application server. so AS configurations is also need to configure and server must be up and running.

 as.host.name=localhost   
 as.http.port=9763   
 as.https.port=9443   
 #as.webContext.root  

Executing test on stratos or cloud
if you want to run your test class against stratos, change setting as below. 

 stratos.test=true   
 execution.environment=stratos   
 execution.mode=tenant   
 cluster.enable=true  
 #Stratos server details   
 app.service.host.name=manager.appserver.stratoslive.wso2.com, appserver.stratoslive.wso2.com   
 esb.service.host.name=manager.esb.stratoslive.wso2.com,esb.stratoslive.wso2.com    
 manager.service.host.name=stratoslive.wso2.com