Saturday, 25 February 2017

Automating REST APIs Series.
PART 2: Using HttpComponentClient

       In this post, we are going to discuss about HttpComponentClient which can be used for automating your REST services.

Concept:
To start with, add the below dependency in your project POM file
            <dependency>
          <groupId>org.apache.httpcomponents</groupId>
          <artifactId>httpclient</artifactId>
          <version>4.3.5</version>
       </dependency>

The general process for using HttpClient consists of a number of steps:
  1. Create an instance of HttpClient.
  2. Create an instance of the method of requirement. The URL to connect to is passed in to the the method constructor.
  3. Tell HttpClient to execute the method.
  4. Read the response.
  5. Release the connection.
  6. Deal with the response.
1. Create an instance of HttpClient:
Instantiate the closeableHttpClient client with default instance.
    CloseableHttpClient httpclient = HttpClients.createDefault();
2. Creating a Method:
The various methods defined by the HTTP specification correspond to the various classes in HttpClient which implement the HttpMethod interface. Below are the most used Actions and their instantiation. 

   For GET: HttpGet httpGet = new HttpGet(url);
   For POST: HttpPost httpPost= new HttpPost(url);
   For PUT: HttpPut httpPut = new HttpPut(url);
3. Execute method:
The actual execution of the method is performed by calling executeMethod on the client 
and passing in the method to execute. Since networks connections are unreliable, we also 
need to deal with any errors that occur.  
       HttpResponse httpResponse;
        try {
            httpResponse = httpGet .execute(httpRequest);
        } catch (IOException e) {
            // throw the exception here;
        }catch (HttpException e) {
            // throw the exception here;
        }
4. Read the response:
To Read the response, first we need to get the entity of it and then with the help of IOUtils 
we need to copy to the response string.
       StringWriter writer = new StringWriter();
        try {
            if(null != httpResponse.getEntity()) {
                IOUtils.copy(httpResponse.getEntity().getContent(), writer);
            }
        } catch (IOException e) {
            //throw the exception here;
        }
   String responseBodyString = writer.toString();
5. Release the connection:
This is a crucial step to keep things flowing. We must tell HttpClient that we are done with 
the connection and that it can now be reused. Without doing this HttpClientwill wait 
indefinitely for a connection to free up so that it can be reused.
               method.releaseConnection();

Let's look at the full implementation below:
CloseableHttpClient client = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("http://targethost/homepage");
HttpResponse httpResponse1;
   try {
       httpResponse1 = client.execute(httpGet);
   } catch (IOException e) {
      // throw the exception here;
   } catch (HttpException e) {
        // throw the exception here;
    }
try {
   System.out.println(httpResponse1.getStatusLine());
   StringWriter writer = new StringWriter();
    try {
       if(null != httpResponse1 .getEntity()) {
            IOUtils.copy(httpResponse1.getEntity().getContent(), 
              writer);
        }
    } catch (IOException e) {
        //throw exception here
    }
    String responseBodyString = writer.toString();
} finally {
    httpResponse1.close();
}

