Saturday, November 13, 2010

Testing sorting feature of an application

All applications display data and allow the user to sort the data on some column. I am sure you would have written or executed test cases to test the sorting feature of your application. There are many strategies to automate such test. In this post I will try to explain a strategy I use widely.

Data is generally displayed in the form of a table (webtable) with each row containing one record. Generally in web applications the sorting feature is given on some or all column of the table. Let’s look at one such website that displays data in this fashion. Navigate to www.vcdq.com


This website as you can see has information on the latest movie releases. It allows you to sort the data on two of the columns, Date and Release. You can sort the data by clicking the respective column header. Both columns can be sorted in ascending and descending order. A small arrow icon is indicating the current sorting order next to the column header text.

My strategy involves the following
a)    Reading all the data of this table into a java ArrayList. Lets call this ExpectedList
b)    Perform the sort on the application by clicking the column header
c)    Read the data from the table again and store it in another ArrayList. Lets call this ActualListAfterSort
d)    Sort the ExpectedList
e)    Compare ExpectedList with ActualListAfterSort and verify that the order of the elements is same.

There is a distinction between the ArrayList that holds primitive datatypes like String or int and the one I use. I use a user defined class to hold the rows of data. Each member element of this class represents one column of the table. The class is defined below.

public class ReleaseInfoTableRecord {
String standard;
Date date;
String format;
String source;
String release;
double imdb;
int disks;
String group;
int ratingAudio;
int ratingVideo;

public ReleaseInfoTableRecord(String standard, Date date, String format,
        String source, String release, double imdb, int disks, String group,
        int ratingAudio, int ratingVideo) {
    super();
    this.standard = standard;
    this.date = date;
    this.format = format;
    this.source = source;
    this.release = release;
    this.imdb = imdb;
    this.disks = disks;
    this.group = group;
    this.ratingAudio = ratingAudio;
    this.ratingVideo = ratingVideo;
}
}

I will insert objects of this class into the ArrayList. An object will represent one row of the table. This is how will insert record within the ArrayList.

ArrayList<ReleaseInfoTableRecord> LatestMovieReleaseDisplayed=new ArrayList<ReleaseInfoTableRecord>();
        
LatestMovieReleaseDisplayed.add(new ReleaseInfoTableRecord(standard, date, format, 
                    source, release, imdb, disks, group, ratingAudio, ratingVideo  ) );

Now in order to sort the data of the ArrayList I would have to define some comparators. I will have to define comparators for all the sort features that I wish to test. For example If the application under test allows sorting the data on ascending and descending order on column Date and I want to test this feature than I need to define two comparators one for ascending and other for descending on date. I will be defining these comparators in the class ReleaseInfoTableRecord.

static final Comparator<ReleaseInfoTableRecord> SORT_DATE_ASCENDING =  new Comparator<ReleaseInfoTableRecord>(){
    public int compare(ReleaseInfoTableRecord o1, ReleaseInfoTableRecord o2) {
        int result = o1.getDate().compareTo(o2.getDate());
        if (o1.getDate().equals(o2.getDate()))
            result =o1.getRelease().compareTo(o2.getRelease())*-1;
        return (result);
    }
};

static final Comparator<ReleaseInfoTableRecord> SORT_DATE_DESCENDING =  new Comparator<ReleaseInfoTableRecord>(){
    public int compare(ReleaseInfoTableRecord o1, ReleaseInfoTableRecord o2) {
        int result = o1.getDate().compareTo(o2.getDate())*-1;
        if (o1.getDate().equals(o2.getDate()))
            result =o1.getRelease().compareTo(o2.getRelease());
        return (result);
    }
};


The hashCode and equals method of the data class must be overridden to make the comparison possible. This overriden methods can be genarated in eclipse by doing right click source-->generate hashcode and equals. You will se this below in the full class code.

If the two records have the same date then the application sorts on the basis of Release name. Note the logic for each comparator when the date is same. This is specific to this application and the application that you are testing may have a different logic. Go thru the application logic carefully before defining the comparators.

Now we define the actual test method that tests the sorting feature. Note that I have read the data into the ArrayList dataAsDisplayedInDefaultView in an earlier step. The code in the while loop is instruction that performs the sorting on the web application i.e clicks the column header link repeatedly till the appropriate arrow icon appears. Your application may involve steps different than this to invoke sort.

@Test
    public void testSortingDateAscending() {            
        int i=0;
        //Click Date column header till the small up arrow is visible next to <Date> column header, 
        //don't get confused by the title of the up arrow image        
        while (false==selenium.isElementPresent("//table//th[2]/a/img[@title='sort descending']")&&i<2){
        selenium.click("link=Date");
        selenium.waitForPageToLoad("30000");
        }        
        
        ArrayList<ReleaseInfoTableRecord> dataAsDisplayedAfterSort=getLatestMovieReleaseDisplayed();
        //make a copy of the arraylist that holds the displayed data 
        ArrayList<ReleaseInfoTableRecord> expectedOrder=dataAsDisplayedInDefaultView;
        //sort the copy on Date Descending, this is how the data is sorted in the default view on this website
        Collections.sort(expectedOrder, ReleaseInfoTableRecord.SORT_DATE_ASCENDING);
        //This will pass only if the elements in both the lists appear in the same order
        org.testng.Assert.assertTrue(dataAsDisplayedAfterSort.equals(expectedOrder));        
    }

Below you can see both the classes in their full glory. ReleaseInfoTableRecord class that will be used to hold the data (record of the table) and SortingTest is the test class.

package test;


import java.util.Comparator;
import java.util.Date;

public class ReleaseInfoTableRecord {
String standard;
Date date;
String format;
String source;
String release;
double imdb;
int disks;
String group;
int ratingAudio;
int ratingVideo;

public ReleaseInfoTableRecord(String standard, Date date, String format,
        String source, String release, double imdb, int disks, String group,
        int ratingAudio, int ratingVideo) {
    super();
    this.standard = standard;
    this.date = date;
    this.format = format;
    this.source = source;
    this.release = release;
    this.imdb = imdb;
    this.disks = disks;
    this.group = group;
    this.ratingAudio = ratingAudio;
    this.ratingVideo = ratingVideo;
}



@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((date == null) ? 0 : date.hashCode());
    result = prime * result + disks;
    result = prime * result + ((format == null) ? 0 : format.hashCode());
    result = prime * result + ((group == null) ? 0 : group.hashCode());
    long temp;
    temp = Double.doubleToLongBits(imdb);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    result = prime * result + ratingAudio;
    result = prime * result + ratingVideo;
    result = prime * result + ((release == null) ? 0 : release.hashCode());
    result = prime * result + ((source == null) ? 0 : source.hashCode());
    result = prime * result + ((standard == null) ? 0 : standard.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;
    ReleaseInfoTableRecord other = (ReleaseInfoTableRecord) obj;
    if (date == null) {
        if (other.date != null)
            return false;
    } else if (!date.equals(other.date))
        return false;
    if (disks != other.disks)
        return false;
    if (format == null) {
        if (other.format != null)
            return false;
    } else if (!format.equals(other.format))
        return false;
    if (group == null) {
        if (other.group != null)
            return false;
    } else if (!group.equals(other.group))
        return false;
    if (Double.doubleToLongBits(imdb) != Double.doubleToLongBits(other.imdb))
        return false;
    if (ratingAudio != other.ratingAudio)
        return false;
    if (ratingVideo != other.ratingVideo)
        return false;
    if (release == null) {
        if (other.release != null)
            return false;
    } else if (!release.equals(other.release))
        return false;
    if (source == null) {
        if (other.source != null)
            return false;
    } else if (!source.equals(other.source))
        return false;
    if (standard == null) {
        if (other.standard != null)
            return false;
    } else if (!standard.equals(other.standard))
        return false;
    return true;
}
public String getStandard() {
    return standard;
}
public void setStandard(String standard) {
    this.standard = standard;
}
public Date getDate() {
    return date;
}
public void setDate(Date date) {
    this.date = date;
}
public String getFormat() {
    return format;
}
public void setFormat(String format) {
    this.format = format;
}
public String getSource() {
    return source;
}
public void setSource(String source) {
    this.source = source;
}
public String getRelease() {
    return release;
}
public void setRelease(String release) {
    this.release = release;
}
public double getImdb() {
    return imdb;
}
public void setImdb(double imdb) {
    this.imdb = imdb;
}
public int getDisks() {
    return disks;
}
public void setDisks(int disks) {
    this.disks = disks;
}
public String getGroup() {
    return group;
}
public void setGroup(String group) {
    this.group = group;
}
public int getRatingAudio() {
    return ratingAudio;
}
public void setRatingAudio(int ratingAudio) {
    this.ratingAudio = ratingAudio;
}
public int getRatingVideo() {
    return ratingVideo;
}
public void setRatingVideo(int ratingVideo) {
    this.ratingVideo = ratingVideo;
}

static final Comparator<ReleaseInfoTableRecord> SORT_DATE_ASCENDING =  new Comparator<ReleaseInfoTableRecord>(){
    public int compare(ReleaseInfoTableRecord o1, ReleaseInfoTableRecord o2) {
        int result = o1.getDate().compareTo(o2.getDate());
        if (o1.getDate().equals(o2.getDate()))
            result =o1.getRelease().compareTo(o2.getRelease())*-1;
        return (result);
    }
};

static final Comparator<ReleaseInfoTableRecord> SORT_DATE_DESCENDING =  new Comparator<ReleaseInfoTableRecord>(){
    public int compare(ReleaseInfoTableRecord o1, ReleaseInfoTableRecord o2) {
        int result = o1.getDate().compareTo(o2.getDate())*-1;
        if (o1.getDate().equals(o2.getDate()))
            result =o1.getRelease().compareTo(o2.getRelease());
        return (result);
    }
};


static final Comparator<ReleaseInfoTableRecord> SORT_RELEASE_ASCENDING =  new Comparator<ReleaseInfoTableRecord>(){
    public int compare(ReleaseInfoTableRecord o1, ReleaseInfoTableRecord o2) {
        int result = o1.getRelease().compareTo(o2.getRelease());
        return (result);
    }
};

static final Comparator<ReleaseInfoTableRecord> SORT_RELEASE_DESCENDING =  new Comparator<ReleaseInfoTableRecord>(){
    public int compare(ReleaseInfoTableRecord o1, ReleaseInfoTableRecord o2) {
        int result = o1.getRelease().compareTo(o2.getRelease());
        return (result * -1);
    }
};

}


