简体   繁体   中英

How to design Selenium 2 tests with the Page Object pattern using inheritance

We are now writing a new test suite using Selenium 2 (Webdriver) and TestNG . Our tests use the Page Object pattern and we are very happy with the the way things are looking so far. However, we ran into a design issue with our tests and we don't seem to be able to find a good solution for it. Let me give you an example. Here is our LoginTestCase:

public class LoginTestCase extends MyTestCase {
    @BeforeTest
    public void login() {
        HomePage homepage = PageFactory.initElements(getDriver(), HomePage.class);
        LoginPage loginPage = homepage.login();
        DashboardPage dashboardPage = loginPage.loginUser("username", "password");
    }   
}

We would like to extend our tests that require a user to be logged in from this test. Ideally we would be able to write something like this:

public class DashboardTestCase extends LoginTestCase {
    @Test
    public void testDashboard(DashboardPage dashboardPage) { 
        ...
    }
}

At this point the user is at the DashboardPage and the only thing needed is the object of that page which was created in the LoginTestCase .

I know the obvious solution is to store that object in a variable (in the LoginTestCase ) that will then be access by the child test cases. However this looks very ugly and can lead to a misuse of that variable.

Is there a better solution for this or some pattern that addresses this design issue?

We used dependency injection and Guice with Guice-berry to solve this problem. The page objects were injected to the test methods and WebDriver was injected to the page objects.

As a tradeoff we had not used all this nice little chaining between page objects.

But static state and singletons are pain in the ass when it comes to parallel test execution so they should be avoided.

I haven't found a better solution yet. I have a singelton WebDriver in a static class from where all my testcases can access the WebDriver. My testclasses all need to be run on the same WebDriver due to Login/Session.

I think you should store a reference to the page object in a private variable in LoginTestCase class and provide a protected getter so that the child tests can access the pageobject. This helps achieve two things

  1. Encapsulate the variable with in your LoginTestCase so that no one can mess it up with that..
  2. Providing a protected getter make sure only the child test cases get access to it and that's what you wanted after all. so that should not a problem.

This is how your code will look like after the changes. Hope that makes sense:

public class LoginTestCase extends MyTestCase {

    private dashboardPage;

    @BeforeTest
    public void login() {
        HomePage homepage = PageFactory.initElements(getDriver(), HomePage.class);
        LoginPage loginPage = homepage.login();
        dashboardPage = loginPage.loginUser("username", "password");
    }

    protected void getDashBoardPage() {
        return dashboardPage;  
    }

}

public class DashboardTestCase extends LoginTestCase {
    @Test
    public void testDashboard() { 
            DashboardPage dashboardPage = getDashBoardPage();
        ...
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM