Sunday, December 27, 2015

Hooks And Tags On Cucumber JVM

Hooks and Tags are most interesting topic on Cucucmber-JVM.

Hooks is a technique to run set of code before and after the whole Feature or Scenarios. So we need to use

@Before 
     and
@After

annotation for hook feature of Cucumber-JVM. We need to be sure when we use those above mentioned annotation then we should import below mentioned packages on Step generation or Glue Code file

import cucumber.api.java.After;
import cucumber.api.java.Before;


It is possible to define a hook so that it is only executed before or after scenarios that are tagged with a specified annotation

We will define this on Feature file and pass this tag value on @Before or @After method on step file. It should be looked like below:

@Before("@add")
        or
@Before(value={"@add"})
@After(value={"@add"}))

Feature file should be :

Feature: This is a sample feature file
@add
    Scenario: This is a scenario for Adding two number.
        Given Two number as 1 and 6
        When We add this two given number
        Then Sum Result should be 7 

 
We can use AND/OR logic on hooks also.

Syntax for AND logic is:
@Before(value={"@add","@sub"})
@After(value={"@add","@sub"})

Syntax for OR logic is :
@Before(value={"@add,@sub"})
@After(value={"@add,@sub"})

 So AND logic means hooks will be executed when all tags are matched with the feature file tags and OR logic means when any of the tag matched with feature file.

We can also mention the execution order when we will use multiple hooks. Syntax looks like below:

@Before(order=5) 
@After(order =5) 

If we use multiple @Before with different order then lower order number execute first but behavior of  @After method is opposite, upper order number execute first then execute the lower order number.

 Complete Code:

Feature File :

Feature: This is a sample feature file
 

@tag1
    Scenario: This is a scenario for Adding two number.
        Given Two number as 1 and 6
        When We add this two given number
        Then Sum Result should be 7
@tag2 @tag3   
    Scenario: This is a scenario for sub two number.
        Given Two number as 8 and 1
        When We substract this two given number
        Then Sub Result should be 7   
       
@tag4 @tag5
    Scenario: This is a scenario for sub two number.
        Given Two number as 6 and 1
        When We add this two given number
        Then Sum Result should be 7
        And We substract this two given number
        Then Sub Result should be 5   
  
 
 

Glue Code : 

import org.junit.Assert;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

public class SumFeatureTest {
    @Before(order=1,value={"@tag1"})
    public void beforeMethod(){
        System.out.println("This will be executed When Tag Matched With The Following Tag Matched :@tag1. ");
    }
    @Before(order=5,value={"@tag1"})
    public void beforeMethodForOrderSingle(){
        System.out.println("Upper Order Value Execute Later For @Before Method. This Is Executed From Single Tag Method : beforeMethodForOrderSingle ");
    }

    @Before(order=1,value={"@tag4","@tag5",})
    public void beforeMethodAND(){
        System.out.println("This will be executed When Both Of The Following Tag Matched :@tag4 AND @tag5. ");
    }
    @Before(order=5,value={"@tag4","@tag5"})
    public void beforeMethodForOrderAND(){
        System.out.println("Upper Order Value Execute Later For @Before Method. This Is Executed From AND Tag Method : beforeMethodForOrderAND ");
    }
    @Before(order=1,value={"@tag2,@tag3"})
    public void beforeMethodOR(){
        System.out.println("This will be executed When Any Of The Following Tag Matched : @tag2 OR @tag3. ");
    }
    @Before(order=5,value={"@tag2,@tag3"})
    public void beforeMethodforOrderOR(){
        System.out.println("Upper Order Value Execute Later For @Before Method.This Is Executed From OR Tag Method : beforeMethodforOrderOR ");
    }
    @After(order=1)
    public void afterMethod(){
        System.out.println("Lower Order Value Execute Later For @After Method.");
    }
    @After(order =5)
    public void afterMethod1(){
        System.out.println("Upper Order Value Execute First For @After Method.");
    }
    int input1,input2,sumResult,subResult;
    @Given("^Two number as (\\d+) and (\\d+)$")
    public void twoNumberGivenAsAndAnotherIs(int firstInput, int secondInput) throws Throwable {
        input1 = firstInput;
        input2 = secondInput;
    }

    @When("^We add this two given number$")
    public void weAddThisTwoGivenNumber() throws Throwable {
        sumResult = input1+input2;
        System.out.println("sum");
    }
    @When("^We substract this two given number$")
    public void weSubstractThisTwoGivenNumber() throws Throwable {
        subResult = input1-input2;
        System.out.println("sub");
    }
    @Then("^Sum Result should be (\\d+)$")
    public void sumResultShouldBe(int expectedTotal) throws Throwable {
        Assert.assertEquals("Not Matched: ", expectedTotal, sumResult);
    }
    @Then("^Sub Result should be (\\d+)$")
    public void subResultShouldBe(int expectedTotal) throws Throwable {
        Assert.assertEquals("Not Matched: ", expectedTotal, subResult);
    }
   


Runner Class:

import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.SnippetType;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(
        plugin = {
                "html:target/cucumber-html-report",
                "json:target/cucumber.json",
                "pretty:target/cucumber-pretty.txt",
                "usage:target/cucumber-usage.json",
                "junit:target/cucumber-results.xml",
                "progress:target/cucumber-progress.txt"
        },features ={"./sample.feature"},
            glue ={"com/automation/steps"},
            monochrome = true, snippets= SnippetType.CAMELCASE)
public class Runner {
} 

Tuesday, December 22, 2015

Different Option On Cucumber JUnit Runner

We can use different option of Cucumber-JVM JUnit runner using @CucumberOption annotation.

There are so many option available with @CucumberOption annotation.We will discuss in details below :

features : This is the most important part of the cucumber option.It is used to mention the path of the feature files like features ={"./sample.feature"} or mention the only folder of feature file, cucumber automatically get all the feature file in the mentioned path.

glue : This is the another most important part of the cucumber option.It is used to mention the path of the glue code files like glue ={"com/automation/steps"}. Cucumber automatically get all the glue codecorrespondng to the feature file.

snippets : This is used when we try to generate basic code structure with the different syntax style(like camelcase or underscore) from the feature file. We use this option in JUnit runner and run this file, after running this we get the basic method structure for the particular feature file on console of the editor. Syntax looks like this : snippets= SnippetType.CAMELCASE
 

monochrome : It is used to get the better result on console of the editor. Syntax is monochrome = true
 

plugin : It is another most important part of the Cucumber JVM runner option. It is used to generate different type of reporting style. We get html report json report xml report and many more type of report. Syntax is describe below:

        plugin = {
                "html:target/cucumber-html-report",
                "json:target/cucumber.json",
                "pretty:target/cucumber-pretty.txt",
                "usage:target/cucumber-usage.json",
                "junit:target/cucumber-results.xml",
                "progress:target/cucumber-progress.txt"
        }


dryRun : It is used to verify that all steps of the feature file defined on step generator or glue code file or not. Syntax is : dryRun= true
One thing keep in mind that when dryRun=true then entire code should not run only it checks that all the methods matched with feature file or not.  

strict: It is used to verify that all steps of the feature file defined on step generator or glue code file or not.
Syntax is : strict= true
Difference between dryRun and strict is that strict run allow execute the code and report as fail if any steps not implemented on feature code.

tags : It is a another option on Cucumber-JVM JUnit runner by which we can execute mentioned tags Syntax is : tags={"@tag1}.This tag should be mentioned on feature file like 
Feature: This is a sample feature file
@tag1
    Scenario: This is a scenario for Adding two number.
        Given Two number as 1 and 6
        When We add this two given number
        Then Sum Result should be 7


 We will discuss details on later post about this.

So after implement all the details runner class @CucumberOption should be looked like this :

@CucumberOptions(
        plugin = {
                "html:target/cucumber-html-report",
                "json:target/cucumber.json",
                "pretty:target/cucumber-pretty.txt",
                "usage:target/cucumber-usage.json",
                "junit:target/cucumber-results.xml",
                "progress:target/cucumber-progress.txt"
        },features ={"./sample.feature"},
            glue ={"com/automation/steps"},strict = true,
            dryRun= false,monochrome = true, snippets= SnippetType.CAMELCASE,tags={"@tag1"})

Sunday, December 20, 2015

Start Coding With Cucumber JVM

Now we know the basic terms and different component of cucumber. Here we will create a simple program using cucumber-jvm. We will follow the below steps to create a simple projects using cucumber-jvm.

So cucumber-jvm must have three parts
  1. Code Runner Class
  2. Feature File
  3. Glue Code Or Step Generation File.

Step 1:

@RunWith   annotation:

 We need help from JUnit to run cucumber tests. So we need to use @RunWith annotation to call the cucumber class from normal JUnit class and pass Cucumber.class as a parameter in @RunWith annotation and put this annotation above the class name means before the class declaration starts.

So after using this annotation in JUnit class it should look like below :

@RunWith(Cucumber.class)
public class Runner {
}


@CucumberOptions:

features and glue option :

 If we think logically then we can understand that we also need to send the feature file location and glue code or step generation file location. It can be possible using @CucumberOptions annotation and passing feature file location using features={"./newtest.feature"} and passing glue code or step generation file location or package name using
glue ={"com/automation/steps"}.

We can pass multiple features or step generation file in the same project then we pass the multiple file separated by comma then features option should be looks like below 
 features={"./newtest.feature","./newtest1.feature"}

and glue should be looks like:  
 glue ={"com/automation/steps","com/automation/anothersteps"}

So in summary @CucumberOptions should be looks like below
@CucumberOptions( features={"./newtest.feature"},glue ={"com/automation/steps"})

plugin option:

plugin option is used for creating different type of  reporting. Different types of  reports created under the target folder so syntax for creating different type of report is describe below :
        Syntax for html report is                :plugin = {"html:target/cucumber-html-report"}
       
Syntax for json report is                 :plugin = {"json:target/cucumber.json"}         
        Syntax for text report is                  :plugin = {"pretty:target/cucumber-pretty.txt"}
       
Syntax for json usage report is       :plugin = {"usage:target/cucumber-usage.json"}
       
Syntax for xml report is                  :plugin = {"junit:target/cucumber-results.xml"}
Here we also mention the different type of reports format with comma separated option. So @CucumberOption should be looks like below with different type of  reporting option.

@CucumberOptions(
        plugin = {
                "html:target/cucumber-html-report",
                "json:target/cucumber.json",
                "pretty:target/cucumber-pretty.txt",
                "usage:target/cucumber-usage.json",
                "junit:target/cucumber-results.xml",
        })


So at last our runner class should be looks like below:


import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.SnippetType;
import cucumber.api.junit.Cucumber;
@RunWith(Cucumber.class)
@CucumberOptions(
        plugin = {
                "html:target/cucumber-html-report",
                "json:target/cucumber.json",
                "pretty:target/cucumber-pretty.txt",
                "usage:target/cucumber-usage.json",
                "junit:target/cucumber-results.xml",
        },features={"./newtest.feature"},
            glue ="com/automation/steps",
            dryRun=false,monochrome = true, snippets= SnippetType.CAMELCASE)

public class Runner {
}


Step 2:


Now we create a .feature file for a sample. Here we create a scenario where we add two number as 1 and 6 and result should be 7. So our feature file looks like below:

Feature: This is a sample feature file

    Scenario: This is a scenario for Adding two number.
        Given Two number as 1 and 6
        When We add this two given number
        Then Result should be 7

 

Step 3:


 So we are now creating our glue or step definition file for this particular step file. Glue code or step definition file is nothing but a java file. Step definition file should be looks like below :

public class Test {
    int input1,input2,total;
    @Given("^Two number as (\\d+) and (\\d+)$")
    public void twoNumberGivenAsAndAnotherIs(int firstInput, int secondInput) throws Throwable {
        input1 = firstInput;
        input2 = secondInput;
    }

    @When("^We add this two given number$")
    public void weAddThisTwoGivenNumber() throws Throwable {
        total = input1+input2;
    }

    @Then("^Result should be (\\d+)$")
    public void resultShouldBe(int expectedTotal) throws Throwable {
        Assert.assertEquals("Not Matched: ", expectedTotal, total);
    }

}

 Regular expression is used on each annotation so we are now try to understand the meaning of the below regular expression:
^  =  This is used to mentioned that string is starting from here.
$  =  This is used to mentioned that string ends here.
+  =  This is used to find one or more time.
\d =  This is used to represent digit.
\   =  This expression represent the escape characters.

So now question is how we will create the basic structure of glue or step definition file? 

It is very easy we just run the cucumber Runner class after creating the feature file then we observe that something written over the console pane of the eclipse it should be looks like below :

You can implement missing steps with the snippets below:

@Given("^Two number as (\\d+) and (\\d+)$")
public void twoNumberAsAnd(int arg1, int arg2) throws Throwable {
    // Write code here that turns the phrase above into concrete actions
    throw new PendingException();
}

@When("^We add this two given number$")
public void weAddThisTwoGivenNumber() throws Throwable {
    // Write code here that turns the phrase above into concrete actions
    throw new PendingException();
}

@Then("^Result should be (\\d+)$")
public void resultShouldBe(int arg1) throws Throwable {
    // Write code here that turns the phrase above into concrete actions
    throw new PendingException();
}


 Now we remove the comments and PendingException() and implement our logic.

[Note: If we observe deeply then we can understand the method name of auto generated code follow the camel notation because we mention snippets= SnippetType.CAMELCASE on @CucumberOptions annotation on cucumber runner class. Default it follow the underscore notaion for method name]

So our complete code looks like below:

Runner Class :

 

import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.SnippetType;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)

@CucumberOptions(
        plugin = {
                "html:target/cucumber-html-report",
                "json:target/cucumber.json",
                "pretty:target/cucumber-pretty.txt",
                "usage:target/cucumber-usage.json",
                "junit:target/cucumber-results.xml",
        },features ={"./sample.feature"},
           glue ={"com/automation/steps"},snippets= SnippetType.CAMELCASE)

public class Runner {
}

 

Feature File :

 

Feature: This is a sample feature file

