Monday, December 24, 2012

Teach Me Ovie OneKaDevie

09-23-2012


Technology is changing the world of testing by nearly demanding we automate our test execution efforts.  Look at the job ads if you don’t believe me….Agile Tester!  What the heck is that?  We must use the force of programming to add this to our already wide-range and diverse set of skills.  That is, if we wish to use a force that grants us robust and reusable solutions to aid our test efforts in this continuously evolving and demanding world.  Hence, we have much to learn from our development knights and commanders.

One method for both learning test automation and quickly expanding coverage, when developing TestFrameworks, is through the use of developing template methods or as the developers would say “interfaces and inheritance.”  Inheritance allows us to create classes with properties and methods of the general behavior we wish our automated methods to have.  Not all of our automated tools allow this technique so a stripped down version would be to create templates, e.g files with functions we can copy and modify to fit each usage situation.  The base class or template can be structured to meet the analyst’s requirements such as:
  • Defining the correct test status results, e.g. passed, failed, blocked, skipped
  • Defining the correct reporting based on the test status results
  • Performing required base state setups and tear downs
  • Managing test result reporting
Some side benefits to utilizing the template and/or interface and inheritance methods are:
  • Aid in easier automation code management and maintenance
  • Reduce the coding effort…woohoo!... because we have enough to do
  • Guide our not so techy testers to help create new or modify existing automation methods/functions
  • Easier refactoring…because we know it will happen
  • Help new testers come up to speed more quickly when assisting with test automation
If you permit me, I would like to share a couple of examples.

Selenium WebDriver template example
public void login (String [] dataParms ) throws Throwable {
        try {->Block (exception) code begins
if (personnummer.equals(null)) {StringTokenizer st = new
StringTokenizer(dataParms[0], ";");
String user = st.nextToken();
String password = st.nextToken();
framework.skrivTextID(null, "ctl00_contentRegion_ctl01_userid",                     user);
framework.skrivTextID(null,                       "ctl00_contentRegion_ctl01_password", password);
String text = framework.klickaKnappenID("ctl00_contentRegion_ctl01_login");
->Behavior driven code
status.setStepStatus("2");->Pass code
} else {
if (this.getExists()) {
framework.skrivTextID(null, "ctl00_contentRegion_ctl01_userid", this.getPersonnummer().trim());
framework.skrivTextID(null, "ctl00_contentRegion_ctl01_password", this.getPassword().trim());
framework.klickaKnappenID("ctl00_contentRegion_ctl01_login");
->Behavior driven code
status.setStepStatus("2");->Pass code
} else {
status.setStepStatus("5");->Block code
status.createErrorLogReport("Hittade inte en kund vi kan verifiera för IK", "login", "Hittade inte en kund vi kan verifiera för IK");                
}           
}
->Block error reporting
} catch (Exception e) {
status.setStepStatus("1");->Exception handlingFail code
status.createPrintScreenReport("Kan inte logga in till IK", "login", "Kan inte logga in till IK");}}->Fail error report with print screen

Selenium WebDriver is an open source web application testing solution that supports languages such as Java and C++ that can leverage the interface and inheritance techniques, the above solution can be converted into a method of a BaseClass.  You can see more examples of how do utilize this technique in java at http://docs.oracle.com/javase/tutorial/java/IandI/index.html and in C++ at, http://www.anyexample.com/programming/cplusplus/cplusplus_inheritance_example.xml.

TestComplete template example (using Jscript)
function newRESTResource( DataParms ) {
var logStepResults = new stepResults("", "", "", "");
var CleanedParms = scrubDataParms(DataParms);
var ParsedParms = CleanedParms.split("|");
var ParsedOperations = ParsedParms[4].split("/");var err;
->Common properties for managing test results and cleaning the incoming data from ALMComplete
if ( Aliases.WaitAliasChild("NewRESTResource", 1000).Exists ) {
try {->Try exception handling begins 
if ( ParsedParms[0] != "" ) {
Aliases.NewRESTResource.ResourceName.setText( ParsedParms[0] );
}
if ( ParsedParms[1] != "" ) {
Aliases.NewRESTResource.ResourcePathEndpoint.setText( ParsedParms[1] );
}
if ( ParsedParms[2] != "" ) {
Aliases.NewRESTResource.ExtractParams.Click();
}
if ( ParsedParms[3] != "" ) {
switch ( ParsedParms[3] )
{
case "Help":
Aliases.NewRESTResource.Help.Click();
break;
case "OK":
Aliases.NewRESTResource.OK.Click();
break;
case "Cancel":
Aliases.NewRESTResource.Cancel.Click();
break;
}
->Behavior driven code 
logStepResults.testStatus="Passed";->Pass code
} catch (e) {
logStepResults.testStatus="Blocked";->Block code 
logStepResults.testStatusMessage="Failed to add New REST Resource";Log.Error("Failed to add New REST Resource, " + e.description);err=getSoapUILog();Log.Error("***SOAP UI LOG:  " + err);clearSoapUILog();err=getErrorLog();Log.Error("***ERROR LOG:  " + err);clearErrorLog();->Block error reporting with application under test’s logs
 }
} else {
logStepResults.testStatus="Failed";->Fail code 
logStepResults.testStatusMessage="New REST Resource is not visible";Log.Error("New REST Resource is not visible");err=getSoapUILog();Log.Error("***SOAP UI LOG:  " + err);clearSoapUILog();err=getErrorLog();Log.Error("***ERROR LOG:  " + err);clearErrorLog();}->Fail error report with the application under test’s logsNOTE:  In this example TestComplete automatically provides screen captures
Delay(5000);return logStepResults;}->Behavior driven code 

Unlike making a choice to join the dark side or the light side …hehe…, don’t feel you have to make the best of all best choices when you begin automation.  For many test automation specialists, especially when using commercial tools, it can and often will be a learning process for some time.  We begin with record and playback and we mature to sophisticated TestFrameworks.  Your methods and frameworks will go through several stages before ending up as a solid and robust testing solution everyone can comfortably rely on.  Do you know, even developers go through a process of developing and refactoring code?  Yes they do!  The code/scripts improve as we learn more and become more confident with our growing programming skill set.  So do not be afraid to begin somewhere.  Anything you develop that helps with the testing effort is valuable.

Happy Automation!

No comments:

Post a Comment