automatictester

my thoughts on test automation

Parallel execution on method level in Selenium + TestNG framework

Most Selenium test automation frameworks based on TestNG implement parallel test execution on class level. This can be easily achieved and is implicitly supported by default for Page Object design pattern class hierarchy:

traditional-page-object-framework-class-hierarchy

You can find example of such design in one of my previous posts – for both pure Page Object and PageFactory design patterns. This default solution works for most of us as long as we don’t have to restart browser after every test method. If we do, we can end up with artificially large number of classes with single test methods.

To enable parallelism per test method, not class, we need to redesign class hierarchy. Test classes can’t extend ParentTest. We need an App object, witch which each test method interacts separately. Below is complete example of such design:

ParentPage

package uk.co.automatictester.session.per.method;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class ParentPage {

    protected WebDriver driver;

    public ParentPage(WebDriver driver) {
        this.driver = driver;
    }

    public void click(By locator) {
        driver.findElement(locator).click();
    }

    public boolean isDisplayed(By locator) {
        return !driver.findElements(locator).isEmpty();
    }

}

MainPage

package uk.co.automatictester.session.per.method;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class MainPage extends ParentPage {

    private static final By ABOUT_TAB = By.linkText("About");

    public MainPage(WebDriver driver) {
        super(driver);
    }

    public void clickAboutTab() {
        click(ABOUT_TAB);
    }
}

AboutPage

package uk.co.automatictester.session.per.method;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class AboutPage extends ParentPage {

    private static final By ROADMAP_LINK = By.linkText("Roadmap");
    private static final By HELP_LINK = By.linkText("Help");

    public AboutPage(WebDriver driver) {
        super(driver);
    }

    public boolean isRoadmapLinkDisplayed() {
        return isDisplayed(ROADMAP_LINK);
    }

    public boolean isHelpLinkDisplayed() {
        return isDisplayed(HELP_LINK);
    }
}

App

package uk.co.automatictester.session.per.method;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class App {

    protected WebDriver driver;

    protected MainPage mainPage;
    protected AboutPage aboutPage;

    public void startBrowser() {
        driver = new ChromeDriver();

        mainPage = new MainPage(driver);
        aboutPage = new AboutPage(driver);

        driver.navigate().to("http://www.seleniumhq.org/");
        driver.manage().window().maximize();
    }

    public void quit() {
        driver.quit();
    }
}

AboutTest

package uk.co.automatictester.session.per.method;

import org.testng.annotations.Test;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

public class AboutTest {

    @Test
    public void verifyAboutPageRoadmapLink() {
        App app = new App();
        app.startBrowser();

        app.mainPage.clickAboutTab();
        assertThat(app.aboutPage.isRoadmapLinkDisplayed(), is(true));

        app.quit();
    }

    @Test
    public void verifyAboutPageHelpLink() {
        App app = new App();
        app.startBrowser();

        app.mainPage.clickAboutTab();
        assertThat(app.aboutPage.isHelpLinkDisplayed(), is(false));

        app.quit();
    }
}

testng.xml

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Test runner" parallel="methods" thread-count="2">
    <test name="Thread per method">
        <packages>
            <package name="uk.co.automatictester.session.per.method.*"/>
        </packages>
    </test>
</suite>
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: