QA (eng)

Test Framework build 1.0

So, my latest and greatest framework build is ready (available at BickBucket, I could share the access, but it will be no core test methods, cause they came from my work and I can’t share them). This is a link to the overall description of the very first version of it. Framework available for every QA in my company and instructions, manuals, key method descriptions and examples provided, for example:

  • Which method validates that alerts and warnings exists (with expected message) and how to close them.
  • Which one method hides/shows grid columns
  • Which one method checks special characters/too long value/empty value input into the text fields
  • Which method and how add/validates date or number fields input
  • Which one method opens row menu
  • Which one validates that value exists in the grid
  • And tens of others

I successfully made TeamCity project to run test suites for some of our components and every QA could create test and upload them to the test library:

12.png

Some metrics

  • Total test run time for 2 browsers on 2 URLs for ready-to-test components takes about 22 minutes.
  • It takes about 25 minutes to create 100% working brand new component Test Suite for the simplest one – System Parameters:
    • Create new parameter
    • Check validations while creating parameter
    • Search for parameter
    • Edit parameter
    • Inactivate/Activate Parameter
    • Check how standard grid components works – Sort, Pagination, Column visibility

Important updates

  • Apache ANT excluded from the project and changed to Maven (I spent about 15 minutes to do that), I also tried Gradle, but it was too complicated for my pretty small framework and, from my point of view, InteliJ Idea is much better then Eclipse IDE to work with it (cause of debug and etc.).
  • XSLT report excluded cause ExtentReport is much better one for today (see my previous post).

I could not show any videos because I’m using framework with our development server, иге I also made a small demo for a public mortgage calculator test:

 

Some useful moments and code listening

Validate JS Errors

To validate if there are JS script errors on a page – just ask your developers to catch them by intercepting the window.onerrorevent:


window.onerror=function(msg){
$(“body”).attr(“JSError”,msg);
}

Then just use command assertElementNotPresent with a target of //body[@JSError].

Selectors for Selenium

If you are searching for a selectors guide for beginners, I found this one very helpful:

http://www.seleniumeasy.com/selenium-tutorials/css-selectors-tutorial-for-selenium-with-examples

Examples