package test;


import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;

import org.openqa.selenium.server.SeleniumServer;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import com.thoughtworks.selenium.SeleneseTestCase;

public class SortingTest extends SeleneseTestCase{
    
    ArrayList<ReleaseInfoTableRecord> dataAsDisplayedInDefaultView;

     @BeforeClass
        public void setUp() throws Exception {
            SeleniumServer seleniumserver=new SeleniumServer();
            seleniumserver.boot();
            seleniumserver.start();
            setUp("http://www.vcdq.com", "*firefox");
            selenium.open("/");
            selenium.windowMaximize();
            selenium.windowFocus();
            
            //filter the results to reduce the data-set to manageable levels            selenium.select("filterStandard", "label=SCENE");
            selenium.select("filterTerm3", "label=DVDR");
            selenium.select("filterTerm2", "label=DVD");
            selenium.click("//input[@value='Filter']");
            selenium.waitForPageToLoad("20000");
            dataAsDisplayedInDefaultView=getLatestMovieReleaseDisplayed();
        }    
    
    @Test
    public void testDefaultSorting(){                
        //make a copy of the arraylist that holds the displayed data 
        ArrayList<ReleaseInfoTableRecord> expectedOrder=dataAsDisplayedInDefaultView;
        //sort the copy on Date Descending, this is how the data is sorted in the default view on this website
        Collections.sort(expectedOrder, ReleaseInfoTableRecord.SORT_DATE_DESCENDING);
        //This will pass only if the elements in both the lists appear in the same order
        org.testng.Assert.assertTrue(dataAsDisplayedInDefaultView.equals(expectedOrder));        
    }
    
        
    @Test
    public void testSortingDateAscending() {            
        int i=0;
        //Click Date column header till the small up arrow is visible next to <Date> column header, 
        //don't get confused by the title of the up arrow image
        while (false==selenium.isElementPresent("//table//th[2]/a/img[@title='sort descending']")&&i<2){
        selenium.click("link=Date");
        selenium.waitForPageToLoad("30000");
        }        
        
        ArrayList<ReleaseInfoTableRecord> dataAsDisplayedAfterSort=getLatestMovieReleaseDisplayed();
        //make a copy of the arraylist that holds the displayed data 
        ArrayList<ReleaseInfoTableRecord> expectedOrder=dataAsDisplayedInDefaultView;
        //sort the copy on Date Descending, this is how the data is sorted in the default view on this website
        Collections.sort(expectedOrder, ReleaseInfoTableRecord.SORT_DATE_ASCENDING);
        //This will pass only if the elements in both the lists appear in the same order
        org.testng.Assert.assertTrue(dataAsDisplayedAfterSort.equals(expectedOrder));        
    }
    
