Thursday

Specified VM install not found


If you have recently upgraded the JRE on your machine and you start facing problems with eclipse. 
Also If you see this message when you try to run eclipse Specified VM install not found: type Standard VM

What will not work? Deleting and recreating the workspace

What will work:

First let the project know which JDK container to use:
  • Navigate to Window -> Preferences -> Java -> Installed JREs
  • Select the jdk on your machine
  • Navigate to Window->Preferences->Java->Installed JREs->Execution Environments
  • List of common jvm environments such as JavaSE-1.6 and JavaSE-1-7 names. Click rows and choose jre instance on the right side panel.
  • This is where you may accidentally have nothing chosen if JREs were uninstalled or names changed in InstalledJREs setting. You may get Specified vm install not found error dialog.

  • Go Back to the Project
  • Navigate to the JavaBuildPath 
  • Add Library -> JRE System Library-> Next and Finish
If you are using Ant then
  • build.xml file->Run As->Ant Build->popup menu entry. 
  • Click on JRE tab and choose execution environment. This may have obsolete value from the previous jdk values.
Now navigate to Project Properties->Java Build Path/Libraries
Add Library.../JRE System Library/(x)Execution environment
Choose execution environment to be used for this project.

Happy Testing!

Wednesday

How do you update the results of a test run into Rally ? Rally REST API

If you are looking for code that can help you update results into Rally after an automated test run, here is the code:

        String host = "https://rally1.rallydev.com";
        String username = configProp.getProperty("RallyUserName");
        String password = configProp.getProperty("RallyPassword");
        String wsapiVersion = "v2.0";
        String workspaceRef = "/workspace/11111";
        String applicationName = "Rest_FindTC";
       
        RallyTestCaseId = TCID;

   RallyRestApi restApi = new RallyRestApi(
           new URI(host),
           username,
           password);
   restApi.setWsapiVersion(wsapiVersion);
   restApi.setApplicationName(applicationName);  

   // Query to get the id from Rally for the test case
   QueryRequest testCaseRequest = new QueryRequest("TestCase");
   testCaseRequest.setFetch(new Fetch("FormattedID","Name"));
   testCaseRequest.setWorkspace(workspaceRef);
   testCaseRequest.setQueryFilter(new QueryFilter("FormattedID", "=", TCID));
   QueryResponse testCaseQueryResponse = restApi.query(testCaseRequest);
   String testCaseRef = testCaseQueryResponse.getResults().get(0).getAsJsonObject().get("_ref").getAsString();
 
   //Add a Test Case Result              
        JsonObject newTestCaseResult = new JsonObject();
        newTestCaseResult.addProperty("Verdict", "Pass");
        java.util.Date date= new java.util.Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
        String timestamp = sdf.format(date);

        newTestCaseResult.addProperty("Date", timestamp);
        newTestCaseResult.addProperty("Build", Build);
        newTestCaseResult.addProperty("Notes", "Selenium Automated Test Run");
        newTestCaseResult.addProperty("TestCase", testCaseRef);
                       
        CreateRequest createRequest = new CreateRequest("testcaseresult", newTestCaseResult);
        CreateResponse createResponse = restApi.create(createRequest);
        restApi.close();

That's all there is!
Happy Automation...
   

Monday

junit @test order - How do you sort the order of test cases in JUNIT?

Although writing ordered test cases is considered a bad practice. There are instances in any testing framework where even though the test cases are independent of each other you want them to run in a certain order. ( Sort the test cases )
The solution is to use MethodSorters class. MethodSorters is a new class that was introduced after Junit 4.11 release and uses three types of execution orders.
** Sorts the test methods by the method name, in lexicographic order */
NAME_ASCENDING(MethodSorter.NAME_ASCENDING),
 
/** Leaves the test methods in the order returned by the JVM. Note that the order from the JVM my vary from run to run */
JVM(null),
 
/** Sorts the test methods in a deterministic, but not predictable, order */
DEFAULT(MethodSorter.DEFAULT);


