Tuesday 31 March 2015

Continuous Integration with Jenkins for Test Automation.


Hello, in this blog I would like to share my knowledge and understanding on Continuous integration for test automation using Jenkins.

As a test automation engineer we need to understand about using the continuous integration methodology well, as firms are moving towards agile development the rate of code check-ins to the source code management are more.

With every code check-in, the probability of breaking the functionality of a system is considerable, this can be checked and prevented by using continuous  integration. If we test the system functionality using fully automated unit and integration tests soon after a code check-in happens, then the possibility of missing a code flaw into the system will be very low and if the code breaks during the build soon after the check-in the developer or the team can take a decision on the next steps, usually it will be the code roll-back.

In brief this is how the continuous integration works in real time.

  • A central repository for source code management (SVN, Git)
  • Test automation suite consisting of both integration tests and functional tests.
  • A build server on which the Jenkins, code builder(Ant/Maven) and the Test runner (Junit/TestNG/MTR).
  • Jenkins is configured to build the latest code from the repository and as a post build action run the automated tests.
  • So whenever a code check-in happens, Jenkins execute the above step, else Jenkins can also be configured to run on a daily basis (nightly build), where the build action happens only once in a day during night.
  • Jenkins sends an email notifications as well to the respective people after the test run is completed.


As automation testers we need to achieve the following to be part of the Continuous integration process,

  • Automate all our test cases that includes your Functional, Integration and UAT cases, use selenium/SoapUI/ or your customized automation tool.
  • Use respective test runners to trigger the test cases automatically, via command line, I use ANT to trigger my REST api test suite.
  • Identify a way to generate user friendly test reports, (most of the existing test framework has their inbuilt test report generator), I use TestNG which gives an Html report.
  • Collect all the dependencies like JAR files, DLLs etc.. and place them in one place for reference.
  • Design your test suite in such a way that you put all your automation code, reference libraries, test runner files etc.. into one directory, that can be moved to any system without difficulty and cab be run with no efforts of set-up.


Setup Jenkins server as below,

  • Install Jenkins as windows service or to run manually download 'Jenkins.war' from here.
  • To start Jenkins server, browse to the directory where you've downloaded 'Jenkins.war' via command line.
  • Now run java -jar jenkins.war --httpPort=8989 command, this will start Jenkins locally on port 8989.
  • Goto your favourite web-browser and explore to localhost:8989 in the URL tab, this will open the Jenkins dashboard.
  • Take your time to explore different options, links and other tabs on this dashboard.


Setup Jenkins to run automated Test run as below,

Create a new item(jenkins Job) from the home page of Jenkins dashboard.
Click on 'New item' and then give a project name(item name) and select 'Freestyle project', click 'OK'



  • Give a project description for this item, this will be helpful if future if you are handling with multiple projects at a time.
  • Select 'None' in the source code management option.

  • Do not select anything in 'Build Triggers'.
  • Select 'Invoke Ant' option in 'Build'.
  • Save these now.

 


  • After saving goto the home page of this dashboard again.
  • Click on 'Manage Jenkins' and select 'Configure system'
  • Set the environment path for the JAVA class and Ant.
  • Set the JDK path for JAVA_HOME, as shown below.


















  • Set the ANT bin path as shown below.



Now we are done with our Jenkins Set-up.


Set-up the automation code to be run after every build.

  • when you run the Jenkins server on your machine, it will create a local workspace for running the Jenkins jobs/projects.
  • Now explore that directory and see that there is a directory created for your newly created jenkins project the directory structure would be 'c:\program files\jenkins\jobs\your-project\workspace\'
  • You need to place your bundled automation project right in this path which I talked about in the very beginning.
  • In my case as seen above, I've used ANT to trigger my tests, Jenkins trigger ANT and ANT will use my 'build.xml' file available in the workspace where my entire project is bundled, to run the tests.


We are done with our Jenkins setup to run our automated tests.... CONGRATS !!!


Now Goto the main Dashboard page where you can see your project in the list of available items.


To run this item, click on the icon with green arrow seen at the end.
Now your test will run and the console output will be stored in Jenkins against the build number.



  • To explore more on customizing your test runs, email notifications see Jenkins website.
  • Usually, the test automation is run after the actual code build happens, so Jenkins allows you to trigger this item as a post-build action, so that every time there is a code change in the application and check-in happens, the code build happens (this is another separate build item) and as a post-build action our above set up item will be executed.

*********************************************************************************

Monday 9 March 2015

REST API test automation using Java.

Hello...
I would like to share my idea of automating RESTful API testing without using an automation tool.
This is quite interesting and challenging and has a very steep learning curve if took seriously, you can save thousands of Dollars to your organisations by developing your own Test-Automation framework for RESTful API testing.

The beautiful thing of this framework is, it is easy to maintain and can be integrated with all your continuous integration servers like Jenkins. The tests can be run on a nightly build and the TestNG report can be emailed to the concerned group of IDs.

There are many free API test libraries that would help you to automate your tests, but over a time the limitations stops your automation and you have to go for an alternative.
-----------------------------------------------------------------------------------------------------------

Things required to start:

1) Your favourite Java IDE, (I use Eclipse).
2) Apache Http Library (click here to download).
3) Apache Excel POI (click here to download).
4) TestNG (click here to download), please download 'Ant/Maven', version of TestNG not the eclipse version.
5) ANT ( click here to download), this is for build+run of your Java classes.
6) Gson (click here to download), to handle/manipulate JSON response.

People who are good with Junit can replace TestNG with it. But I prefer TestNG because of its features.
It generates a beautiful HTML report at the end which gives an detailed info of tests passes/failed and skipped.


Below are the different Java classes each performing a unique task in automation.

1) BaseTasking.java  : This class does the following,

  •     Data supply.
  •     Test Control.
  •     API Url creation dynamically.
  •     REST API calling.
  •     Response reading and formatting.
  •     Http connection managing.


2) DataReader.java  : This is class reads the input parameters from a spread sheet and passes it to the data provider in the 'BaseTasking.java' class.

3) TestCollection.java  : This class has a collection of tests.

4) RestulValidator.java   : This class contains the logic for validating the results from an API call.

5) Testng.xml  : This xml file will have the collection of test classes that are to be executed.

6) Build.xml : This xml file is used to compile and run the test-suite using Ant.
-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------

1) BaseTasking.java

package myTest;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.util.Properties;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.testng.Reporter;
import org.testng.SkipException;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;