//This is for the POST action.
HttpPost httpPost = new HttpPost("http://targethost/login");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("username", "vip"));
nvps.add(new BasicNameValuePair("password", "secret"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
HttpResponse httpResponse2;
   try {
       httpResponse2 = client.execute(httpPost);
   } catch (IOException e) {
       // throw the exception here

   } catch (HttpException e) {
        // throw the exception here;

    }

try {
  System.out.println(httpResponse2.getStatusLine());
  StringWriter writer = new StringWriter();
    try {
      if(null != httpResponse2.getEntity()) {
        IOUtils.copy(httpResponse2.getEntity().getContent(), writer);
      }
    } catch (IOException e) {
        //throw the exception here
    }
   String responseBodyString = writer.toString();
} finally {
    httpResponse2.close();
}
For the big scale projects we might need to customize the httpconnectClient for https
requests and also for network bypassing.
In our next posts, we will discuss about UrlconnectClient and RestAssuredClient

Thursday, 27 October 2016

Automating REST APIs Series.
PART 1: Using Jersey Client

        In this series we are going to learn about automating REST APIs. This post is dedicated for Jersey Client. 

Below link has the basic information about REST APIs
http://www.qaautomationsimplified.com/api/an-introduction-to-rest/ 

Idea behind using Jersey Client+Java:
1. We will be creating instances of Jersey client for various methods like GET,PUT,POST etc. by mentioning the request URL

 In our example We will be sending GET Request to http://restcountries.eu/rest/v1/name/norway

  So we will be creating instance of JerseyClient and setting the URL as :  http://restcountries.eu/rest/v1/name/norway

2. We will be composing the request body as JSON

  As the above example is a GET request , so it can not have a request body. In case of    POST, PUT etc if we need to set the request body then that needs to be represented in  JSON format according to the design if the API. So we will be  extensively using org.json  methods/APIs to build JSON objects and set it as Jersey request body.

3. Execute the desired Jersey method when headers etc are all set

 As the request body contains request information in JSON format , so we need to set a    header – Content-Type as ‘application/json’ , which gives instruction to server that  request body is represented as JSON and should be parsed accordingly to process the  request.

4. Capture the response and convert it to a JSON object.

 Response object is captured and parsed to a JSON object.

5. Perform the assertions based on the requirements.

Steps to automate REST APIs using Jersey Client:
#1. Create a Maven Project
       
       To know about creating a simple maven project refer the below link

#2. Add the below dependencies to pom.xml
            <dependency>
          <groupId>com.sun.jersey</groupId>
          <artifactId>jersey-client</artifactId>
          <version>1.18.1</version>
      </dependency>
      <dependency>
          <groupId>com.sun.jersey</groupId>
          <artifactId>jersey-json</artifactId>
          <version>1.18.1</version>
               <exclusions>
                  <exclusion>
                     <groupId>com.sun.xml.bind</groupId>
                     <artifactId>jaxb-impl</artifactId>
                   </exclusion>
               </exclusions>
      </dependency>
      <dependency>
           <groupId>com.sun.jersey</groupId>
           <artifactId>jersey-bundle</artifactId>
           <version>1.10</version>
      </dependency>
      <dependency>
           <groupId>org.json</groupId>
           <artifactId>json</artifactId>
           <version>20140107</version>
       </dependency>


#3. After adding the dependency, create a class and below is the sample code for    checking.

     In this example I have used a public webservice which has the details about European countries and their currencies etc. 
      
     Here I am going to validate the capital of norway.
     
 Client _client = Client.create();
WebResource wr = _client.resource("http://restcountries.eu/rest/v1/name/norway");
 WebResource.Builder builder = wr.getRequestBuilder();
 //Adding headers to the request
 builder = builder.header("Accept", "application/json");
 //Fetching Response from API
 ClientResponse cr = builder.method("GET", ClientResponse.class,null);
 String responseBodyString = cr.getEntity(String.class).trim();
 System.out.println("This is the response: "+responseBodyString);
 System.out.println(cr.getStatus());
 //Fetching response in JSON
JSONArray jsonResponse = new JSONArray(responseBodyString);
System.out.println(jsonResponse);
//Fetching value of capital parameter
String capital = jsonResponse.getJSONObject(0).getString("capital");
//Asserting that capital of Norway is Oslo
Assert.assertEquals(capital, "Oslo");

In the long scale projects, we may need to handle request and response more in terms of json. We can use below dependency for handling json response/request

            <dependency>
          <groupId>com.google.code.gson</groupId>
          <artifactId>gson</artifactId>
          <version>2.2.4</version>
      </dependency>


In our next post we will discuss about Apache httpclient.

Sunday, 31 July 2016

Finding JavaScript errors through Webdriver

        Now a days it became very common that many of the applications are using extensive java script for the client side transactions. So, from the QA perspective it is very important to validate those Java script errors irrespective of whether those errors or warnings affect the application in near future or not. There are options like firebug, chrome developer tool, IE Developer tool, which gives the java script errors on their consoles. 

         We can automate this by using Selenium Web driver API. Below code snippet can be used to get those java script errors. Here I used one sample site which has some java script errors

     public void consoleEntries(LogEntries consoleEntries) {
         for (LogEntry logEntry : consoleEntries) {
               System.out.println("Log Level: " + logEntry.getLevel().toString());
               System.out.print(" Log Message: " + logEntry.getMessage().toString());
          }
    }


  @Test
  public void getJavaScriptErrors() throws Exception {
  String url = "http://www.softwaretestingtricks.com/";
  WebDriver webDriver = new FirefoxDriver();
  webDriver.get(url);
   LogEntries logEntries = webDriver.manage().logs().get(LogType.BROWSER);
   consoleEntries(logEntries);
  webDriver.quit();
  }


To reduce the no.of logs, we can set the log preferences. So, that we will get only desired logs. That can be done as below

        DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
LoggingPreferences loggingPreferences = new LoggingPreferences();
loggingPreferences.enable(LogType.BROWSER, Level.SEVERE);
desiredCapabilities.setCapability(CapabilityType.LOGGING_PREFS, loggingPreferences);
webDriver = new FirefoxDriver(desiredCapabilities);

Saturday, 18 June 2016

Winium for automating Desktop Applications

Winium is a Automation framework for Windows Applications. It is a open source tool from 2GIS. Winium supports
  • Windows Desktop (WPF, WinForms) Apps
  • Windows Store or Universal Apps for Windows Phone
  • Windows Phone Silverlight Apps
But in this post we are going to discuss only about Winium for Desktop application automation.

We know that selenium supports only web applications. There are multiple other tools that we discussed in our previous blogs like AutoIT, Sikuli can be used to automate Windows based applications. But winium has the below advantages comparing to AutoIT and Sikuli.
  1. As discussed in our previous blogs, to use Auto IT, We have to use some windows bridge to access the methods in it. But Winium comes as Java API and also it is implemented on JSONWire protocal that is used by selenium.
  2. We can also write tests in any programming language that is supported by selenium.
  3. It supports wide magnitude of applications comparing to AutoIT.

Technically, Winium.Desktop is an http client. It implements JSWP protocol and uses Cruciatus to work with UI elements. Essentially, this is an implementation of WebDriver for Windows-based desktop applications. It uses regular Selenium bindings with Winium. Desktop in order to test Windows-based desktop applications.


Below are the features of Winium.
  • Automates native windows desktop app(winforms, WPF, everyapp that uses MS accessibility)
  • compatible with JSON wire protocal
  • Full access to desktop and UI
  • Protocal extensions for desktop specific elements
  • We can write tests in any programming language which Selenium Web driver supports

Below are commands that are supported by Winium.


Command Query
NewSession POST /session
FindElement POST /session/:sessionId/element
FindChildElement POST /session/:sessionId/element/:id/element
ClickElement POST /session/:sessionId/element/:id/click
SendKeysToElement POST /session/:sessionId/element/:id/value
GetElementText GET /session/:sessionId/element/:id/text
GetElementAttribute GET /session/:sessionId/element/:id/attribute/:name
Quit DELETE /session/:sessionId
ClearElement POST /session/:sessionId/element/:id/clear
Close DELETE /session/:sessionId/window
ElementEquals GET /session/:sessionId/element/:id/equals/:other
ExecuteScript POST /session/:sessionId/execute
FindChildElements POST /session/:sessionId/element/:id/elements
FindElements POST /session/:sessionId/elements
GetActiveElement POST /session/:sessionId/element/active
GetElementSize GET /session/:sessionId/element/:id/size
ImplicitlyWait POST /session/:sessionId/timeouts/implicit_wait
IsElementDisplayed GET /session/:sessionId/element/:id/displayed
IsElementEnabled GET /session/:sessionId/element/:id/enabled
IsElementSelected GET /session/:sessionId/element/:id/selected
MouseClick POST /session/:sessionId/click
MouseDoubleClick POST /session/:sessionId/doubleclick
MouseMoveTo POST /session/:sessionId/moveto
Screenshot GET /session/:sessionId/screenshot
SendKeysToActiveElement POST /session/:sessionId/keys
Status GET /status
SubmitElement POST /session/:sessionId/element/:id/submit

Disadvantages:
  • It uses real mouse and key board events, i.e You can't run more than one session on same machine, or use mouse while tests are running.
  • If the app runs in the background and remains running there, then it will not work appropriately.
  • It is sometimes difficult to get the text from component that displays the output. Then you receive the error message:  NO Text property. The reason is probably that this type of component is defined as Image.
In this post we are going to learn about writing a text into notepad by using winium. Please follow the steps given below.

Step 1:
Download the below jars
http://mvnrepository.com/artifact/com.github.2gis.winium/winium-elements-desktop/0.1.0-1
http://mvnrepository.com/artifact/com.github.2gis.winium/winium-elements-desktop/0.2.0-1

Along with these two jars you need to have selenium latest jar as well. You can get the latest selenium jar from the below path.
http://docs.seleniumhq.org/download/

Step 2:
Download Winium.Desktop.Driver.exe file from https://github.com/2gis/Winium.Desktop/releases (Latest). Extract the zip file

Step 3:
Run the Winium.Desktop.Driver.exe file (by double clicking the Winium. Desktop.Driver.exe file). So that a Winium desktop server will be started and running at port 9999.

Step 4:
Create a sample Java project and add the downloaded jars into the class path of the project and also TestNG Library. Now create a class and use the below code.

package com.src.Nainappa.test;
import java.io.IOException;
import java.net.URL;
import org.openqa.selenium.winium.DesktopOptions;
import org.openqa.selenium.winium.WiniumDriver;
import org.testng.annotations.Test;

public class NotepadTest {
@Test
public void test() throws IOException{
DesktopOptions options= new DesktopOptions();
options.setApplicationPath("C:\\WINDOWS\\system32\\notepad.exe");
try{
WiniumDriver driver=new WiniumDriver(new URL("http://localhost:9999"),options);
driver.findElementByClassName("Edit").sendKeys("This is sample test");
driver.close();
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
}

Step 5:
Run this code as TestNG Method. It opens the notepad and enters the text on the note pad and also tries to close it.

If anybody is wondering how to get to know the properties of the elements, we have multiple ways.

1. Renorex offers free spy. We can download it from the below path and use it.
   http://www.ranorex.com/test-automation-tools/ranorex-spy.html

2. The other way is White tool. You can download the entire tool from the below path.
   https://github.com/TestStack/White
   Extract the Zip file and you will see a file called UISpy.exe. This can also be used for spying on the elements.

We will see automating the Windows phone applications in our next post.

Sunday, 21 February 2016

Galen Framework for RWD/Layout/Cross Browser Automation

   Automating the layout testing for websites is always a challenging. But is very important in the current industry as the Responsive Web Design has become more popular than ever in the Front End Development. Testing these responsive web application manually is a herculean task as the testing spans across multiple resolutions,devices and browsers. Huge amount of manual effort and infrastructure support is required in order to  cover the above scenarios.

      In the quest of finding out sophisticated tool I had two things in mind. First thing was, tool should be able to integratable with any Selenium based automation frameworks by considering its usage in the industry. Second thing was, tool should be Open source. I was able to find out a very good tool which can be integrated with Selenium named Applitools. But applitools is a Paid tool. I have already shared a post that explains how applitools can be used with selenium framework. You can find the post here.


    This time I am going to share a Open source tool which can be used for RWD Layout tests.

    Galen Framework is built on top of selenium. This checks each individual component of the page with another element.The fundamental testing concept in Galen Framework centers on checking the location and size of all page elements relative to each other. This way, you can describe the layout for any browser window’s size and you don’t have to use absolute positioning. Selenium offers functionality for getting location and dimension of element in all browsers. When it comes to testing a responsive layout it works in a following way:

1. Open a page in browser
2. Resize it to specified size
3. Test the layout according to user-defined specs

     Galen allows you to express your expectations towards website layout and then uses selenium to retrieve the information about the page elements. These expectations should be written in a special laguage called GalenSpec language. The Galen Specs language was designed to resemble natural English as closely as possible and has been implemented in a semi-Markdown way. The below link gives you  more details about Galen Spec Language.


    Once your test is completed Galen provides very comprehensive reporting. Galen provides good explanations using Object Definition names in reports when a test failed or passed. You can also have a nice screenshot in a popup after clicking on the failed test.It highlights the failed object on the screenshot. It will show you what's wrong at a glance. These reports would automatically generated under "target/galen-html-reports". But these can also be saved into user specific HTML Reports.


Once you click on any report, it opens the below view with hierarchical details.

  The initial version of Galen Framework was in JavaScript. But now it is supporting Java as well. Here is the sample project with Galen Java API. 


You can download this project and add your own pages with the Galen Spec Language. This can also be integrated with the existing java and selenium based automation frameworks by its Maven dependency. 

Below are some other features of Galen:
1. We can use it for image comsprison as well with percentage  of tolerance
2. This can be iintegrated with saucelabs for cloud based devices
3. This can be used for internatiolization
4. Galen also tests the Colors of your website
5. Galen is very good for cross browser testing
6. This will fit into the behavior testing processes such as BDD,TDD etc.

Conclusion:
In my personal opinion, this is a very good open source tool for RWD automation. But if you are looking for only layout testing, I would use it for the main lines of a project like the global layout of a given page or when a feature really needs a particular layout. I would recommend using Galen aside your daily tests, it's just another security before going in production. This can also be used by the front end developers before they push code changes to QA. 

Sunday, 20 September 2015

Cobertura War Instrumentation and Coverage in a web application

In a day to day work we typically run our tests and presumably check that we are getting the expected results.Our tests may all pass with flying colours, but if we've only tested 50% of the code, how much confidence can we have in it? So a step ahead would be to ensure how much of the application code is exercised by our tests which ensures the quality of the tests that we typically run and thus code coverage comes into picture.

What is Code Coverage?
Code Coverage is a measurement of how many lines/blocks of the application code are executed while the automated/unit tests are running. Though code coverage is a white box testing methodology(as it requires knowledge of and access to the code itself rather than simply using the interface provided), we might come across situations where we need to analyse/collect code coverage metrics for our functional test cases.This post briefs the need of code coverage,coverage analysis,instrumentation for functional test cases with an example using Cobertura.

How is Code Coverage achieved?
Code coverage is collected by using a specialized tool to instrument the binaries to add tracing calls and run a full set of automated/unit tests against the instrumented product. A good tool will give you not only the percentage of the code that is executed, but also will allow you to drill into the data and see exactly which lines of code were executed during particular test. There are many coverage tools in market for Java Code Coverage -Cobertura,Clover,Emma,Jcoverage.In this post we will generate coverage metrics using cobertura -one of the most widely used java coverage tool as it has edge over other tools.

Features of Cobertura:
  • Open source Java tool.
  • Can be executed from simple ant build script.
  • Instruments Java bytecode after it has been compiled.
  • Can generate reports in HTML/XML by class name, percent of lines covered, percent of branches covered, etc.
  • Shows the percentage of lines and branches covered for each class, each package, and for the overall project.

What is instrumentation?
Instrumentation is all about manipulating the application code by injecting reporting code into strategic positions. In fact, the art of instrumentation falls in either of the two: class instrumentation and source instrumentation. Not surprisingly, the difference is that class instrumentation injects the reporting code directly into compiled .class files while source instrumentation creates an intermediary version of the sources which are then compiled into the final, source-instrumented .class files. Most of the code coverage tools will follow either of these instrumentation techniques.

For this post we are using a sample war file from (https://tomcat.apache.org/tomcat-6.0-doc/appdev/sample/)for instrumentation wherein for real time scenario,this should be replaced with your application war file.

Sample Cobertura War Instrumentation and Coverage in a web application

PreRequisite:
  • Tomcat 7 and above
  • JDK 1.7 and above
  • Ant 1.8 and above
  • Cobertura 1.9 and above
  • A sample war file for instrumentation/use your application war file

Pre-coverage steps:
  • Extract classes from your war.
  • Create an ant script for instrumenting the classes.
  • Add required libs/dependencies for instrumentation (Sample attached- Refer build.xml and build.properties).
Coverage steps:
  • Perform Cobertura instrumentation using your build target as below.
  • Now we have instrumented classes generated as below ,Replace the generated files in the war (replace with the existing classes) and cobertura.ser file generated.
  • Put your updated war in the tomcat webapps.
  • Put your cobertura.ser file in the tomcat bin .
  • Add cobertura.jar in the tomcat lib .
  • Start your tomcat.
  • Hit the required test cases (run ur web application flows either manually or through your automation scripts)
  • (for this sample war -we are hitting http://localhost:8080/sample home page -this application has Hello page-hello class alone so we are executing a test to hit the hello page)
  • Now put the updated cobertura.ser in the project ant home folder
Post-coverage steps:
  • Run coverage targets as below.
  • Now we have coverage for the test cases that we have run!