    Scenario: This is a scenario for Adding two number.
        Given Two number as 1 and 6
        When We add this two given number
        Then Result should be 7  

 

Glue Code Or Step Definition File:

 

import org.junit.Assert;
import cucumber.api.DataTable;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

public class SumFeatureTest {

    int input1,input2,total;
    @Given("^Two number as (\\d+) and (\\d+)$")
    public void twoNumberGivenAsAndAnotherIs(int firstInput, int secondInput) throws Throwable {
        input1 = firstInput;
        input2 = secondInput;
    }

    @When("^We add this two given number$")
    public void weAddThisTwoGivenNumber() throws Throwable {
        total = input1+input2;
    }

    @Then("^Result should be (\\d+)$")
    public void resultShouldBe(int expectedTotal) throws Throwable {
        Assert.assertEquals("Not Matched: ", expectedTotal, total);
    }
}

Sunday, November 29, 2015

Details Of Feature File

On our previous post we learn how to setup eclipse and netbeans for Cucumber.

Now here we learn the heart of the cucumber that is known as feature file.

Feature file contains the all business logic or acceptance criteria. But we need to write this using specific language which is know as Gherkins.

Gherkins is basically english like language and it hold some keywords. We need to follow this keywords when we write down the feature file.

Keywords are mentioned below :

Feature : This tag contains the feature description.This tag basically required to describe the functionality of the application in brief. One feature file contains only one Feature tag.

Description : This tag contains the details of the Feature file.

Background : Backgrounds allows you to add some context to all scenarios in a single feature. A Background is like an untitled scenario, containing a number of steps. The difference is when it is run: the background is run before each of your scenarios,

Scenario : This tag specify the scenario name and details to check the feature of the application.

Given : The purpose of Given steps is to put the system in a known state before the user (or external system) starts interacting with the system

When : The purpose of When steps is to describe the key action the user performs.

Then : The purpose of Then steps is to observe outcomes. The observations should be related to the business value/benefit in your feature description. The observations should inspect the output of the system.

And : We can use And steps, allowing our Scenario to read more fluently:

But : We can use And steps, allowing our Scenario to read more fluently:

Scenario Outline : We use this when we need to run the same scenario with different data.

Examples : We supply the data to scenario outline using Example tag.

* : This is actually wild character, it can be used for the alternate of the above mentioned keyword.


We will know the details of each keywords on the later post with example.





Saturday, November 21, 2015

Cucumber SetUp in NetBeans

On our previous post we learn how to setup cucumber projects in Eclipse. Now we learn how to setup a NetBeans for cucumber.

Prerequisite:
Need to be installed Java SDK and NetBeans. We discussed here how to install Java SDK and Netbeans.

Step 1:

We need to download below jars :
a. cucumber-core-1.2.4.jar (This jar contains all the story terminology utilized from writing scenarios and implemented in the defining methods.)
b. cucumber-java-1.2.4.jar (This provides the Java runtime environment for all tests.)
c. cucumber-jvm-deps-1.0.5.jar (This module provides the Java parser for cucumber)
d. gherkin-2.12.2.jar   (gherkin is the language cucumber’s feature stories are written in, and this module contains parsing instructions for the features)
e. cucumber-junit-1.2.4.jar (This jar required for customized JUnit framework with cucumber.)
f. cucumber-html-0.2.3.jar (This provides a nice output in html format upon test completion.)

We can download this jars from  maven repository

and from sonatype repository.


now add all the jars in our projects.After adding all the jar project looks like below.

Step 2 :

Now we need to install cucumber plugin for Netbeans.

So open this url and click on download button. We found one .nbm file downloaded in our preferred download location.



Step 3:

Now we need to install this in Netbeans.
a. Click on Tools-> Plugins option.

b. Click on "Downloaded" tab from Plugins window and again click on "Add Plugins" button to select downloaded Netbeans Cucumber plugin file.

c. On next window shows  check box select this check box.

d. Accept term and condition.

e. Restart the Netbeans IDE.

After successful installation of Cucumber plugin .feature file in projects should be shown like below.




Cucumber file option should be available in NetBeans when we try to add any file in our project.



Saturday, November 14, 2015

Cucumber SetUp In Eclipse

On previous post we learn what is BDD and TDD and we also know the name of different type of BDD tools, Cucumber is one of those.

Here we learn how to configure cucumber in eclipse.

Prerequisite:
Need to be installed Java SDK and also downloaded the Eclipse. This configuration details describe here.

Now we download all the required jars for Cucumber setup.

Step 1: 

We need to download below jars :
a. cucumber-core-1.2.4.jar (This jar contains all the story terminology utilized from writing scenarios and implemented in the defining methods.)
b. cucumber-java-1.2.4.jar (This provides the Java runtime environment for all tests.)
c. cucumber-jvm-deps-1.0.5.jar (This module provides the Java parser for cucumber)
d. gherkin-2.12.2.jar   (gherkin is the language cucumber’s feature stories are written in, and this module contains parsing instructions for the features)
e. cucumber-junit-1.2.4.jar (This jar required for customized JUnit framework with cucumber.)
f. cucumber-html-0.2.3.jar (This provides a nice output in html format upon test completion.)

We can download this jar from  maven repository

and from sonatype repository.

now add all the jars in our projects.After adding all the jar project looks like below.


Step 2:
We need to add cucumber plugin in eclipse. There are so many plugin available for cucumber in eclipse.

We can add
a. Cucumber JVM Eclipse Plugin
                     OR
b. CucumberPeople

Lets starts with one by one we can install Cucumber JVM Eclipse Plugin in two different way

a. Cucumber JVM Eclipse Plugin Installation

i. Click on Help -> Install New Software

ii. Click on Add button and put name as Cucumber and location as  http://cucumber.github.com/cucumber-eclipse/update-siteClick ok button.

iii. Select all from List and click next button.

iv. Accept License and agreement.
v. Accept security  warning.
vi. Restart the eclipse.

Another way to install Cucumber JVM Eclipse Plugin is :

i. Open https://marketplace.eclipse.org/content/cucumber-jvm-eclipse-plugin


ii. Drag the Install button to Eclipse editor.

b. CucumberPeople Eclipse plugin installation