public class BaseTestFactors {

static DefaultHttpClient httpClient;
BufferedReader br=null;
HttpResponse response=null;
String URL=null;
String AuthenticationKey=null;

String TCNUM=null;
String Environment=null;
String MethodName=null;
String Stores=null;
String Products=null;
String Parameters=null;
String ExpectedJson=null;
public static String Execute=null;
public static String TestDescription="No description available for this test case now.. will be added soon";

@BeforeClass
public static void SetUpSuite(){
}

// every @Test method will call this data provider, and based on the Test method name they'll get their data.
@DataProvider(name = "MyData")
public static Object[][] dataProvider(Method meth) throws IOException {
 
System.out.println("inside the dataprovider class");
Properties prop = new Properties();
InputStream input = null;
int SheetNumber=0, TestNumber=0;
DataRead E=new DataRead();

try {

input = new FileInputStream("ReferenceFiles/TestDescription.properties");
prop.load(input);

TestDescription=(prop.getProperty(meth.getName().toString().trim()));
input = new FileInputStream("ReferenceFiles/Environment.properties");
prop.load(input);
String TestGroup=(prop.getProperty((meth.getName().toString()).substring(0,4)).trim());
String TestNumberString=((meth.getName().toString()).substring(5,7)).trim();

System.out.println("TCNUM "+TestNumberString);
TestNumber=Integer.parseInt(TestNumberString);
System.out.println(TestNumber);
SheetNumber=Integer.parseInt(TestGroup);

} catch (IOException ex) {
ex.printStackTrace();
}
catch (NullPointerException e) {
System.out.println("caught an exception while reading properties file");
}

String[][] StrData=E.ReadEXCEL(SheetNumber);
  int Row=Excelread.RowSize;
  int Col=Excelread.ColumSize;
  Object[][] TempData = new Object[Row][Col];
  Object[][] data= new Object[1][Col];
  
   for(int x=0;x<Row;x++){
  for(int y=0;y<Col;y++){
  TempData[x][y]=StrData[x][y];
  }
  }
  data[0]= TempData[(TestNumber-1)];
return  data;
}

public void ExecutionCheck(){
if(Execute.equalsIgnoreCase("N"))
throw new SkipException("Skipping - This Test case was aksed to be SKIPPED ");
}

@SuppressWarnings("deprecation")
public String[] MyTestGerneral() throws JSONException{
System.out.println("InsideTest-"+TCNUM);
Reporter.log(TCNUM+":- "+TestDescription);
String CompleteURL=null;
String ValidationResults[]= new String[2];

Properties prop = new Properties();
InputStream input = null;

try {// Setter for TestEnvironment IP/FQDN

input = new FileInputStream("ReferenceFiles/Environment.properties");
prop.load(input);
String PropRead[]=(prop.getProperty(Environment).split(","));
System.out.println("property read"+PropRead[0]+"  "+PropRead[1]);
URL=PropRead[0].toString();
AuthenticationKey=PropRead[1].toString();
CompleteURL=getURL();
System.out.println(CompleteURL);

} catch (IOException ex) {
ex.printStackTrace();
}

try {// Make HTTP Call
org.apache.http.Header[] headers=null;
String headerMessage= null;
String JExpected= ExpectedJson;
String JActual="[{\"NoJSON\":\"No\"}]";

System.out.println("before http call");
HttpResponse Temp_response=RESTCall(CompleteURL);
System.out.println(Temp_response.toString());
if (Temp_response != null){

System.out.println("after http call");
br = new BufferedReader(new InputStreamReader(Temp_response.getEntity().getContent()));

int actualRespCode=Temp_response.getStatusLine().getStatusCode();

if(actualRespCode != 200){

try{
headers = Temp_response.getHeaders("CustomMessage");
headerMessage= headers[0].toString();
}
catch(ArrayIndexOutOfBoundsException e)
{
headerMessage="NO Error Message in the response";
}
 }
 
if(actualRespCode == 200){
JActual =GETJSONRESULT(br);
}
ResultValidator ResVal= new ResultValidator();
System.out.println("before validation");
ValidationResults=ResVal.Validate(TCNUM,JExpected.toString(),JActual.toString(),headerMessage,actualRespCode);

httpClient.getConnectionManager().shutdown();
}

} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

return ValidationResults;
}// end of myTestGeneral method

/*Method to the get the URL*/
public String getURL(){
int option=0;
String CompleteURL=null;
if(MethodName.equalsIgnoreCase("SS1-V1")) option=1;
else if(MethodName.equalsIgnoreCase("SS2-V1")) option=2;
else if(MethodName.equalsIgnoreCase("SS3-V1")) option=3;
else if(MethodName.equalsIgnoreCase("SS4-V1")) option=4;
else if(MethodName.equalsIgnoreCase("SS5-V1")) option=5;
else if(MethodName.equalsIgnoreCase("SS6-V1")) option=6;
else if(MethodName.equalsIgnoreCase("SS7-V1")) option=7;
else if(MethodName.equalsIgnoreCase("SS8-V1")) option=8;
else if(MethodName.equalsIgnoreCase("SS1-V2")) option=9;
else if(MethodName.equalsIgnoreCase("SS2-V2")) option=10;
else if(MethodName.equalsIgnoreCase("CRACK")) option=11;
else if(MethodName.equalsIgnoreCase("ROOT")) option=12;
else if(MethodName.equalsIgnoreCase("ACURCY")) option=13;
else if(MethodName.equalsIgnoreCase("ADJOIN")) option=14;

switch(option){
case 1:
CompleteURL="http://"+URL+"/v1/Stock/method1/"+Stores+"?"+"productIds="+Products+"&"+Parameters;
break;

case 2:
CompleteURL="http://"+URL+"/v1/stock/"+"method2/"+Products+"?"+"locationids="+Stores+"&"+Parameters;
break;

case 3:
CompleteURL="http://"+URL+"/v1/stock/"+"method3/"+Stores+"?"+"productIds="+Products+"&"+Parameters;
break;

case 4:
CompleteURL="http://"+URL+"/v1/Stock/"+"method4/"+Stores+"?"+"productIds="+Products+"&"+Parameters;
break;

case 5:
CompleteURL="http://"+URL+"/v1/stock/"+"method5/"+Products+"?"+"locationids="+Stores+"&"+Parameters;
break;

case 6:
CompleteURL="http://"+URL+"/v1/method6/all/"+Products+"/"+Stores+"?business=Group";
break;

case 7:
CompleteURL="http://"+URL+"/v1/stockcr/method7/"+Stores+"?productId="+Products+"&business=Group";
break;

case 8:
CompleteURL="http://"+URL+"/v1/stockcr/method8/"+Products+"?locationId="+Stores+"&business=Group";
break;

case 9:
CompleteURL="http://"+URL+"/v2/stock/method9?productIds="+Products+"&locationIds="+Stores;
break;

case 10:
CompleteURL="http://"+URL+"/v2/stock/method10?productIds="+Products+"&locationIds="+Stores;
break;

case 11:

  CompleteURL="http://"+URL+"/v2/stock/method11?productIds="+Products+"&locationIds="+Stores+"&business=Group";
  break;
 
case 12:

CompleteURL="http://"+URL+"/v2/stock/method12/"+Stores+"productIds="+Products;
break;

case 13:

CompleteURL="http://"+URL+"/v2/stock/method13?productIds="+Products+"&locationIds="+Stores;
break;

case 14:

CompleteURL="http://"+URL+"/v1/stockcr/method14/"+Stores+"?business=Group";
break;

case 0:
CompleteURL=null;
break;
}
return CompleteURL;
}

/*Method to call the rest method*/
public HttpResponse RESTCall(String URLData) throws IOException{
HttpGet getRequest = new HttpGet(URLData);
getRequest.addHeader("accept", "application/json");
getRequest.addHeader("Authorization", AuthenticationKey);

httpClient = new DefaultHttpClient();
response = httpClient.execute(getRequest);

  return response;
}

/*Method to return the JSON Array result*/
public String GETJSONRESULT(BufferedReader Buff) throws IOException, JSONException{
String output=null;
String JasonResponse="";
System.out.println("Output from Server .... \n");
while ((output = Buff.readLine()) != null) {
System.out.println(output);
JasonResponse=JasonResponse+output.toString();
}
System.out.println(JasonResponse);
//JSONArray temp1 = new JSONArray(JasonResponse);

return JasonResponse;

}

public String[] MyPOSTModule() throws JSONException{// Method for POSTing the JSON data.
System.out.println("InsideTest-"+TCNUM);
Reporter.log(TCNUM+":- "+TestDescription);
String CompleteURL=null;
String ValidationResults[]= new String[2];
ValidationResults[0]="PASS";ValidationResults[1]="Looks SUccessfull";
Properties prop = new Properties();
InputStream input = null;

try {// Setter for Environment Variable

input = new FileInputStream("ReferenceFiles/Environment.properties");
prop.load(input);
String PropRead[]=(prop.getProperty(Environment).split(","));
System.out.println("property read"+PropRead[0]+"  "+PropRead[1]);
URL=PropRead[0].toString();
AuthenticationKey=PropRead[1].toString();
CompleteURL=getURL();
System.out.println(CompleteURL);
} catch (IOException ex) {
ex.printStackTrace();
}
try {

DefaultHttpClient httpClient = new DefaultHttpClient();
FileInputStream inStrm = new FileInputStream("ReferenceFiles\\PostMethodJSON\\"+TCNUM+".txt");
byte[] fileData = new byte[input.available()];
inStrm.read(fileData);
inStrm.close();
String JSONData= new String(fileData, "UTF-8");
HttpPost postRequest = new HttpPost(CompleteURL);
postRequest.addHeader("Authorization", AuthenticationKey);

StringEntity StockJSON = new StringEntity(JSONData);
StockJSON.setContentType("application/json");
postRequest.setEntity(StockJSON);

HttpResponse response = httpClient.execute(postRequest);

if (response.getStatusLine().getStatusCode() != 200) {
ValidationResults[0]="FAIL";

//throw new RuntimeException("Failed : HTTP error code : "+ response.getStatusLine().getStatusCode());
}

BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));
String output="", TempOutput="";
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
TempOutput=TempOutput+output;
}
System.out.println(output);
ValidationResults[1]="Could not post the message - Please check manually: "+TempOutput;