    @Test
    public void testSortingReleaseNameAscending(){
        int i=0;
        //Click Date column header till the small up arrow is visible next to <Release> column header, 
        //don't get confused by the title of the up arrow image
        while (false==selenium.isElementPresent("//table//th[6]/a/img[@title='sort descending']")&&i<2){
        //Click Date column header once so that the sort ascending image is visible
        selenium.click("link=Release");
        selenium.waitForPageToLoad("30000");
        i=i+1;
        }
        
        ArrayList<ReleaseInfoTableRecord> dataAsDisplayedAfterSort=getLatestMovieReleaseDisplayed();
        //make a copy of the arraylist that holds the displayed data 
        ArrayList<ReleaseInfoTableRecord> expectedOrder=dataAsDisplayedInDefaultView;
        //sort the copy on Date Descending, this is how the data is sorted in the default view on this website
        Collections.sort(expectedOrder, ReleaseInfoTableRecord.SORT_RELEASE_ASCENDING);
        //This will pass only if the elements in both the lists appear in the same order
        org.testng.Assert.assertTrue(dataAsDisplayedAfterSort.equals(expectedOrder));        
    }
    
    @Test
    public void testSortingReleaseNameDescending(){            
        int i=0;
        //Click Date column header till the small up arrow is visible next to <Release> column header, 
        //don't get confused by the title of the up arrow image        
        while (false==selenium.isElementPresent("//table//th[6]/a/img[@title='sort ascending']")&&i<2) {
        //Click Date column header once so that the sort ascending image is visible
        selenium.click("link=Release");
        selenium.waitForPageToLoad("30000");        
        }
        
        ArrayList<ReleaseInfoTableRecord> dataAsDisplayedAfterSort=getLatestMovieReleaseDisplayed();
        //make a copy of the arraylist that holds the displayed data 
        ArrayList<ReleaseInfoTableRecord> expectedOrder=dataAsDisplayedInDefaultView;
        //sort the copy on Date Descending, this is how the data is sorted in the default view on this website
        Collections.sort(expectedOrder, ReleaseInfoTableRecord.SORT_RELEASE_DESCENDING);
        //This will pass only if the elements in both the lists appear in the same order
        org.testng.Assert.assertTrue(dataAsDisplayedAfterSort.equals(expectedOrder));        
    }
    
    public ArrayList<ReleaseInfoTableRecord> getLatestMovieReleaseDisplayed() {
        ArrayList<ReleaseInfoTableRecord> LatestMovieReleaseDisplayed=new ArrayList<ReleaseInfoTableRecord>();
        
        String standard;
        Date date=null;
        String format;
        String source;
        String release;
        double imdb;
        int disks;
        String group;
        int ratingAudio;
        int ratingVideo;
        
        String rating;
        String imdbCellContent;
        int tableRowCount=selenium.getXpathCount("/descendant::table//tr").intValue();
        
        //read the data from the webtable
        for (int i=1;i<tableRowCount;i++){
            standard=selenium.getText("XPATH=/descendant::table//tr["+i+"]//td[1]");
            DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
            try{
            date=df.parse(selenium.getText("XPATH=/descendant::table//tr["+i+"]//td[2]"));
            }catch (ParseException p){
                System.out.println(p.getMessage());
            }
            
            format=selenium.getText("XPATH=/descendant::table//tr["+i+"]//td[4]");
            source=selenium.getText("XPATH=/descendant::table//tr["+i+"]//td[5]");
            release=selenium.getText("XPATH=/descendant::table//tr["+i+"]//td[6]");
            imdbCellContent=selenium.getText("XPATH=/descendant::table//tr["+i+"]//td[10]");            
            imdb=!(imdbCellContent.equalsIgnoreCase("N/A"))?Double.parseDouble(selenium.getText("XPATH=/descendant::table//tr["+i+"]//td[10]")):0.0;
            disks=Integer.parseInt(selenium.getText("XPATH=/descendant::table//tr["+i+"]//td[11]"));
            group=selenium.getText("XPATH=/descendant::table//tr["+i+"]//td[12]");
            rating=selenium.getText("XPATH=/descendant::table//tr["+i+"]//td[13]");
            ratingVideo=Integer.parseInt(rating.split(" ")[0].split(":")[1]);
            ratingAudio=Integer.parseInt(rating.split(" ")[1].split(":")[1]);
            
            //insert the data as a instances of the class ReleaseInfoTableRecord into the arraylist
            LatestMovieReleaseDisplayed.add(new ReleaseInfoTableRecord(standard, date, format, 
                    source, release, imdb, disks, group, ratingAudio, ratingVideo  ) );
    }
return LatestMovieReleaseDisplayed;
}
    
}

