I've been using Selenium off and on for the past two years. Recently I've been seeing more references to page objects. (I'm referring to page objects as an means of organizing UI automation code -- not an interface or implementation manifested in the Selenium API.) What are the advantages and disadvantages of using page objects relative to using a mere collection of functions? Please attempt to justify the advantages and disadvantages.
What are the trade-offs of using page objects instead of a collection of functions in UI automation?
5 Answers
Advantages:
- Clear separation between test code and navigation code in code base.
Easy to comprehend test, for example -
Homepage.testLogin(username, password);
is more succinct than
selenium.type(username); selenium.type(password); selenium.click(submit); selenium.waitForpageToLoad(waitPeriod);
Ease of maintenance, when UI changes you need to change the navigation code and not test (provided application logic is still the same and only UI object/navigation is changed)
Disadvantage:
The only one I could think of is, initial design of page object might take more time but pain is definitely worth it
-
4You could do the same thing with a function, without going to the trouble of defining an object, so I don't think this answers the question.– user246May 14, 2011 at 20:34
-
Tarun is it like page objects are methods or each page object will have its member function? May 16, 2011 at 1:48
-
@user246 - True for the example Tarun has used, but not true generally. PageObjects ensure defining an object once, and reusing it everywhere else. If you define multiple methods around an object, the part of your code that identifies the object will be scattered around your entire code, which will create a maintenance nightmare. May 17, 2011 at 1:19
-
2@Suchit Perhaps this is just a matter of our using different terms. When you say, "PageObjects ensure defining an object", what object are you referring to? Functions work just as well as objects for encapsulating logic. There is a stronger argument for using objects if you need inheritance or if you need to encapsulate state. However, it sounds to me like most PageObjects are basically stateless proxies -- just collections of functions.– user246May 17, 2011 at 13:43
-
2The pain of defining page object model is lower than the pain of maintaining a set of functions only if page object model is done correctly.– dzieciouJun 2, 2014 at 21:39
There are three main advantages to putting your functions into PageObjects rather than just having a bunch of static functions:
- Context.
LoginPage.clickNext()
vsItemDetails.clickNext()
immediately tells you what page you're on when looking at the test, even if they're identical methods inherited from a parent class. - The
PageObjectFactory
can automatically initialize member variables of a PageObject so you don't have to do afind()
every time you want to interact with something. This keeps your code cleaner, but assumes you use the PageObject paradigm and will work best if you do so. - Ease of maintenance of code; if you're using Java or .NET, everything has to be in a class anyway, so it's easier to break it up into logical groupings by page rather than putting everything in the same static class. Naming your page classes well allows you to easily find the methods you need to update when a given page changes.
In actual practice, PageObjects are primarily a way of organizing code rather than anything too difficult or complicated to implement. They don't provide much in the way of performance improvements or enable much you can't do otherwise, but they make your code cleaner and easier to read and maintain.
-
+1 for PageObjectFactory. Annotating
WebElement
s lets you separate completex locators for page elements from operations on them.– dzieciouJun 2, 2014 at 21:44
Though there are many advantages of Page Project Model, some of them are :
Simple and clear page classes with sensible method names.
You can actually give the customize names to you methods. Like above so that you need not to keep anything in mind.
Just looking into the method name gives you all idea about the capabilities of the method.
Makes tests more readable. In comparison to above commands of selenium , where in you need to add all the commands in the tests scripts . in page object model you need to put method names. The methods which you have created according to your understanding of application so these methods name are more readable and easy to understand.
Stay DRY. Page object model believes in the principle of Do not repeat yourself.
Good support of tests, because everything is stored in one place.
Easy creation of new tests. In fact, tests can be created by a person not knowing the features of automation tools.
As I have actually implemented it in my project so definitely there are some flaws:
All locators should be kept in page class file.
And this abstraction leads to some chaos with in the Page Class file. So you need to implement something like key word driven on top of Page Object Model so as to fully take the advantages.
Advantages:
(OOP) Separation of defining objects from implementing them in methods. Define once, use it multiple times.
Clarity of tests / self-documentation
loginPage.typeUsername; loginPage.typePassword; loginPage.submit;
Easy to maintain - e.g. if the login page elements get updated, you can just go to your loginPage Page Object class and update the methods identifying the elements
Disadvantage:
- Takes time to build the infrastructure (as mentioned before)
- Requires good enough programming skills to design the automation suite (+ or - depending on the programming skills of the team)
-
+1 for "easy to maintain". I think both disadvantages are simply costs of investing into tests that are easy to maintain. There's never a free lunch, one just must make sure there is ROI/gain from this investment, i.e., costs of maintenance is lowered than cost of building page object model and employing skilled engineers.– dzieciouJun 2, 2014 at 21:35
Static functions / Single line variables
- easier to read more at once on the screen
- easier to maintain naming subclasses with more visible for cmparison
- can have a global scope (generally a bad thing)
PageObject Class with functions
- easier to subclass and lends itself to mixing in modules in a more modular fashion
- Scoped and namespaced to the class
Our PageObject approach for identify page elements has gone through a number of transformations! See below. My takeaway from this is:
- The actual form used (variable, method, yaml, etc) became somewhat irrelevant. In the end it is a file I am editing that I care about.
- The hard part is using good naming and good selectors that are specific enough without being too specific or hard-coded so focus effort there
- Be willing to redo and rework whatever structure you have created from your naming as new data appears
- Decide whether to have one central file or a bunch of different ones depending on the need. Personally I have found one single file is the easiest to maintain.
- one line per finder as done with the variables or yaml file is the easiest way to see the most selectors at once and be able to group and name them in an organized fashion without duplicates and inconsistencies
Our Page Object journey:
Initially they were javascript variables included as a file in the seleniumIDE.
var footer='div#footer';
These were then moved to a file and coded as ruby methods (similar to functions) in a PageObject class in a rails application.
...
def footer
'div#footer'
end
... ```
These were then moved to a yaml file and read in from there.
...
footer: 'div#footer'
...