Search This Blog

Tuesday, November 18, 2014

Logging using AbstractWebDriverEventListener/WebDriverEventListener

WebDriverEventListener is an Interface and AbstractWebDriverEventListener is an abstract class. These are used for logging before an event occurs.They behave similar to the listeners(iTestListener) in TestNG.

It has few custom abstract methods defined under the class/interface.In order to use these listener one has to extend AbstractWebDriverEventListener  or implement WebDriverEventListener and the custom class has to override the below methods.







Sample Implementation

I have created an custom webdriver logger class ("WebdriverLogger") which implements the webdriver event listener interface and overrides all methods under it.Find the Sample Page below:

WebdriverLogger.class

 public class WebdriverLogger implements WebDriverEventListener{  
      @Override  
      public void beforeNavigateBack(WebDriver arg1){  
           System.out.println("beforeNavigateBack");  
      }  
      @Override  
      public void afterNavigateBack(WebDriver arg1){  
           System.out.println("afterNavigateBack");  
      }  
      @Override  
      public void afterScript(String arg0, WebDriver arg1){  
           //-Add Code  
      }  
      @Override  
      public void beforeScript(String arg0, WebDriver arg1){  
      }  
      @Override  
      public void beforeFindBy(By arg0, WebElement arg1 , WebDriver arg2){  
      }  
      @Override  
      public void afterFindBy(By arg0, WebElement arg1 , WebDriver arg2){  
      }  
      @Override  
      public void beforeClickOn(WebElement arg1 , WebDriver arg2){  
           System.out.println("beforeClickOn");  
      }  
      @Override  
      public void afterClickOn(WebElement arg1 , WebDriver arg2){  
           System.out.println("afterClickOn");  
      }  
      @Override  
      public void beforeNavigateForward(WebDriver arg2){  
      }  
      @Override  
      public void afterNavigateForward(WebDriver arg2){  
      }  
      @Override  
      public void beforeNavigateTo(String url, WebDriver arg2){  
           System.out.println("beforeNavigateTo");  
      }  
      @Override  
      public void afterNavigateTo(String url, WebDriver arg2){  
           System.out.println("afterNavigateTo");  
      }  
      @Override  
      public void afterChangeValueOf(WebElement arg0, WebDriver arg1){  
      }  
      @Override  
      public void beforeChangeValueOf(WebElement arg0, WebDriver arg1){  
      }  
      @Override  
      public void onException(Throwable t, WebDriver arg1){  
           System.out.println("Exception Caught"+t.getMessage());  
      }  
 }  

Tests have been defined in a separate class 'TestWebdriverListener' which adds the event and triggers the logging process.

TestWebdriverListener.java

public class TestWebdriverListener {  
      private static WebDriver driver;  
      private static EventFiringWebDriver edriver;  
      @BeforeMethod  
      public static void setUp(){  
           driver=new ChromeDriver();  
           edriver=new EventFiringWebDriver(driver);  
           edriver.register(new WebdriverLogger());  
           edriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);  
      }  
      @Test  
      public static void testMobikwik(){  
           edriver.navigate().to("https://www.mobikwik.com/");  
           //edriver.findElement(By.xpath("//*[@id='gs_htif0']")).sendKeys("George Bernard Shaw");  
           edriver.findElement(By.xpath("//ul[@class='user-auth-nav nav-secondary sub-block quarter flushright hud-light']//li[@class='sub-block one-w glued tiny']/a")).click();  
      }  
      @AfterMethod  
      public static void tearDown(){  
           edriver.quit();  
      }  
 }  

Sample Output

 Starting ChromeDriver (v2.9.248315) on port 45663  
 beforeNavigateTo  
 afterNavigateTo  
 beforeClickOn  
 afterClickOn  
 PASSED: testGoogle  
 ===============================================  
   Default test  
   Tests run: 1, Failures: 0, Skips: 0  
 ===============================================  

Monday, November 17, 2014

Assertions in SoapUI