Copy paste these classes into your project and run as testng test to see them in action.

This is the most robust and foolproof strategy I have come across for testing sorting functionality. I use it to test search results, reports etc. You might also want to create test data before invoking the sort i.e create test data items abc, efg, zab or you could just use the existing data in the system.

59 Comments:

bob said...

Mahesh,
This is exactly what I'm looking for. I'm trying to follow what you did but it looks like the site has changed since you posted this and I can't quite work out some of the details. Can you explain the section where the comment starts:

//filter the results to reduce the data-set to manageable levels

I may be able to work out the details with this bit but it would be best if you could update such that your code will work with the site as is.

This is an excellent post. Well done!

Nagaraj Hebbar said...

Hi Mahesh,
I just wanted to know how to handle the Ext-JS pages by using the selenium. This is am trying from couple of days before,my test case is getting failed because of random ID generation in Ext-JS pages. Can you please explain me how to handle this case
contact me on nagaraja12hebbar@gmail.com

Regards
Nagaraj

James said...

It seems to be a useful information and I am sure, there will be many out there who will prefer implement automation testing in the same way like you did.

Unknown said...

Very informative post thanks for share this with us i highly appreciate you for this information thanks once again for sharing information like this Very informative post Thanks for sharing with you, I appreciate this information thank you again for sharing information like this!.............:)
Automated System

GE Fanuc plc Software Free Download said...

I was very encouraged to find this site. GE Fanuc plc Software Free Download

vonexpy said...

The application is really good. Liked the way it is conveyed in the post.
mobile application development services

Anitha said...

Thanks a lot for sharing!!!Your input really helped.

Unknown said...

This tutorial comes handy to testers while doing automation. Thank you.
Selenium Automation Testing Framework

Unknown said...

The best practice for automation frameworks relies on integrated test management tools with automation tool, which helps to achieve reliability and faster test execution as well as easy maintenance of the automation test scripts.Software Test Automation

Unknown said...

Hi, thanks for sharing such an informative blog. I have read your blog and I gathered some needful information from your blog. Keep update your blog. Awaiting for your next update.
Regards
Selenium Training in Chennai

Unknown said...

Thank you for this great information and I appreciate you to Awesome way to present your thoughts and knowledge.
I am a beginner and I want to learn more .Keep sharing your knowledge with us.
Selenium Interview Questions
Selenium Tutorial
Selenium Training in Noida

Unknown said...

Thanks for the great information in your blog Selenium Training in Chennai

andersonherry said...

Hi
Wow... what an informative post for testing automation. The blog post written in a superb way.....CLEARLY DEFINES EVERYTHING WITH A DETAILED VIEW :) cheers!!! Building automation

yolanda said...

This is one of the most incredible blogs I've read in a very long time. The amount of information in here is stunning, like you practically wrote the book on the subject. Your blog is great for anyone who wants to understand this subject more. Great stuff; please keep it up!
selenium automation testing

Unknown said...

Learn Selenium WebDriver Online Training By Professional IT Expert.
Selenium Training in Hyderabad

SAP SuccessFactors Training said...




In that ideas was really good and everyone sharing described to be grate informative give that's you'll give that all content sharing and easy learning explanation.
SAP SuccessFactors Online Training

Unknown said...

Great site for these post and i am seeing the most of contents have useful for my Carrier.Thanks to such a useful information.Any information are commands like to share him.

digital marketing course in chennai
hadoop training in chennai

Unknown said...

Thank you so much for sharing. it’s useful for me.
Learn a training in Best Institute & get a 100% placement Assistant................
Selenium Training in Chennai
Dot Net Training in Chennai
Hadoop Training in Chennai

Unknown said...