You will require the following imports to achieve the same:
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;

You now have a way to execute your test cases in order :)
Happy Test Automation!

Friday

How to retrieve the test case ID or TCID from Rally using Rally REST API



Trying to integrate Rally using Java, then you are reading the right post.

Download the jars needed which would be:

  • rally-rest-api-2.0.1.jar
  • gson-2.2.4.jar
The code below takes the TCID as the input and returns a reference to the test case that you can use as need be.


        String host = "https://rally1.rallydev.com";
        String username = configProp.getProperty("RallyUserName");
        String password = configProp.getProperty("RallyPassword");
        String wsapiVersion = "v2.0";
        String workspaceRef = "/workspace/11111"; 
        String applicationName = "Rest_FindTC";


   RallyRestApi restApi = new RallyRestApi(
           new URI(host),
           username,
           password);
   restApi.setWsapiVersion(wsapiVersion);
   restApi.setApplicationName(applicationName);   
   // Query to get the ref from Rally for the test case
   QueryRequest testCaseRequest = new QueryRequest("TestCase");
   testCaseRequest.setFetch(new Fetch("FormattedID","Name"));
   testCaseRequest.setWorkspace(workspaceRef);
   testCaseRequest.setQueryFilter(new QueryFilter("FormattedID", "=", TCID));
   QueryResponse testCaseQueryResponse = restApi.query(testCaseRequest);
   String testCaseRef = testCaseQueryResponse.getResults().get(0).getAsJsonObject().get("_ref").getAsString(); 
   testCaseRef = testCaseRef.replace("https://rally1.rallydev.com/slm/webservice/v2.0/testcase/", "");
   logger.debug("For the Rally TCID: "+TCID+ " retreived from Rally the ID - "+testCaseRef);
   restApi.close();

In the above code TCID is the parameter that is passed which has the rally test case id. and testCaseRef is what is returned

Happy automated integration!

Could not start a new session. Possible causes are invalid address of the remote server.......



Problem: This again was an issue that I found when I tried setting up the selenium test automation framework on a new machine.

Solution:
Things that you need to check to solve this issue.

First thing check the version of JRE in your project, the javac compiler in your IDE.
Changing the JRE System Library from jdk1.7.0 to jre7
Make sure the classpath is set correctly pointing to the JRE and JDK
If you are using ANT make sure you have the ant libraries in the right place.
Also make sure you have the tools.jar under Ant - Runtime - global libraries.

That worked for me, hope it helps anyone facing the same issue.

Happy Automating!

Thursday

Cannot find chrome binary Selenium Webdriver



This is a very basic error that you find when you try and setup the Selenium framework on new machines.
"Unknown error - Cannot find chrome binary: Selenium...."

Even though you have chrome running on your machine and the chromedriver.exe working fine this error haunts for sometime, until you realize that all you need to do is re-install a local copy of chrome.
You can also copy Google Chrome to a local folder within the machine and change the class-path.

Simple error but sometimes gets annoying.

Happy automation!

Wednesday

Page Object Pattern v/s Separating elements from behavior


This is one of the most common issues that you face while designing a Selenium Webdriver test automation framework.

Technique 1:
Something that you will see being either prescribed by people who have been doing automation for long or have used in automation tools earlier ( like QTP/TestComplete). Create page elements/locators class to store all elements and a separate page object class for the behavior of elements in that page.

Technique 2:
In contrast to the above idea here we use just one page object class to store all the elements and methods for that page. Validations and test flows reside outside the page object class.

I guess as an automation architect the only question I always have is
"Which design is easier to manage and maintain?"

A combination of the two approaches is what makes an hybrid maintainable framework. Have separate page elements but store them in a Java properties file. Have a page element class or a Business process class for behavior of each flow. Further have actions and keywords that facilitate a layer of abstraction over the Selenium API being used as the core engine of the framework.
I like the idea of locators in properties file as you can make changes w/o having to modify the source code. Similar to application config files to specify settings & global parameters.

