Sunday, 24 July 2016

Approach for Effective Automation Framework

Preface: This blog is not related to different kind of automation frameworks. It is about the thing need to consider during planning phase for Automation framework.

A well-defined automation framework helps to maintain higher re-usability and develops easily maintainable scripts. It is very important to choose an effective automation framework for any project or organization which is more effective and can be used across projects and have higher ROI from the automation project.
To consider a framework, we must understand the requirements and select an approach to create an effective automation framework. Below mentioning few points which are important to consider to create an effective framework.
  • What all kind of application need to automate? It might be Web, Webservices/API, Mobile, Desktop, specific application like Oracle, SAP, etc.
  • Flow requirement?  Single application or combination frontend and backend.
  • Who all are going to use this automation framework for execution?It can be used by QA, Developer or business people as well
  • What kind of reporting we require?
  • Do you require any separate logging for debugging?
  • Is your framework require Performance Testing using those functional scenarios?
  • Is any requirement of GUI testing?
  • Do you require CI/CD integration?
  • Do you require Code coverage also?
  •  Do you require Big Data integration too?

Epilogue : If we are clear of what we require then we can move to selecting tool, technologies, methodologies to create an effective framework. To achieve desired benefits the framework must be accurately designed and developed.

A Goal without planning is just a Dream


Wednesday, 12 November 2014

Selenium's Inventor


Selenium's Inventor