httpClient.getConnectionManager().shutdown();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

return ValidationResults;
}

}



-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------

2) DataReader.java


package myTest;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.*;

public class DataRead{

public static int RowSize,ColumSize;
public  String[][]ReadEXCEL(int sheetNum) throws IOException{
String fileName = "ReferenceFiles\\DataSheet.xls";
FileInputStream myInput = new FileInputStream(fileName);
POIFSFileSystem myFileSystem = new POIFSFileSystem(myInput);
HSSFWorkbook myWorkBook = new HSSFWorkbook(myFileSystem);
HSSFSheet mySheet = myWorkBook.getSheetAt(sheetNum);

RowSize= (mySheet.getLastRowNum());
HSSFRow myRow = mySheet.getRow(0);
ColumSize=(myRow.getLastCellNum());
String ExcelData[][]=new String[RowSize][ColumSize];

try{

for(int i=1;i<=RowSize;i++){
myRow= mySheet.getRow(i);
for(int j=0;j<ColumSize;j++){
HSSFCell C2 = myRow.getCell(j);
if(C2 !=null)
ExcelData[i-1][j]=C2.toString();
else
ExcelData[i-1][j]="";
}
}

}catch(NullPointerException e){
e.printStackTrace();
}


myInput.close();
return ExcelData;
}

}