Pros and Cons
Advantages of this approach is that whatever you use (Properties files/XML files/JSON files) Business Analysts/Manual Testers or any non-programmer can adjust tests to changing circumstances 
On the flip side programmers who are the only ones who can understand the test logic don’t have immediate access to details that bind the app to the test.

Happy Testing!


Tuesday

Create Test Automation HTML reports with Java + Selenium Webdriver



As the name suggests the idea is to create a neat and classy html report that has all the data and the links to your screenshots.
Easy to Read + Clean and classy + Apt data + Links to your screenshots
The easiest way to create reports in any test automation framework. that uses Java is to have separate functions for:

  1. The Header 
  2. The Data + Footer
You might also want to have a separate function for the footer.

Some sample reports that can be an inspiration:
https://www.qfs.de/en/qftest/report.html
http://www.telerik.com/clientsfiles/258892_TestReport.JPG?sfvrsn=0
http://thucydideswebtestsdotcom.files.wordpress.com/2013/01/new-reporting.png

Html Color codes: http://www.computerhope.com/htmcolor.htm

And here is the code that is reusable:


public void testHeader(String testCaseName) throws IOException{
Date d = new Date();
String date=d.toString().replaceAll(" ", "_");
date=date.replaceAll(":", "_");
date=date.replaceAll("\\+", "_");
result_FolderName="Reports"+"_"+date;
new File("TestReports\\"+result_FolderName).mkdirs();
File file3=new File(System.getProperty("user.dir")+"\\Screenshots\\");
File file5=new File(System.getProperty("user.dir")+"\\TestReports\\"+result_FolderName+"\\" );
FileUtils.copyDirectory(file3,file5);
Properties CONFIG = new Properties();
FileInputStream fs = new FileInputStream(System.getProperty("user.dir")+ "\\src\\com\\PROJECT\\selenium\\properties\\configuration.properties");
CONFIG.load(fs);
String environment=CONFIG.getProperty("environment");
// create results html page
currentTestCase= testCaseName; 
String indexHtmlPath="TestReports\\"+result_FolderName+"\\"+currentTestCase+".html";
new File(indexHtmlPath).createNewFile();
 
FileWriter fstream = new FileWriter(indexHtmlPath);
BufferedWriter out = new BufferedWriter(fstream);
out.write(" Automation Test Report Summary

Automation Test Report Summary

Test Details

Run Date");
out.write(d.toString());
out.write("

Run Environment
");

out.write(environment);
out.write("

Test Suite Name
");

out.write("Suite_One");
out.write("

Test Case Name
");

out.write(currentTestCase);
out.write("

Report

");
Step NumberTest Step DescriptionTest DataTest ResultResult Description
out.write("
");
out.close();
}

public void testReport(String stepNo, String description,String testdata,String result) throws IOException{
String indexHtmlPath="TestReports\\"+result_FolderName+"\\"+currentTestCase+".html";
FileWriter fileWritter = new FileWriter(indexHtmlPath,true);
BufferedWriter out_test_steps = new BufferedWriter(fileWritter);
         
out_test_steps.write(" ");  
String data=result;
out_test_steps.write("
"+stepNo+"
");
out_test_steps.write("
"+description+"
");
out_test_steps.write("
"+testdata+"
");
if((data.startsWith("Pass") || data.startsWith("PASS")))
out_test_steps.write("
Pass
");
else if((data.startsWith("Fail") || data.startsWith("FAIL"))){
out_test_steps.write("
Fail
");
}
out_test_steps.write("
"+data+"
");
out_test_steps.write("
");
out_test_steps.write("
");
out_test_steps.close();
}

Thursday

Naming Conventions for Object / Locator Repository / Properties File

I guess there is no real need for me to emphasize why is it that we need to make our Object / Locator repository clean.

Whatever you call the OR:
  • Object map
  • Simple Properties file
  • Object Repository
  • Name Mapping file
  • Or any other file that stores your objects
The reason you want them to be clean:
  • Vastly reduce the amount of time needed for script
  • Script maintenance in case object properties change
  • Sophisticated Object identification and management
  • In the context of Selenium WebDriver, there is no out-of-the box solution for Object identification and repository. This furthermore increases the relevance and importance of a good way of managing things.
  • In an Agile based project, you can add object place holders so that as development is happening, even automation can begin in parallel.
  • Identify objects in the Object Repository that are no longer available in the AUT
  • Easy navigation when the size of the Object Repository grows exponentiall
#-----------------------------------------------------------------
#Naming Convention for Objects in OR
#-----------------------------------------------------------------

Name your page in this manner: 
Project.PageName.Functionality.ObjectType
e.g - GoogleProject.HomePage.SignIn.Link

the objects can be any of these:
# Button
# Calendar
# ComboBox
# CheckBox
# Dialog
# Frame
# Image
# Label
# Link
# Listbox
# MenuHeader
# MenuItem
# ProgressBar
# RadioButton
# Table
# TextBox
# TextArea
# Window

Once you know all the objects make sure that you place them in the right bucket:
Some examples:

#Button
HomePage.SignIn.Button=xpath://*[@name='login-submit']
all buttons

#Checkbox
HomePage.RememberMe.CheckBox=xpath://*[@class='input-remember-me']

# Frame
HistoryPage.QueryForm.Frame=xpath:.//iframe[@id='iframePage']

#Label 
AccountSummaryPage.Main.Label=xpath://*[@class='money bold Main Wallet r-mainWallet']

#Links

#MenuHeader

#MenuItem

# RadioButton

#Table

#Textbox

#TextArea

Happy Testing!



Tuesday

TestComplete for testing mobile web applications

Automation has evolved with time, Today the industry demands automation on mobile platforms as much as on the workstations.

After evaluating quite a few tools, I see that the easiest way to automate web applications for a mobile device is by using TestComplete: If you would want to do a POC yourself follow these simple steps and you will be ready to automate a lot more!
  • Uses Google Chrome’s mobile browser emulation. 
  • You can create automated GUI tests and functional tests of your mobile Web apps, and make sure they work fluently on multiple mobile devices with different aspect ratios and screen resolutions.
  • Chrome uses Webkit Browser Engine
  • Built-In Mobile Browser Definitions

  • Keyword Driven Mobile Web Mobile Web Testing

Let's get to the meat of things, How do you create your Mobile Web Tests?
  1. Create a New Project for POC
  2. Setup Chrome with the test case settings 
  3. To add a mobile browser profile to your test project:
    • Start test recording.
    • Select a mobile browser profile from the drop-down list on the Recording toolbar. TestComplete will launch the emulator with the selected profile.
    • Open your tested web site in the mobile browser emulator.
    • Perform test actions (navigate through web pages, fill out forms and so on) and create checkpoints for the tested web site.
    • Stop test recording.
  4. Run the test and modify if need be!
You have created your first mobile automated script!

Let's make these tests cross browser tests

In keyword tests, you can use the Virtual Browser Loop operation to repeat test operations in different mobile browsers.
  1. Insert the Virtual Browser Loop operation at the beginning of the test and configure its parameters:
    • Select whether to use all enabled mobile browser profiles or just specific ones.
    • Specify the URL of the tested web site.
  2. Delete the recorded Run Virtual Browser and browser.ToUrl operations at the beginning of the test. The Virtual Browser Loop operation replaces them.
  3. Place the test operations inside the loop (indented to the right of it).
  4. Before the end of the loop, add an operation that would close the browser emulator. For example, you can use the On-Screen Action operation to call the Close method of the Aliases.browser object.
During the test run, the Virtual Browser Loop operation launches the mobile browser emulator with each of the specified browser profiles in turn and executes the loop’s child operations against the tested web site in the emulator.