Posted by Patrick Copeland, Test Engineering Director
Couple of GTAC Videos with Jason: SeleniumRCSelenium vs WebDriver
CG: Why did you invent Selenium? What was the motivation? 
Huggins: Selenium was extracted from a web-based (Python + Plone!) time-and-expense (T&E) application my team and I were building for my previous employer. One of the mandates for the new T&E app was that it needed to be "fast, fast, fast." The legacy application was a client-server Lotus Notes application and wasn't scalable to the current number of offices and employees at the time. To live up to the "fast, fast, fast" design goal, we tried to improve and speed up the user experience as much as possible. For example, expense reports can get pretty long for people who travel a lot. No matter how many default rows we put in a blank expense form, people often needed to add more rows of expense items to their reports. So we added an "Add row" button to the expense report form. To make this "fast, fast, fast," I decided to use a button that triggered JavaScript to dynamically add one blank row to the form. At the time (Spring 2004), however, JavaScript was considered buggy and evil by most web developers, so I caught a lot of flak for not going with the classic approach of POSTing the form and triggering a complete page refresh with the current form data, plus one blank row.
Going down the road of using JavaScript had consequences. For one, we had a really, really difficult time testing that little "Add row" button. And sadly, it broke often. One week "Add row" would be working in Mozilla (Firefox was pre-1.0), but broken in Internet Explorer. And of course, nothing was working in Safari since few developers were allowed to have Macs. ;-) The following week, we'd open a bug saying "'Add row' is broken in IE!!" The developer assigned to the issue would fix and test it in IE, but not test for regressions in Mozilla. So, "Add row" would now be broken in Mozilla, and I'd have to open a ticket saying "'Add row' is now broken in Mozilla!!!". Unlike most other corporate IT shops, we didn't have the luxury of telling all employees to use a single browser, and developers didn't want to manually test every feature in all supported browsers every time. Also, we had a very tiny budget and commercial testing tools were -- and still are -- ridiculously over-priced on a per-seat basis. The T&E project was done the "Agile Way" -- every developer does testing -- so shelling out thousands of dollars per developer for a testing tool wasn't going to happen. Never mind the fact that there were no commercial tools that did what we needed anyway!
After many months of trial and error and various code workarounds, I came to the conclusion I needed a testing tool that would let me functional-test JavaScript-enhanced web user interfaces (aka "DHTML" or now "Ajax"). More specifically, I needed to test the browser UIs: Internet Explorer, Mozilla Firefox, and Safari. There were no commercial apps at the time that could do this, and the only open source option was JsUnit, which was more focused on unit testing pure JavaScript functions, rather than being a higher-level black-box/smoke-test walk through a web app. So we needed to write our own tool. Our first attempt was a Mozilla extension called "driftwood" (never released), coded by Andrew McCormick, another co-worker of mine at the time. It did make testing the "Add row" button possible, but since it was Mozilla-only, it wasn't what we needed for testing in all browsers. Paul Gross and I started over, and I started to educate myself on functional testing tools and techniques and stumbled upon Ward Cunningham's Framework for Integrated Testing (FIT). I originally set out to implement "FIT for JavaScript," but quickly realized we were drifting away from the FIT API, so Selenium became its own thing.
CG: Why does the world need another test tool?
Huggins: 
At the time I created Selenium, had there been another testing tool that could test JavaScript UI features in all browsers on all platforms, believe me, I would have saved lots of time *not* writing my own tool.
CG: What's special about it?
Huggins: Well, maybe the right question is "What's “lucky” about it? Selenium was created in a time when JavaScript was considered "bad" and generally avoided by most professional web developers. Then Google Maps hit the scene a year later, the term "Ajax" was coined, and BOOM! Overnight, JavaScript became "good." Also, Firefox started stealing market share from IE. The combination of needing to test 1) JavaScript features 2) in several browsers (not just IE) was a "right place, right time" moment for Selenium.
CG: When did you realize that Selenium was a big deal? What was the tipping point? 
Huggins: When I started being asked to give presentations or write about Selenium by people I didn't know. The tipping point for Selenium technically relied on two things: 1) the Selenium IDE for Firefox, written by Shinya Kasatani, which made installation and the first-hour experience tons better for new users. And 2), Selenium Remote Control (RC) created by Paul Hammant, and extended by Dan Fabulich, Nelson Sproul, and Patrick Lightbody, which let developers write their tests in Java, C#, Perl, Python, or Ruby, and not have to write all their tests in the original FIT-like HTML tables. Socially, if Google Maps or Gmail never existed and thus the whole Ajax gold rush, I wonder if JavaScript would still be considered "bad," with a similar "why bother?" attitude to testing it.
CG: Have you discovered any interesting teams using Selenium in ways you'd never intended? 
Huggins: At my previous company, I did see some developers write Selenium scripts to create their time and expense reports for them from YAML or XLS files. Since we hadn't exposed a back-end API, automating the browser for data entry was the next best thing. It was never designed for this purpose, but I started (ab)using it as coded bug reports. Asking users for steps on how to reproduce a bug naturally lends itself to looking like a Selenium test for that bug. Also, I've used the Selenium IDE Firefox plug-in to enter NBC's "Deal or No Deal" contest on their website from home, but I stopped doing that when I read in the fine print that the use of automation tools to enter their contest was grounds for disqualification.
CG: What advice do you have to offer Google groups interested in Selenium?Huggins: Well, one of the biggest drawbacks with user interface testing tools is that they're slow for various reasons. One way to bring the test run times down is to run them in parallel on a grid of servers, instead of sequentially. Of course, that isn't news to your average Googler. Engineers would be more likely to run automated browser UI tests if they could run 1000 tests in 1 minute total time on 1000 machines instead of 1000 tests in 1000 minutes on 1 machine. Sadly, though, most projects allocate only one machine, maybe two, to browser testing. I'm really excited to come to Google with the resources, the corporate interest, and the internal client base to make a large scale Selenium UI test farm possible. Eventually, I’d like to take Selenium in some new directions that we’ll talk about in later blog posts. But I'm getting ahead of myself. I have to survive Noogler training first.

Sunday, 4 August 2013

Send Email in Soap UI using Groovy

Hi Guys,

Here is the code to send email in SoapUI using groovy.

Requirement: Java Mail Jar file location
http://www.java2s.com/Code/JarDownload/java/java-mail-1.4.4.jar.zip

// Note: Generally in SoapUI no need of java mail jar file but if require then can download from above link and save at ext directory.

Sending email "Gmail" SMPT server:

import com.sun.mail.smtp.SMTPTransport;
import java.security.Security;
import java.util.Date;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public static void Send(final String username, final String password, String recipientEmail, String ccEmail, String title, String message) throws AddressException, MessagingException {
        final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";

        // Get a Properties object
        Properties props = System.getProperties();
        props.setProperty("mail.smtps.host", "smtp.gmail.com");
        props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        props.setProperty("mail.smtp.port", "465");
        props.setProperty("mail.smtp.socketFactory.port", "465");
        props.setProperty("mail.smtps.auth", "true");

        /*
        If set to false, the QUIT command is sent and the connection is immediately closed. If set
        to true (the default), causes the transport to wait for the response to the QUIT command.

        ref :   http://java.sun.com/products/javamail/javadocs/com/sun/mail/smtp/package-summary.html
                http://forum.java.sun.com/thread.jspa?threadID=5205249
                smtpsend.java - demo program from javamail
        */


        props.put("mail.smtps.quitwait", "false");

        Session session = Session.getInstance(props, null);

        // -- Create a new message --
        final MimeMessage msg = new MimeMessage(session);

        // -- Set the FROM and TO fields --
        msg.setFrom(new InternetAddress(username + "@gmail.com"));
        msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipientEmail, false));

        if (ccEmail.length() > 0) {
            msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(ccEmail, false));
        }

        msg.setSubject(title);
        msg.setText(message, "utf-8");
        msg.setSentDate(new Date());

        SMTPTransport t = (SMTPTransport)session.getTransport("smtps");

        t.connect("smtp.gmail.com", username, password);
        t.sendMessage(msg, msg.getAllRecipients());     
        t.close();
    }

 log.info Send(username, password, recipientEmail, ccEmail, title, message);

Sunday, 19 May 2013

StartUp Groovy Scripts commands in SoapUI


// ***************** Project Commands***************************
// Define Project object
def project = testRunner.testCase.testSuite.project

// Get Project Location
log.info project.getPath()

// ***** Get Default Project Properties
1. Name
log.info project.name

2. Default Scripting Language
log.info project.getDefaultScriptLanguage()

In Similar fashion we can fetch other default values of project properties like ‘Description (getDescription)’, etc

// ***** Get Custom Project Properties
log.info project.getPropertyValue(“Property1”)

// ***** Change/Set default project property values
1. Name
log.info project.setName("Currency")

2. Change Default Script Language
log.info project.setScriptLibrary("Groovy")

In Similar fashion we can set other default values of project properties like ‘Description (setDescription)’, etc

// ***** Set Custom Project Properties
log.info project.setPropertyValue(“Property1”, “SampleValue”)

// *******************************************************************

// *********************** Test Suite Commands***************************
// Define Test Suite object
def sTestSuite = testRunner.testCase.testSuite

// ***** Get Default Test Suite Properties
## Name
log.info sTestSuite.name

// ***** Get Custom TestSuite Properties
log.info sTestSuite.getPropertyValue("SuiteProperty1")

// ***** Change default Test Suite property values
## Name
log.info sTestSuite.setName("Currency")

// ***** Set Custom Test Suite Properties
log.info sTestSuite.setPropertyValue("SuiteProperty1", "ChangeSampleValue")

 // *******************************************************************

// *********************** Test Case Commands*************************
// Define Test Case object
def sTestCase = testRunner.testCase

// ***** Get Default Test Case Properties
## Name
log.info sTestCase.name

// ***** Get Custom TestSuite Properties
log.info sTestCase.getPropertyValue("TestCaseProperty1")

// ***** Change default Test Case property values
## Name
log.info sTestCase.setName("TestCaseCurrency")

// ***** Set Custom Test Case Properties
log.info sTestCase.setPropertyValue("TestCaseProperty1", "ChangeSampleValue")

// *******************************************************************

// ***************** Global Property Commands**************************
// Define SoapUI Global object
def oGlobal = com.eviware.soapui.SoapUI.globalProperties

// ***** Get Global property
oGlobal.getPropertyValue("GlobalProperty1")

// ***** Set New Global Property
oGlobal.setPropertyValue("GlobalProperty2", "GlobalValue2")

SOAPUI Properties


SoapUI Properties
Properties are a central aspect of more advanced testing with soapUI. In regard to Functional Testing properties are used to parameterize the execution and functionality of your tests, for example:

·         Properties can be used to hold the endpoints of your services, making it easy to change the actual endpoints used during test execution (see example below)
·         Properties can be used to hold authentication credentials, making it easy to manage these in a central place or external file
·         Properties can be used to transfer and share session ids during test execution, so multiple teststeps or testcases can share the same sessions
·         etc


SOAP UI TYPE OF PROPERTIES


Default Property:
·         These are the set of properties which comes by default with every soapUI installation.
·         We can change the values of these properties (not in every case) & consume as when needed.

Custom/User Defined Property:
·         These are the set of properties which the end user defines as per his requirement.
·         It can be used a temporary storage for validating the end result of any test (like in assertion).

SOAP UI LEVELS OF PROPERTIES
# Global Properties: specify/define the properties associated with installed version of soapUI. These properties can be access across the project/test suites/ test cases and so on.

# Project Properties: specify the properties associated with the current project. This property can be used by all the subset (test suite, test case, test step, script) of the project.

# Test Suite Properties: specify the properties associated with the current test suite. This property can be used by all the subset (test case, test step, script) of the test suite.

