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.
- Clear separation between test code and navigation code in code base.
Easy to comprehend test, for example -
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)
The only one I could think of is, initial design of page object might take more time but pain is definitely worth it
There are three main advantages to putting your functions into PageObjects rather than just having a bunch of static functions:
ItemDetails.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.
PageObjectFactorycan automatically initialize member variables of a PageObject so you don't have to do a
find()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.
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.
(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
- 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)
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:
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' ...