 Now we can install CucumberPeople if we are not interested to install the previous plugin.

We need to follow this steps to install this plugin.

i. From the Help menu, select Install New Software... to open an Install pop-up window.
ii. In the Name: field type Cucumber People and in  Location: text box type the URL https://alterhu.github.io/CucumberPeople/ then hit the Enter key.
iii. In the populated table below, check the box next to the name of the plug-in, and click the Next button.
iv. Click the Next button to go to the license page.
v. Choose the option to accept the terms of the license agreement, and click the Finish button.

After successful installation of Cucumber plugin .feature file in projects should be shown like below.
Intenseness should be available when writing feature file. 

Wednesday, November 11, 2015

Cucumber A Behavior Driven Development(BDD) Tool

Here we will learn about Cucumber a Behavior Driven Development(BDD) Tool.

What is BDD ?

Ans : Behavior Driven Development or BDD is a process where we will concentrate on the behavior of the application not on the implementation details. BDD use human understandable language where we try to focus the behavior of an application. So as it is a human readable language we can involve Business stakeholders, Business Analysts, QA Team and developers.

What is TDD ?
Ans : Test Driven Development or TDD is the approach where we write down all the expectation from the Application and can implement all the expectation gradually.

Explain the difference between TDD and BDD ?
Ans : Let's take an example of different type of sort like bubble,selection,merge, insertion sort. So if we go for the TDD, we need to write test cases for each and every sort because implementation of each sort are different but in BDD we need to write only one test case because every sort have the same expected outcomes and BDD focus on the expectation not on the implementation.

Can you mention some BDD tools name?
Ans : There are so many BDD tools available. Cucumber and Jbehave are some of those. This are open source tools.



Sunday, October 18, 2015

Multiple Column Sorting On WebTable

On previous post we learn how to handle webtable in a better manner. Now we try to validate the webtable with sorting facility.

Steps 1 :
 Load page which contains WebTable
e.g :
driver.get("https://en.wikipedia.org/wiki/List_of_largest_oil_and_gas_companies_by_revenue");

Step 2 :
 Access the WebTable.
e.g :
WebTable table =WebTable.getTable(driver.findElement(By.xpath(".//*[@id='mw-content-text']/table/tbody/tr/td/table")));

Step 3 :
  Store each row as a object in a list.
e.g :
for (int tableBodyRow =0; tableBodyRow < table.getTableBody().getRowCount();tableBodyRow++) {
TableDataObject tabObj = new TableDataObject();
for (int tableBodyColumn = 0; tableBodyColumn <  table.getTableBody().getRow(tableBodyRow).getCoulmnCount(); tableBodyColumn++) {
//System.out.print(" TableBody Row : " + (tableBodyRow+1) + " TableBody Column : " + (tableBodyColumn+1)); 
if(tableBodyColumn==0){
//System.out.println(" TableBody Cell Text : " + table.getTableBody().getRowElement(tableBodyRow).findElement(By.xpath(".//span/a/img")).getAttribute("alt"));
tabObj.setCountry_Name(table.getTableBody().getRowElement(tableBodyRow).findElement(By.xpath(".//span/a/img")).getAttribute("alt").trim());
}
else if(tableBodyColumn ==1){
//System.out.println(" TableBody Cell Text : " + table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText());
tabObj.setCompany_Name(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
else if(tableBodyColumn ==2){
//System.out.println(" TableBody Cell Text : " + table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText());
tabObj.setRevenue_2014(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
}
ltTableDataObj.add(tabObj);
Step 4 :
 Now click on the desired column header to sort the table.

e.g :
driver.findElement(By.cssSelector(".headerSort:first-child+th")).click();

Step 5 :
 Now sort the previously stored list.

e.g :
Collections.sort(ltTableDataObj, new TableDataObject.CompanyNameSort()); 

This is the most important part of this post. Sorting a list of any object can not be done using only sort method. To get this facility from object we need to implement comparable or comparator. If we use comparable then we can choose only one field to sort but here we need to sort the objects against different column so we implement comparator.

e.g :
/**
 * Comparator implementation using anonymous class
 */
static Comparator<TableDataObject> country_NameComparator = new Comparator<TableDataObject>() {
@Override
public int compare(TableDataObject o1, TableDataObject o2) {
if(o1.getCountry_Name().equals(o2.getCountry_Name())){
if(o1.getRevenue_2014().compareTo(o2.getRevenue_2014())>1){
return o2.getCountry_Name().compareTo(o1.getCountry_Name());
}
else {
return o1.getCountry_Name().compareTo(o2.getCountry_Name());
}

}
else {
return o1.getCountry_Name().compareTo(o2.getCountry_Name());
}
}
};

/**
 * Comparator implementation using sub class
 */
static class CompanyNameSort implements Comparator<TableDataObject>{

@Override
public int compare(TableDataObject o1, TableDataObject o2) {
return o1.company_Name.compareToIgnoreCase(o2.company_Name);
}

}

Step 6 :
 Now iterate on the webtable again and store this on another different list of object.

Step 7 :
 Now compare two list

e.g :
System.out.println(ltTableDataObj.equals(ltTableDataObj2));

Comple Code Given Below :

Table Object Class :

import java.util.Comparator;

public class TableDataObject {
private String country_Name;
private String company_Name;
private String revenue_2014;

@Override
public String toString() {
return "TableDataObject [country_Name=" + country_Name + ", company_Name=" + company_Name + ", revenue_2014="
+ revenue_2014 + "]";
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((company_Name == null) ? 0 : company_Name.hashCode());
result = prime * result + ((country_Name == null) ? 0 : country_Name.hashCode());
result = prime * result + ((revenue_2014 == null) ? 0 : revenue_2014.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TableDataObject other = (TableDataObject) obj;
if (company_Name == null) {
if (other.company_Name != null)
return false;
} else if (!company_Name.equals(other.company_Name))
return false;
if (country_Name == null) {
if (other.country_Name != null)
return false;
} else if (!country_Name.equals(other.country_Name))
return false;
if (revenue_2014 == null) {
if (other.revenue_2014 != null)
return false;
} else if (!revenue_2014.equals(other.revenue_2014))
return false;
return true;
}

public String getCountry_Name() {
return country_Name;
}

public void setCountry_Name(String country_Name) {
this.country_Name = country_Name;
}

public String getCompany_Name() {
return company_Name;
}

public void setCompany_Name(String company_Name) {
this.company_Name = company_Name;
}

public String getRevenue_2014() {
return revenue_2014;
}

public void setRevenue_2014(String reevenue_2014) {
this.revenue_2014 = reevenue_2014;
}
/**
* Implement Comparator using anonymous class
*/
static Comparator<TableDataObject> country_NameComparator = new Comparator<TableDataObject>() {
@Override
public int compare(TableDataObject o1, TableDataObject o2) {
if(o1.getCountry_Name().equals(o2.getCountry_Name())){
if(o1.getRevenue_2014().compareTo(o2.getRevenue_2014())>1){
return o2.getCountry_Name().compareTo(o1.getCountry_Name());
}
else {
return o1.getCountry_Name().compareTo(o2.getCountry_Name());
}

}
else {
return o1.getCountry_Name().compareTo(o2.getCountry_Name());
}
}
};
/**
* Implement Comparator using inner class
*/
static class CompanyNameSort implements Comparator<TableDataObject>{

@Override
public int compare(TableDataObject o1, TableDataObject o2) {
return o1.company_Name.compareToIgnoreCase(o2.company_Name);
}
}
}

Test Class :

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;

import com.automation.webtable.table.WebTable;

public class AccessTable {
public static void main(String[] args) {
List<TableDataObject> tableExpected = new ArrayList<TableDataObject>();
List<TableDataObject> tableOnPage = new ArrayList<TableDataObject>();
WebDriver driver = new FirefoxDriver(new FirefoxBinary(new File("G:/Program Files/Mozilla Firefox/firefox.exe")),new FirefoxProfile());
try{
driver.get("https://en.wikipedia.org/wiki/List_of_largest_oil_and_gas_companies_by_revenue");
WebTable table =WebTable.getTable(driver.findElement(By.xpath(".//*[@id='mw-content-text']/table/tbody/tr/td/table")));
System.out.println("Table Body Row Count : " + table.getTableBody().getRowCount() + " Table Body Column Count : " + table.getTableBody().getRow(0).getCoulmnCount());
for (int tableBodyRow =0; tableBodyRow < table.getTableBody().getRowCount();tableBodyRow++) {
TableDataObject tabObj = new TableDataObject();
for (int tableBodyColumn = 0; tableBodyColumn <  table.getTableBody().getRow(tableBodyRow).getCoulmnCount(); tableBodyColumn++) { 
if(tableBodyColumn==0){
tabObj.setCountry_Name(table.getTableBody().getRowElement(tableBodyRow).findElement(By.xpath(".//span/a/img")).getAttribute("alt").trim());
}
else if(tableBodyColumn ==1){
tabObj.setCompany_Name(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
else if(tableBodyColumn ==2){
tabObj.setRevenue_2014(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
}
tableExpected.add(tabObj);
}
driver.findElement(By.cssSelector(".headerSort:first-child")).click();
Collections.sort(tableExpected, TableDataObject.country_NameComparator);
System.out.println("After Sorted Data : "+ tableExpected);
for (int tableBodyRow =0; tableBodyRow < table.getTableBody().getRowCount();tableBodyRow++) {
TableDataObject tabObj = new TableDataObject();
for (int tableBodyColumn = 0; tableBodyColumn <  table.getTableBody().getRow(tableBodyRow).getCoulmnCount(); tableBodyColumn++) {
if(tableBodyColumn==0){
tabObj.setCountry_Name(table.getTableBody().getRowElement(tableBodyRow).findElement(By.xpath(".//span/a/img")).getAttribute("alt").trim());
}
else if(tableBodyColumn ==1){
tabObj.setCompany_Name(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
else if(tableBodyColumn ==2){
tabObj.setRevenue_2014(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
}
tableOnPage.add(tabObj);
}
System.out.println("New Table :"+ tableOnPage);
System.out.println(tableExpected.equals(tableOnPage));
driver.findElement(By.cssSelector(".headerSort:first-child+th")).click();

/**
* Sort using inner class which is defined in TableDataObject class.
*/
//Collections.sort(ltTableDataObj, new TableDataObject.CompanyNameSort());
Collections.sort(tableExpected, new Comparator<TableDataObject>() {

@Override
public int compare(TableDataObject o1, TableDataObject o2) {
return o1.getCompany_Name().compareToIgnoreCase(o2.getCompany_Name());
}
});
System.out.println("After Sorted Data : "+ tableExpected);
for (int tableBodyRow =0; tableBodyRow < table.getTableBody().getRowCount();tableBodyRow++) {
TableDataObject tabObj = new TableDataObject();
for (int tableBodyColumn = 0; tableBodyColumn <  table.getTableBody().getRow(tableBodyRow).getCoulmnCount(); tableBodyColumn++) {
//System.out.print(" TableBody Row : " + (tableBodyRow+1) + " TableBody Column : " + (tableBodyColumn+1)); 
if(tableBodyColumn==0){
//System.out.println(" TableBody Cell Text : " + table.getTableBody().getRowElement(tableBodyRow).findElement(By.xpath(".//span/a/img")).getAttribute("alt"));
tabObj.setCountry_Name(table.getTableBody().getRowElement(tableBodyRow).findElement(By.xpath(".//span/a/img")).getAttribute("alt").trim());
}
else if(tableBodyColumn ==1){
//System.out.println(" TableBody Cell Text : " + table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText());
tabObj.setCompany_Name(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
else if(tableBodyColumn ==2){
//System.out.println(" TableBody Cell Text : " + table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText());
tabObj.setRevenue_2014(table.getTableBody().getRow(tableBodyRow).getCell(tableBodyColumn).getText().trim());
}
}
tableOnPage.add(tabObj);
}
System.out.println("New Table :"+ tableOnPage);
System.out.println(tableExpected.equals(tableOnPage));
}
finally{
driver.close();
}
}
}

WebTable Code:

Complete Code given on previous post.