# Test Cases Properties: specify the properties associated with the current test case. This property can be used by all the subset (test step, script) of the test cases.

# Test Step Properties: specify the properties associated with the current test step. This property can be used by all the subset (test step, property transfer, script) of the test steps

SnapShot

Saturday, 18 May 2013

Enable and Disable Test Cases in SoapUI using Groovy

Hi,

If you require to get the list of of test cases of a test suite under SoapUI project, use the below code with in groovy step:


// **** Test case list
// Create testSuite object

def oTestSuite = testRunner.testCase.testSuite;

// Get the array of test cases
def iTotalTestCases = oTestSuite.getTestCaseList().name

// Fetch list of test case and their name
for(testCaseCounter in (0..(iTotalTestCases.size-1)))
{    
log.info iTotalTestCases[testCaseCounter]
}




// **** Below Code is on the basis of  index value
// Create testSuite object
def oTestSuite = testRunner.testCase.testSuite;

// Get the count of test cases in a testSuite
def iTotalTestCases = oTestSuite.getTestCases().size();

// List down the name of each test Case with in a test suite
for(testCaseCounter in (0..iTotalTestCases-1))
{  
def sTestCaseName = oTestSuite.getTestCaseAt(testCaseCounter).name
log.info sTestCaseName
}

SnapShot:



** Note: Result in sequential order as shown in above snapshot

## Disable Test Cases in SoapUI using groovy
// ***** Code to disable test step using its name:
def oTestSuite = testRunner.testCase.testSuite;
oTestSuite.getTestCaseByName("TestCase 1").setDisabled(true)

if require to disable all cases within a test suite in one go then use below code:


// Create testSuite object

def oTestSuite = testRunner.testCase.testSuite;

// Get the array of test cases
def iTotalTestCases = oTestSuite.getTestCaseList().name

// Fetch list of test case and their name
for(testCaseCounter in (0..(iTotalTestCases.size-1)))
{    
oTestSuite.getTestCaseByName(iTotalTestCases[testCaseCounter]).setDisabled(true)
}



## Enable test cases in SoapUI using groovy


// ***** Code to enable test step using its name:
def oTestSuite = testRunner.testCase.testSuite;
oTestSuite.getTestCaseByName("TestCase 1").setDisabled(false)


if require to enable all step in one go then use below code:

// Create testSuite object

def oTestSuite = testRunner.testCase.testSuite;

// Get the array of test cases
def iTotalTestCases = oTestSuite.getTestCaseList().name

// Fetch list of test case and their name
for(testCaseCounter in (0..(iTotalTestCases.size-1)))
{    
oTestSuite.getTestCaseByName(iTotalTestCases[testCaseCounter]).setDisabled(false)
}



Point to be remember:  Above code will work only when call with in groovy step of a test case because it is using SoapUI predefined variable i.e. "testRunner" which works only under Groovy Test Step of a Test Case.

Friday, 17 May 2013

Enable and Disable test steps in SoapUI using Groovy

Hi,

If you require to get the list of of test steps in SoapUI then use the below code:

// Get the list of test steps
def oNameList = testRunner.testCase.getTestStepList().name

// Use loop to print name of every step in log
for(iNameCounter in (0..oNameList.size-1))
{
log.info oNameList[iNameCounter]
}

Example Image:













* Note: Result in sequential order as shown in above image

## Disable test steps in SoapUI using groovy

1 Get the list of test steps using the above code and use the below code:

// Code to disable test step using its name:
testRunner.testCase.getTestStepByName("TestStep1").setDisabled(true)

if require to disable all step in one go then use below code:

//Get the names of all test steps
def oNameList = testRunner.testCase.getTestStepList().name
for(iNameCounter in (0..oNameList.size-1))
{  
testRunner.testCase.getTestStepByName(oNameList[iNameCounter]).setDisabled(true)
}




## Enable test steps in SoapUI using groovy

1 Get the list of test steps using the above code and use the below code:

// Code to enable test step using its name:
testRunner.testCase.getTestStepByName("TestStep1").setDisabled(false)

if require to enable all step in one go then use below code:

//Get the names of all test steps
def oNameList = testRunner.testCase.getTestStepList().name
for(iNameCounter in (0..oNameList.size-1))
{  
testRunner.testCase.getTestStepByName(oNameList[iNameCounter]).setDisabled(false)
}


oNameList[iNameCounter]: It store the name of step.