-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------
3) TestCollection.java

package myTest;
import java.io.IOException;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.json.JSONException;

public class TestCollection extends BaseTasking {

@BeforeMethod
public void SetUpTest(){
}
@Test(dataProvider="MyData",enabled=true)//Test-001
public void TC01_01(String TcNumber,String Environment,String MethodName,String Parameter1,
String Parameter1, String OtherParameters,String Execute) throws JSONException, IOException{

super.TCNUM= TcNumber;super.Environment=Environment.trim();super.MethodName=MethodName.trim();super.Parameter1=parameter1.trim();super.Parameter2=Parameter2.trim();super.OtherParameters=OtherParameters.trim();super.Execute=Execute;
ExecutionCheck();
String Status[]=CallHttpMethod();
AssertJUnit.assertTrue(Status[1],Status[0].equalsIgnoreCase("PASS"));
}

@Test(dataProvider="MyData",enabled=true)//Test-002
public void TC01_02(String TcNumber,String Environment,String MethodName,String Parameter1,
String Parameter1, String OtherParameters,String Execute) throws JSONException, IOException{

super.TCNUM= TcNumber;super.Environment=Environment.trim();super.MethodName=MethodName.trim();super.Parameter1=parameter1.trim();super.Parameter2=Parameter2.trim();super.OtherParameters=OtherParameters.trim();super.Execute=Execute;
ExecutionCheck();
String Status[]=CallHttpMethod();
AssertJUnit.assertTrue(Status[1],Status[0].equalsIgnoreCase("PASS"));
}

@Test(dataProvider="MyData",enabled=true)//Test-003
public void TC01_03(String TcNumber,String Environment,String MethodName,String Parameter1,
String Parameter1, String OtherParameters,String Execute) throws JSONException, IOException{

super.TCNUM= TcNumber;super.Environment=Environment.trim();super.MethodName=MethodName.trim();super.Parameter1=parameter1.trim();super.Parameter2=Parameter2.trim();super.OtherParameters=OtherParameters.trim();super.Execute=Execute;
ExecutionCheck();
String Status[]=CallHttpMethod();
AssertJUnit.assertTrue(Status[1],Status[0].equalsIgnoreCase("PASS"));
}

@Test(dataProvider="MyData",enabled=true)//Test-004
public void TC01_04(String TcNumber,String Environment,String MethodName,String Parameter1,
String Parameter1, String OtherParameters,String Execute) throws JSONException, IOException{

super.TCNUM= TcNumber;super.Environment=Environment.trim();super.MethodName=MethodName.trim();super.Parameter1=parameter1.trim();super.Parameter2=Parameter2.trim();super.OtherParameters=OtherParameters.trim();super.Execute=Execute;
ExecutionCheck();
String Status[]=CallHttpMethod();
AssertJUnit.assertTrue(Status[1],Status[0].equalsIgnoreCase("PASS"));
}

@AfterMethod
public void TearDown() {
System.out.println("************************************End of Test"+TCNUM+"************************************\n\n");
}

@AfterClass
public static void TearDownTest(){
System.out.println("Test Complete");
}
}