And here are some code examples (you could find some related code for utilities there – http://software-testing-tutorials-automation.blogspot.com):

MortgageNegativeMinus.java

package solution.testSuite.Demo;
import static org.testng.Assert.assertEquals;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.ITestResult;
import org.testng.SkipException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.asserts.SoftAssert;
import com.relevantcodes.extentreports.LogStatus;
import eccentex.AppTester.driver.SeleniumWebDriver;
import eccentex.AppTester.helper.Common;
import eccentex.AppTester.helper.Helpers;
import eccentex.AppTester.utility.Read_XLS;
import eccentex.AppTester.utility.SuiteUtility;
import eccentex.TestSuite.Base.SuiteBase;

//SuiteLoginCaseOne Class Inherits From SuiteOpenSolutionBase Class.
//So, SuiteLoginCaseOne Class Is Child Class Of SuiteOpenSolutionBase Class And SuiteBase Class.

public class MortgageNegativeMinus extends SuiteDemo{
Read_XLS filePath = null;
String sheetName = null;
String testCaseName = null;
String toRunColumnNameTestCase = null;
String toRunColumnNameTestData = null;
String testDataToRun[]=null;
static boolean testCasePass=true;
static int dataSet=-1;
static boolean testSkip=false;
SoftAssert s_assert =null;
private Helpers helpers;
public static String siteURL;
public static String testBrowser;
public static SeleniumWebDriver seleniumWebDriver;

@BeforeTest
public void checkCaseToRun() throws IOException{
//get current test case name
testCaseName = this.getClass().getSimpleName();
//Called init() function from SuiteBase class to Initialize .xls Files
init();

extentTest = extentReport.startTest(testCaseName);
extentTest.log(LogStatus.INFO, testCaseName + ” configuration started”);
Add_Log.info(testCaseName + ” configuration started”);

//To set SuiteLogin.xls file’s path In filePath Variable.
filePath = TestCaseListExcel;
//sheetName to check CaseToRun flag against test case.
sheetName = “TestCasesList”;
//Name of column In TestCasesList Excel sheet.
toRunColumnNameTestCase = “CaseToRun”;
//Name of column In Test Case Data sheets.
toRunColumnNameTestData = “DataToRun”;
//To retrieve DataToRun flags of all data set lines from related test data sheet.
testDataToRun = runOrSkipCase(filePath, testCaseName, sheetName, toRunColumnNameTestCase, toRunColumnNameTestData);
}

//Accepts 4 column’s String data In every Iteration.
@Test(dataProvider=”SuiteGetTestData”)
public void suiteDemoGooglePositive(String IncomingDataCol1,String IncomingDataCol2,String IncomingDataCol3,String IncomingExpectedResult) throws Throwable{
DataCol1 = IncomingDataCol1;
DataCol2 = IncomingDataCol2;
DataCol3 = IncomingDataCol3;
dataSet++;
//Created object of testng SoftAssert class.
s_assert = new SoftAssert();

//If found DataToRun = “N” for data set then execution will be skipped for that data set.
//If found DataToRun = “Y” for data set then bellow given lines will be executed.
skipTestIfDataToRunIsN();

if (Param == null){
//INITIATE DRIVERS AND RUN BROWSER
Param = new Properties();
FileInputStream fip = new FileInputStream(propertyPath);
Param.load(fip);
}

seleniumWebDriver = new SeleniumWebDriver();

for (String testBrowser : testBrowsers) {
//To Initialize browser.
driver =  seleniumWebDriver.loadDriver(testBrowser);
helpers = new Helpers(driver);
driver.manage().window().maximize();

for (String siteURL : siteURLtoRUN) {
SuiteBase.Add_Log.info(“Run test for ” + siteURL);
extentTest.log(LogStatus.INFO, “Run test for ” + siteURL);

// TEST METHODS HERE

}
}
}

public void skipTestIfDataToRunIsN() {
if(!testDataToRun[dataSet].equalsIgnoreCase(“Y”)){
Add_Log.info(testCaseName+” : DataToRun = N for data set line “+(dataSet+1)+” So skipping Its execution.”);
extentTest.log(LogStatus.INFO, testCaseName+” : DataToRun = N for data set line “+(dataSet+1)+” So skipping Its execution.”);
//If DataToRun = “N”, Set testSkip=true.
testSkip=true;
throw new SkipException(“DataToRun for row number “+dataSet+” Is No Or Blank. So Skipping Its Execution.”);
}
}

//@AfterMethod method will be executed after execution of @Test method every time.
@AfterMethod
public void reporterDataResults(ITestResult result){
afterMethodCheckStatus(testSkip, filePath, testCaseName, dataSet, testCasePass, result);
//At last make flag as false for next data set.
testSkip=false;
}

//This data provider method will return 4 column’s data one by one In every Iteration.
@DataProvider
public Object[][] SuiteGetTestData(){
//To retrieve data from Data 1 Column,Data 2 Column,Data 3 Column and Expected Result column of SuiteLoginCaseOne data Sheet.
//Last two columns (DataToRun and Pass/Fail/Skip) are Ignored programatically when reading test data.
return SuiteUtility.GetTestDataUtility(filePath, testCaseName);
}

//To report result as pass or fail for test cases In TestCasesList sheet.
@AfterTest
public void closeBrowser(){
Add_Log.info(“TestCaseName = ” + testCaseName + ” , testCasePass = ” + testCasePass + ” , filePath =” + filePath + ” , sheetName =” + sheetName);
extentTest.log(LogStatus.INFO, “TestCaseName = ” + testCaseName + ” , testCasePass = ” + testCasePass + ” , filePath =” + filePath + ” , sheetName =” + sheetName);
seleniumWebDriver.closeWebDriver(testCaseName, testCasePass, filePath, sheetName);
extentReport.endTest(extentTest);
extentReport.flush();
}
}

SuiteDemo.java

package solution.testSuite.Demo;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;

import org.testng.annotations.BeforeSuite;

import eccentex.AppTester.utility.Read_XLS;
import eccentex.TestSuite.Base.SuiteBase;

public class SuiteDemo extends SuiteBase{
//Initializing Test Suite (<test suite file name>.xls) File Path Using Constructor Of Read_XLS Utility Class.
public static Read_XLS TestCaseListExcel = new Read_XLS(xlsDirectory);

//Set Site URL which to test SQL in this test suite
public static String SiteURLSQL = “http://www.mortgagecalculator.org/&#8221;;
//Set Site URL which to test ORACLE in this test suite
public static String SiteURLORACLE = null;
//set test browser for current suite. Set null to ignore this browser.
public static String TestBrowserMozilla = null;//”Mozilla”;
public static String TestBrowserChrome = “Chrome”;
public static String TestBrowserIE = null; //”IE”;

//menu item name which always exists in this solution
public static String menuItemName = “Dictionaries”;

//Oracle DB parameters
public static String OracleDriver = “text”;
public static String OracleConnection = “text”;
public static String OracleUser = “text”;
public static String OraclePassword = “text”;

//MsSql DB parameters
public static String MssqlDriver = “text”;
public static String MssqlName = “text”;
public static String MssqlUser = “text”;
public static String MssqlPassword = “text”;

public static ArrayList<String> siteURLtoRUN = new ArrayList<String>();
public static ArrayList<String> testBrowsers = new ArrayList<String>();

public static String DataCol1;
public static String DataCol2;
public static String DataCol3;
public static Properties Param;

//This function will be executed before SuiteLogin’s test cases to check SuiteToRun flag.
@BeforeSuite
public void checkSuiteToRun() throws IOException{
//Called init() function from SuiteBase class to Initialize .xls Files
init();
//get site URL link
//if !Param.getProperty(“parameterSiteURL”) {siteURL = Param.getProperty(“parameterSiteURL”} else
if (SiteURLSQL != null){
siteURLtoRUN.add(SiteURLSQL);
}

if (SiteURLORACLE != null){
siteURLtoRUN.add(SiteURLORACLE);
}

if (siteURLtoRUN.isEmpty()){Add_Log.error(this.getClass().getSimpleName()+” : no URL to check.”);}

//get test browser
//if (!Param.getProperty(“parameterTestBrowser”)){testBrowser = Param.getProperty(“parameterTestBrowser”);} else

if (TestBrowserMozilla != null){
testBrowsers.add(TestBrowserMozilla);
}
if (TestBrowserChrome != null){
testBrowsers.add(TestBrowserChrome);
}
if (TestBrowserIE != null){
testBrowsers.add(TestBrowserIE);
}
if (testBrowsers.isEmpty()){Add_Log.error(this.getClass().getSimpleName()+” : no browsers to check.”);}
//To set TestSuiteList.xls file’s path In filePath Variable.
Read_XLS filePath = testSuiteListExcel;
//To set all test in the suite
String sheetName = “SuitesList”;
//to get the data from the tab
String suiteName = “SuiteDemo”;
//Column name SuiteToRun to get or set the status
String toRunColumnName = “SuiteToRun”;
runOrSkipSuite(filePath, sheetName, suiteName, toRunColumnName);
}
}

SuiteBase.java

package eccentex.TestSuite.Base;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.openqa.selenium.WebDriver;
import org.testng.ITestResult;
import org.testng.SkipException;

import com.relevantcodes.extentreports.ExtentReports;
import com.relevantcodes.extentreports.ExtentTest;
import com.relevantcodes.extentreports.LogStatus;

import eccentex.AppTester.utility.ExtentReport;
import eccentex.AppTester.utility.Logging;
import eccentex.AppTester.utility.Read_XLS;
import eccentex.AppTester.utility.ScreenshotUtility;
import eccentex.AppTester.utility.SuiteUtility;

public class SuiteBase {
public static Read_XLS testSuiteListExcel=null;
public static Read_XLS testCaseListExcelOne=null;
public static Read_XLS testCaseListExcelTwo=null;
public static Read_XLS testCaseListExcelThree=null;
public static Read_XLS testCaseListExcelFour=null;
public static Logger Add_Log = null;
public boolean browserAlreadyLoaded=false;
public static Properties Param = null;
public static Properties Object = null;
public static WebDriver driver=null;
public static WebDriver existingchromeBrowser;
public static WebDriver existingmozillaBrowser;
public static WebDriver existingIEBrowser;
protected static ExtentReports extentReport;
public static ExtentTest extentTest;

public void init() throws IOException{
//———–To Initialize logger service.
if (Add_Log == null){
Add_Log = Logging.getLogger();
}

//———–To Initialize http://extentreports.relevantcodes.com/ service
if (extentReport == null){
extentReport = ExtentReport.getExtentReport();
}

//Please change file’s path strings bellow If you have stored them at location other than bellow.
//Initializing Test Suite List(TestSuiteList.xls) File Path Using Constructor Of Read_XLS Utility Class.
testSuiteListExcel = new Read_XLS(System.getProperty(“user.dir”)+”\\src\\solution\\input\\ExcelFiles\\TestSuiteList.xls”);
//Bellow given syntax will Insert log In applog.log file.
Add_Log.info(“All Excel Files Initialised successfully.”);

//Initialize Param.properties file.
Param = new Properties();
FileInputStream fip = new FileInputStream(System.getProperty(“user.dir”)+”//src//solution//input//property//Param.properties”);
Param.load(fip);
Add_Log.info(“Param.properties file loaded successfully.”);

//Initialize Objects.properties file.
Object = new Properties();
fip = new FileInputStream(System.getProperty(“user.dir”)+”//src//solution//input//property//Objects.properties”);
Object.load(fip);
Add_Log.info(“Objects.properties file loaded successfully.”);
}

public String[] runOrSkipCase(Read_XLS filePath, String testCaseName, String sheetName, String toRunColumnNameTestCase, String toRunColumnNameTestData) {
//To check test case’s CaseToRun = Y or N In related excel sheet.
//If CaseToRun = N or blank, Test case will skip execution. Else It will be executed.
if(!SuiteUtility.checkToRunUtility(filePath, sheetName,toRunColumnNameTestCase,testCaseName)){
Add_Log.info(testCaseName+” : CaseToRun = N for So Skipping Execution.”);
extentTest.log(LogStatus.SKIP, testCaseName+” : CaseToRun = N for So Skipping Execution.”);
//To report result as skip for test cases In TestCasesList sheet.
SuiteUtility.WriteResultUtility(filePath, sheetName, “Pass/Fail/Skip”, testCaseName, “SKIP”);
//To throw skip exception for this test case.
throw new SkipException(testCaseName+”‘s CaseToRun Flag Is ‘N’ Or Blank. So Skipping Execution Of “+testCaseName);
}
//To retrieve DataToRun flags of all data set lines from related test data sheet.
return SuiteUtility.checkToRunUtilityOfData(filePath, testCaseName, toRunColumnNameTestData);
}

//check if we should run suite or skip it
public void runOrSkipSuite(Read_XLS filePath, String sheetName, String suiteName, String toRunColumnName) {
//Bellow given syntax will Insert log In applog.log file.
Add_Log.info(“Execution started for ” + suiteName + “.”);

//If SuiteToRun !== “y” then SuiteLogin will be skipped from execution.
if(!SuiteUtility.checkToRunUtility(filePath, sheetName,toRunColumnName,suiteName)){
Add_Log.info(“SuiteToRun = N for “+suiteName+” So Skipping Execution.”);
//To report SuiteLogin as ‘Skipped’ In SuitesList sheet of TestSuiteList.xls If SuiteToRun = N.
SuiteUtility.WriteResultUtility(filePath, sheetName, “Skipped/Executed”, suiteName, “Skipped”);
//It will throw SkipException to skip test suite’s execution and suite will be marked as skipped In testng report.
throw new SkipException(suiteName+”‘s SuiteToRun Flag Is ‘N’ Or Blank. So Skipping Execution Of “+suiteName);
}
//To report Suite as ‘Executed’ In SuitesList sheet of TestSuiteList.xls If SuiteToRun = Y.
SuiteUtility.WriteResultUtility(filePath, sheetName, “Skipped/Executed”, suiteName, “Executed”);
}

public void afterMethodCheckStatus(boolean testskip, Read_XLS filePath, String testCaseName, int dataSet, boolean testCasePass, ITestResult result) {
if(result.getStatus() == ITestResult.FAILURE)
{
String screenShotPath = ScreenshotUtility.captureScreenShot(result, null);
extentTest.log(LogStatus.FAIL, testCaseName+” : Reporting test data set line “+(dataSet+1)+” as FAIL In excel.”);
extentTest.log(LogStatus.FAIL, result.getThrowable());
extentTest.log(LogStatus.FAIL, “Snapshot below: ” + extentTest.addScreenCapture(screenShotPath));
Add_Log.error(testCaseName+” : Reporting test data set line “+(dataSet+1)+” as FAIL In excel.”);
Add_Log.error(result.getThrowable());
//Set TestCasePass = false to report test case as fail In excel sheet.
testCasePass=false;
//If found testFail = true, Result will be reported as FAIL against data set line In excel sheet.
SuiteUtility.WriteResultUtility(filePath, testCaseName, “Pass/Fail/Skip”, dataSet+1, “FAIL”);
}
else if(testskip){
Add_Log.info(testCaseName+” : Reporting test data set line “+(dataSet+1)+” as SKIP In excel.”);
//If found testSkip = true, Result will be reported as SKIP against data set line In excel sheet.
extentTest.log(LogStatus.SKIP, testCaseName+” : Reporting test data set line “+(dataSet+1)+” as SKIP In excel.”);
SuiteUtility.WriteResultUtility(filePath, testCaseName, “Pass/Fail/Skip”, dataSet+1, “SKIP”);
}
else{
Add_Log.info(testCaseName+” : Reporting test data set line “+(dataSet+1)+” as PASS In excel.”);
//If found testSkip = false and testFail = false, Result will be reported as PASS against data set line In excel sheet.
SuiteUtility.WriteResultUtility(filePath, testCaseName, “Pass/Fail/Skip”, dataSet+1, “PASS”);
}
}
}

Advertisements
Standard

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s