Useful information,don't stop sharing and Please keep updating us..... Thanks

Anonymous said...


Good blog post conveyed a helpful information.keep updating...
SEO Company in India

Ancy merina said...
This comment has been removed by the author.
Anonymous said...

Nice information and thanks for sharing

automation testing courses online

Anonymous said...

Really superb information.Thanks for sharing.

Weblogic Admin Training

Sai Elakiyaa said...

Big Thanks for this wonderful read. I enjoyed every little bit of reading and I have bookmarked your website to check out new stuff of your blog a must read blog.


Selenium Training in Chennai
Selenium Training
Selenium Course in Chennai

Diya shree said...

Thanks for sharing your information. Great efforts put it to find it which is really amazing. It is very useful to know, Definitely will share the same to other forums.
best openstack training in Chennai | openstack training center in Chennai | openstack certification training in Chennai | openstack course fees in chennai

Durai Raj said...

The blog which you are posted is innovative…. thanks for the sharing…
Digital Marketing Training in Chennai
Digital Marketing Classes in Coimbatore
Digital Marketing Institute in Bangalore
Digital Marketing Training Institute in Bangalore

Jaweed Khan said...

This is an best post. It is Really very informative concept.I like it and help me to development very well.Thanks alot for this brief explanation and very nice information.Keyword

Anonymous said...

Thanks for your great and helpful presentation I like your good service. I always appreciate your post. That is very interesting I love reading and I am always searching for informative information like this.iot training institutes in chennai | industrial iot training chennai | iot training center in chennai | best iot training centre in chennai

Kamila said...

All the points you described so beautiful. Every time i read your i blog and i am so surprised that how you can write so well.
Asp.Net Training in Chennai
Software Testing Institutes in Chennai
Java Training Institutes in Chennai with 100 Placement
PHP Certification in Chennai

Ruby said...

Pretty article! I found some useful information in your blog, it was awesome to read, thanks for sharing this great content to my vision, keep sharing. Need to learn
Test Automation Services
Regression Testing Services
Functional Testing Services
Performance Testing Services
Security Testing Services

Softgen Infotech said...

Such a great information for blogger i am a professional blogger thanks…

Softgen Infotech is the Best HADOOP Training located in BTM Layout, Bangalore providing quality training with Realtime Trainers and 100% Job Assistance.

kani said...

nice blog..
hosting
india hosting
india web hosting

kani said...

nice blog..
iran web hosting
technology 11 great image sites like imgur hosting
final year project dotnet server hacking what is web hosting
macao web hosting
cloud computing virtual server canada hosting
italy hosting
kenya shared web hosting
inplant training in chennai

Bangalore Training Academy said...

Really very happy to say, your post is very interesting to read. I never stop myself to say something about it. You’re doing a great job. Keep it up...

Tableau Training in Bangalore
Tableau Courses in Bangalore
Tableau Classes in Bangalore
Tableau Training Institute in Bangalore
Tableau Course Syllabus
Best Tableau Training
Tableau Training Centers

Anonymous said...

Thanks for Sharing This Article.It is very so much valuable content. I hope these Commenting lists will help to my website
sailpoint online training

Sap Online Training Portal said...

Thanks for sharing such a great information.It is really one of the finest article and more informative too. I want to share some informative data about sap course and sap abap training . Thank you. expecting more articles from you.

Anonymous said...

The blog is very useful and informative which provides great information and I really loved it.Cisco SD-WAN Training

Anonymous said...

The blog is very useful and informative checkpoint

Arunvijay said...

great post....
Coronavirus Update
Intern Ship In Chennai
Inplant Training In Chennai
Internship For CSE Students
Online Internships
Internship For MBA Students
ITO Internship

Rashika said...

Thanks for Sharing This Article.It is very so much valuable content.
It is more impressive... thanks for sharing with us...

Digital Marketing Training in Chennai | Certification | SEO Training Course | Digital Marketing Training in Bangalore | Certification | SEO Training Course | Digital Marketing Training in Hyderabad | Certification | SEO Training Course | Digital Marketing Training in Coimbatore | Certification | SEO Training Course | Digital Marketing Online Training | Certification | SEO Online Training Course

Sig Sauer Firearms said...

best place to buy dank wood mars OG
Buy brass knocles apple sour
Buy brass knocles banana OG
best place to buy mario carts gorrilla glue online
buy kingpen king louis OG online
best to buy exortic carts online