-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------
4) RestulValidator.java

package myTest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class ResultValidator {

public String[] Validate(String testcaseNum, String ExpectedJson,String ActualJson,
  String HeaderMessage, int ActualRespCode ) throws JSONException{

String Flag="Fail";
String ReportMessage="";
switch(testcaseNum){ 


case TC01_01:

/*   
Logic for validating your Actual results against the expected results.
use GSON to extract JSON value and use it to compare against the expected values.
use flags and indicators to set the validation status to 'Pass' or 'Fail'
 
do not use assertions, instead use if-else to compare the results.
finally return a 1D string array with
Str[0] having the value 'Pass'/'Fail'--> Flag
Str[1] having the error message detailing why the validation failed--> ReportMessage
 
*/
break;
}

 
 case 2:
{
/*   
Logic for validating your Actual results against the expected results.
use GSON to extract JSON value and use it to compare against the expected values.
use flags and indicators to set the validation status to 'Pass' or 'Fail'
 
do not use assertions, instead use if-else to compare the results.
finally return a 1D string array with
Str[0] having the value 'Pass'/'Fail'--> Flag
Str[1] having the error message detailing why the validation failed--> ReportMessage
 
*/
break;
}

 case 3:
{ /*   
Logic for validating your Actual results against the expected results.
use GSON to extract JSON value and use it to compare against the expected values.
use flags and indicators to set the validation status to 'Pass' or 'Fail'
 
do not use assertions, instead use if-else to compare the results.
finally return a 1D string array with
Str[0] having the value 'Pass'/'Fail'--> Flag
Str[1] having the error message detailing why the validation failed--> ReportMessage
 
*/
break;
}



case 4:
{/*   
Logic for validating your Actual results against the expected results.
use GSON to extract JSON value and use it to compare against the expected values.
use flags and indicators to set the validation status to 'Pass' or 'Fail'
 
do not use assertions, instead use if-else to compare the results.
finally return a 1D string array with
Str[0] having the value 'Pass'/'Fail'--> Flag
Str[1] having the error message detailing why the validation failed--> ReportMessage
 
*/
break;
}// End of Group-4

default:
{
System.out.println("invalid Test case Number");
}

}//End of Switch

Flags[0]=Flag;
Flags[1]=ReportMessage;

return  Flags;
}

}


-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------
4) Testng.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="StockRegression" parallel="none">
 <test name="Test">
   <classes>
   <class name="myTest.TestCollection"/>
</classes>
 </test>
 </suite>


-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------


Run this 'Testng.xml' using the TestNG run command via command-line.
you'll get an html report once all the tests are run.