Organizing your tests and the objects that describe elements within the application your are testing is one of the ways to help DRY up your tests and to reduce the amount of change needed when the application your are testing changes. You can do this in a couple of ways, and, depending on the driver you are using, there are some libraries that can help you. One way to do this is with the page object pattern.
What is a page object?
A page object is basically a class that defines the grouping of elements that your test can interact with in the application you are testing. Think of it as the representation in your test library of the HTML elements that make up the page you are testing. In the libraries that are available, site_prism and page-object, the elements can be defined using simple css descriptors. This makes it easy to create a page for a test even before it is coded by the developer. (Crazy notion that an automated functional GUI test can be created before the developer writes the code that will be tested eh?) A page object also holds the re-usable page level interactions; things that are more complex than simply retrieving or setting values or determining state and presence of elements. For example if there is a form that needs to be filled in on a page which may be called from different steps, or with different inputs from different steps, then a method at the page level can be defined to interact with the elements and data. A page object can also define page level validation. Things like page specific elements or conditions that show that the page has loaded correctly or not, error messages or specific page text can all be put into a 'page_loaded?' type of method that can be called when instantiating a page to run basic validations each time. If there are site wide items for validations, such as static footer text, site wide page logos etc. or if there are elements or sections that exist on all pages, these things can be placed in a 'CommonPage' class. How to I use Page Objects I like to create a single page object class for each physical page or unique URL within the application that I am testing. Depending on if I am using webdriver and page-object or capybara and site_prism, I handle shared partial pages differently. I like to put all of the 'browser.what.action' type of statements directly in the page class that is being acted on. This keeps it simpler when there are changes done in the application that impact things like css or layout. You don't need to change your features or steps, just the page that has been updated. If there are common reused elements or structures in your application, it is often helpful to have methods to interact that can be re-used on each page that includes them. I usually have helper classes that handle common functions that get used across multiple pages, things like interactions with standard kendo grids for example. I like to keep the page objects in a folder under features called pages and name them according to the page, something like login_page.rb. Here is an example for a login page using webdriver and page-object. features\pages\login_page.rb
Here is what it looks like using capybara and site_prism.
features\pages\login_page.rb
|
Quick links:
|