BEST PLACE TO BUY OXYCODONE ONLINE WITH AND WITHOUT PRESCRIPTION
BUY Promethazine Codeine WITH BITCOINS
How should I take Adderall?Buy Adderall online here,Adderall discreetly shipped to your home,Adderall 30 mg,

Verify Customer Identity said...

Nowadays, id verification service is higher in need. There are numerous id verification methods that anybody can receive on a professional site termed Trust Swiftly, and an agency can use the methods to secure their own web business ideally. By visiting this excellent https://www.trustswiftly.com internet site, you can obtain details of id verification service.

lovemaster said...

Cenforce 100
Fildena 25
generico-italia.com

Chad said...


This blog will help to get more ideas. This is very helpful for Software Testing learners. Thank you for sharing this wonderful site. If someone wants to know about Software QA services this is the right place for you Software QA Companies. Visit here

21 CFR Part 11 Compliance Testing

HIPAA Validation Services

Pci Compliance Testing services

Vijayakash said...

Awesome Blog!!! Thanks for it, it is more useful for us
AWS Training in Tambaram
AWS Training in Anna Nagar
AWS Training in Velachery
AWS Training in Tnagar
AWS Training in Porur
AWS Training in OMR
AWS Training in Chennai

senthilr7692 said...

The Blog contains the effective and attractive information’s and thanks for the blog.
JAVA Course in Chennai
JAVA Course in Bangalore


Afridh A said...

Thank you for sharing this. Best Automation Anywhere training in Chennai. visit our website for more info: Best Automation Anywhere Training Institute in Chennai

ISWARYASEO said...

Modern problems demand modern solutions, and if it is ultimately about the growth of your organization, one shouldn't take any chances. A leading conversational intelligent service desk program, Rezolve.ai provides immediate, real-time resolutions to employee issues. Rezolve.ai, an AI-enabled HR ticketing system, reduces 70% of repetitive questions and boosts HR productivity by 35%.

Click here: AI service desk

Elango said...

Extraordinary Blog. Provides necessary information.
Protractor Training
Protractor Course

Lokeswari said...

I think this is one of the best blog for me because this is really helpful for me. Thanks for sharing this valuable information

internship meaning | internship meaning in tamil | internship work from home | internship certificate format | internship for students | internship letter | Internship completion certificate | internship program | internship certificate online | internship graphic design

shamitha senthil said...

To know more about AI automated service desk and help desk with rezolve.ai, click down the link here: : https://bit.ly/3MyfJ5Q

periyannan said...

Really awesome blog. Your blog is really useful for me. Thanks for sharing this informative blog. Keep update your blog.

python internship | web development internship |internship for mechanical engineering students |mechanical engineering internships |java training in chennai |internship for 1st year engineering students |online internships for cse students |online internship for engineering students |internship for ece students|data science internships |

infrassist said...

We are master managed service provider and we are also provide professional services and noc services 24*7 and outsourced service.
infrassist
join Microsoft Teams Meeting
noc services for msp
managed noc services

cyber pc said...

The website is looking bit flashy and it catches the traffic eyes. layout is beautiful clean and a enjoyable adherent without problems reached interface. Serial Movavi Video Editor

Cyberz Pc said...

Quite for your liking pronounce. I just stumbled about your blog and desired to publicize that i've in truth enjoyed reading your weblog posts. Any pretension i will be subscribing to your feed and that i hope you call anew soon. big thanks for the beneficial data. thank you! keep rocking. Kaspersky Cracked

Hi Every One said...

Its a cozy delight reading your claim.Its full of aspire i am looking for and i lionize to claim a comment that "The content material of your proclaim is incredible" extremely good accomplish..... Good Night Memorial Day

MY LEARN NEST TRAINING said...

My Lear Nest Training Academy is one of the best SAP HCM course which is located in Hyderabad KPHB and the training which they provide is very good and they make it easy to learn. They will clear all your doubts as soon as possible. classes will be scheduled on time and trainers are very punctual.

Muskan said...

Great blog! Your testing strategy is well thought out and meticulous.
Also Read: AUTOMATION IN SOFTWARE TESTING: A COURSE FOR THE FUTURE

George Willy said...

I just wanted to drop by and say how much I enjoyed reading this blog post. Your writing style is captivating, and your knowledge on the outsourced NOC support services is impressive.