Assertions in SoapUI are only applicable to test requests under test steps.We put assertions to understand the behavior of tests.Tests generally passes or fails depending upon the test(having assertion point) that we have defined.Assertions are of many types in SoapUI. I'll be discussing few common assertions here.
SoapUI has the below list of assertions:
  • Property Content
    • Contains
    • Not Contains
    • Xpath Match
    • XQuery Match
  • Compliance,Status and Standards
    • Invalid HTTP Status Codes
    • Schema Compliance
    • Valid HTTP Status Codes

Contains

This assertion ensures that the parsed string is a substring of the response token received.Below is the sample response on which most of the assertions will be discussed.

 <Response xmlns="http://localhost/rest-assured-example/service/single-user">  
   <email>test@hascode.com</email>  
   <firstName>Tim</firstName>  
   <id>1</id>  
   <lastName>Testerman</lastName>  
 </Response>  

Contains assertion takes 2 types of input:
  • String
  • Regex Pattern
String be defined below:














Contains assertion with RegEx:



Not Contains

This too used in the same way we used Contains assertion.

Xpath Match

User needs to define namespace in order to form an xpath.Namespace is nothing but the reference to the parent node.

Xquery Match

Xquery match is applicable to only xml responses.Its as similar as Xpath.Find the sample assertion below:





















Hope it helps :)

Wednesday, November 12, 2014

Understanding SoapUI Layout

SoapUI has a very user friendly layout which indirectly follows the testing terminology to define the structure hierarchy.Below diagram explains it very well:







































As per the above structure, tests and services are present at the same label.Each test steps contains a set of test requests on which assertions can be added.Now notice the below diagram which shows the internal layout/structure heirarchy:









Hope it helps :)

Monday, November 10, 2014

JSON Schema Validation Using REST-assured Framework

JSON Schema

  • IS a JSON based data format
  • Represents the structure of JSON data in terms of few attributes like : 'type','description','required' etc.
  • Follows a hierarchy(object-attribute) of representation
  • Every JSON returned has been based upon a format which is called JSON Schema

Test Case

Scenario: Verify the JSON returned from a service resource follows a JSON Schema
@Given:  WebService Resource URL [http://localhost:8080/rest-assured-example/service/single-user]
@Input:    
  • Generate JSON schema file and put it on the classpath root
  • Specify JAR download dependency of Rest-Assured JSON Validator Schema in pom.xml

Generating JSON Schema

Below is the sample JSON response returned when /service/single-user is accessed:

 {  
   "email": "test@hascode.com",  
   "firstName": "Tim",  
   "id": "1",  
   "lastName": "Testerman"  
 }

Corresponding JSON schema can be obtained from here and JSON schema file can be generated which would look like this:

{  
      "type":"object",  
      "$schema": "http://json-schema.org/draft-03/schema",  
      "id": "http://jsonschema.net",  
      "required":false,  
      "properties":{  
           "email": {  
                "type":"string",  
                "id": "http://jsonschema.net/email",  
                "required":false  
           },  
           "firstName": {  
                "type":"string",  
                "id": "http://jsonschema.net/firstName",  
                "required":false  
           },  
           "id": {  
                "type":"string",  
                "id": "http://jsonschema.net/id",  
                "required":false  
           },  
           "lastName": {  
                "type":"string",  
                "id": "http://jsonschema.net/lastName",  
                "required":false  
           }  
      }  
 }  

Identify Root Classpath & Save the JSON Schema


Step-1: Normally we face problem while identifying Root Classpath file.In these case you can use the below code snippet to find out the path:

 System.out.println(this.getClass().getResource("/").getPath());  

Step-2: Save the above schema content in a file say: getService.json and put it under the root classpath(which we go from Step-1).

Specify JSON Validator Schema Dependency

Below is the Dependency snippet which can be specified in POM.xml in order to download the dependency:

      <dependency>  
           <groupId>com.jayway.restassured</groupId>  
           <artifactId>json-schema-validator</artifactId>  
           <version>2.2.0</version>  
      </dependency>  

Write Your Test

Before we write the test,We need to import matchesJsonSchemaInClasspath static method using static import as shown below:

 import static com.jayway.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;  

Define your unit test like below:
     @Test  
      public void testJsonSchema(){  
           //Uses the generated schema to Assert  
           get("http://localhost:8080/rest-assured-example/service/single-user").then().assertThat().body(matchesJsonSche  maInClasspath("getService.json"));  
      }  

Troubleshooting

Exception : java.lang.IllegalArgumentException: Schema to use cannot be null

 java.lang.IllegalArgumentException: Schema to use cannot be null  
      at com.jayway.restassured.module.jsv.JsonSchemaValidator.validateSchemaIsNotNull(JsonSchemaValidator.java:240)  
      at com.jayway.restassured.module.jsv.JsonSchemaValidator.access$100(JsonSchemaValidator.java:75)  
      at com.jayway.restassured.module.jsv.JsonSchemaValidator$JsonSchemaValidatorFactory.create(JsonSchemaValidator.java:251)  
      at com.jayway.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchema(JsonSchemaValidator.java:161)  
      at com.jayway.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath(JsonSchemaValidator.java:117)  
      at testcases.ApiTesting.testJsonSchema(ApiTesting.java:19)  
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
      at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)  
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)  
      at java.lang.reflect.Method.invoke(Unknown Source)  
      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)  
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)  
      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)  
      at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)  
      at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)  
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)  
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)  
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)  
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)  
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)  
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)  
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)  
      at org.junit.runners.ParentRunner.run(ParentRunner.java:300)  
      at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)  
      at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)  
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)  
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)  
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)  
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)  

Solution: Generally this exception noticed when we have the JSON schema file which is absent on the root classpath. Please use the above Step-1 and Step-2 to solve this out.

Hope this helps!!

Thursday, November 6, 2014

Never Say REST Protocol & SOAP Service

I am now a days learning and exploring Webservices Testing.During last couple of month, Whatever blog,sites that i visited i was always getting to see few posts/content related to Webservices testing,SoapUI etc etc.This is the only which forced me to get inclined towards this field.Then i started reading articles,searching for video tutorials,going through wiki.After few days of exploration, i understood that in the field of Webservice Testing, you need to be pretty much clear on the concept,terminology.I would like to discuss most commonly used terminology here in this post.

SOA(Service oriented Architecture)

Service is as simple as a business unit/functionality which is really independent and has a consistent outcome.Service is :

  • Loosely Coupled
  • Executable unit
  • Having consistent set of outcome
Example:
Customer-care,Hospitals providing health services,Restaurants etc etc.

SOA


Human being can very well talk with an web application and can have a good interaction whereas earlier it was not possible for two software to communicate with each other and SOA was the solutions for it.It is a kind of architecture which is the combinations if services and messages.Below diagram explains it better:














If you look at the above diagram , you can see it has 3 components:

  • Service Consumer
  • Service Provider
  • Broker/3rd Party

Simple Analogy

Lets say, i have a car which got some minor dents due to an accident.Now i need to fix these dents.I went to the Dealer(Chevvy) and i explained everything to the Receptionist guy.Now that guy helped me to complete the registration process and he introduced me to the Mechanical Dept. who will taking up the dent work and finally he fixes it and closes the job sheet.Now:

  • Me: The service consumer here who need the service(Fixing of dent work)
  • Receptionist Guy: Broker who introduces me  to correct service provider
  • Mechanical Dept: Service provider

REST

REST stands for Representational State Transfer which is an architectural style(concept,theory) and it implements SOA and bult on the top of HTTP.Hence it has few simple http methods like: GET,PUT,DELETE,POST etc.





SOAP

SOAP stands for Simple Object Access Protocol and it is used to establish a communication between two services.Requests and responses are represented in the form of xml notation.















SOAP is a protocol which helps in communicating in between two services.SOAP request can be understood by looking at the envelop.Soap envelop contains Header and body which creates a representation and distinguishes it among other protocols.

Note:

  • REST is not a protocol
  • SOAP is not a Service
  • WSDL file is used to register service description into UDDI(Broker)
  • SOAP request always has a wsdl file where REST services are not involved with any