Tag Archives: DRYness

Watchwords

Here are some principles I try to keep in mind.

Readability Make code easy to read: code is read more often than
written.
DRYness: Don’t Repeat Yourself Avoid redundant code and data.
YAGNIty: You Ain’t Gonna Need It Don’t write code before it’s needed.
Sloth Maximize use of existing packages and libraries. The line of code you don’t write is the line of code you never have to debug. — Steve Jobs
Explicitness Explicate everything, even when “unnecessary.” If it goes without saying, it would go better by saying it. — Tallyrand
Cleanliness Keep everything clean and consistent: run static code
analysis; resolve all issues before committing.
Failed Verdict Diagnostics Log data sufficient to diagnose a failed verdict.
Error Diagnostics Detect test errors early, fail early, log useful information.
Monitoring Trust, but verify. Monitor documentation for changes (programatically, of course).

Test Pages, Not Workflows: Part the Second

A few weeks ago, I posted Test Pages, Not Workflows. Since then, I’ve been doing just that, with much success.

My page, I can say without revealing anything proprietary, is the application’s Users page, for which I’m adding eight page-specific tests:

  1. Evaluate page initial state:
    • Page has correct menu bar and footer elements.
    • Expected buttons are present and have correct enabled/disabled state.
    • User list (table) is present.
    • User list has correct column headers.
  2. Add users in UI.
  3. Add users from CSV file.
  4. Add users from spreadsheet.
  5. Send email to selected users.
  6. Search users.
  7. Sort users by column.
  8. Remove selected users.

These tests perform several hundred verifications, which covers the page and its operation completely.

Can you spell D-R-Y? With these tests in hand, no other test will ever have to verify anything on this page.

Now on to the next page!

Pass the Object, Please

This sign-in method looks reasonable:

public HomePage SignInPage.SignIn(String userName, String password)

It isn’t reasonable.

Why? Because it violates encapsulation: the caller knows (or thinks it knows) what’s needed for signing in.

What if a scanned-in card id is added to the sign-in procedure? Well, that would require the method to be changed.

But actually, that’s none of the caller’s business in the first place.

This is reasonable:

public HomePage SignInPage.SignIn(User user)

Moral: don’t pass multiple data items from an object. Pass the object!

Clean and DRY Verifiers

In a Coded UI Test (CUIT), a test method is a method that has attribute TestMethod. A test method is what many might call a test script. It’s the outermost method in the test, and directs the test steps.

Some say that only the test method itself should perform verifications, that a method in a page object (or other supporting object) should not perform verifications automatically:

The usual reason given is that such automatically performed verifications definitely will affect performance, and may not even be wanted or needed in a particular test context.

I agree, but with one addition: a method can appropriately perform verification at the request (direct or indirect) of the test method. So the request for verification should originate in the test method.

No matter where the actual verification is performed, the verifier method must log the expected value, the actual value, the verdict (pass or fail), and a descriptive message.

Question: Where is the best place to perform the actual verification?

Answer: Wherever it will be clean and DRY (Don’t Repeat Yourself).

A that will be where the verification method has the fewest and simplest parameters passed to it: in a page object!

A page object encapsulates its entire page, so it already has access to the HTML control that has the actual value for the verification. That means that a verification method in the page object need not pass the actual value. And that means, in turn, that a call to the verification method has fewer parameters: at most, just the expected value and a message string. That’s pretty DRY.

But wait, there’s more!

When the expected value is a constant (a table column header, for example), that value can also be stored in the page object. So in that case, the verification method would have no parameters at all. That’s really DRY.

Examples:

  • Home page verifies logged-in user’s name:
    public Boolean VerifyUserName(String expectedValue, String message = "User name")
  • User page verifies user data:
    public Boolean VerifyUser(User expectedValue, String message = "User")
  • Users page verifies that user does not exist:
    public Boolean VerifyUserNotExist(User expectedValue, String message = "User does not exist")
  • Page object knows its own column headers: public VerifyColumnHeaders()
  • Page object knows its own URL: public VerifyUrl()

Finally, I have a special-purpose verifier:

  • Verify that the locators in a page object correspond to actual controls in the UI: public Boolean VerifyLocators()

So performing verification in a page object, under the supervision of the test method, is easy. And doing so improves both cleanliness and DRYness.

Location, Location, Location

In my Coded UI Test (CUIT) page objects, I encapsulate locator data into a Locator object. A locator defines and specifies the search for a specific HTML control in the target web application.

The Locator object has:

  • A locator name.
  • One or more name/value pairs, each of which indicates an attribute name and value to search for.
  • A search criterion: Contains or EqualTo.
  • A status:
    • Required: The control is expected to be on the page now; it is an error if it is not present.
    • Forbidden: The control is expected to not be on the page now; it is an error if it is present.
    • Allowed: The control is allowed (but not required) to be on the page now; it is not an error whether or not it is present.

Locator Creation

A page object creates locators when it is instantiated. Many of the locators will be Required. Some may be Forbidden or Allowed.

Locator Maintenance

The page object is responsible for maintaining the status of its locators. For example, if a locator is initially Forbidden, but some Javascript creates the corresponding control, the page object must change the status to Required.

More specifically, I have a user page with a delete button. If the test presses that button, the application will put up a display with buttons for confirming or cancelling the deletion. The locators for these two buttons, which have been Forbidden must now be changed to Required.

Conversely, when one of those two buttons is clicked, their containing display is removed, and the two locators must be returned to Forbidden.

The reason for this strict locator maintenance is that the page object may be called upon at any time to verify its locators’ controls: to confirm that each Required locator’s is present, and that each Forbidden locator’s control is absent.

In the Page Object: Locators, not Controls

A page object operates on an HTML element by passing a locator to a lower-level library method. That method finds the control and performs the operation. For example, a page object can call a button-click method, passing a locator; the button-click method uses the locator to find the button, then clicks it.

The page object does not retrieve a control, nor, I think, should it. It’s not clear to me when or why the object might to go “stale” (no longer reflect the state of the UI), so I prefer to get a fresh object for each operation. And, I think, doing so is just good data-hiding.

A Thorn in My Side

A very few of the HTML elements I’m interested in do not have sufficiently unique attributes to support unambiguous location. For example, there may be several h2 elements on the page, each with no attributes at all.

Perhaps the most fragile way to get at one of these is to search for all h2 elements, then take the one with the appropriate index. A change in the number or positions of the elements can break the test.

A way that’s only a little better, and one that I’ve felt obliged to use occasionally, is to find a nearby element (one that can easily be located), then “walk” the DOM (accessing parent and child elements) to get to the desired element.

I hate having this DOM-walking code in my page object, even though it’s factored into a method. Doing things this way means that there are two completely different ways the page can operate on a control:

  • The right way: Call for the operation to be done, passing a locator object.
  • The wrong way: User a locator to retrieve a control, walk the DOM to get to the desired control, then call for the operation to be done, passing a control.

Note that this means that for the same operation on different HTML elements, I need two method overloads: one that accepts a locator object, and another that accepts a control object.

A Partial Solution

A partial solution I’m considering is enhancing class Locator so that it stores one of the following:

  • Name/value pairs, representing the usual attributes in the element to be searched for.
  • The method that’s called finds the control and performs the operation.

  • A reference to a method that returns a control. The method that’s called calls the function, gets the control, and performs the operation.

Doing this would at least mean that a page object always works with a locator, and never with method that returns a control object. And that in turn would mean that if (when?) the HTML is improved, the locator could be adjusted without requiring other changes.

Thoughts, anyone?

Getters and Setters

Some test automation I “inherited” a while back had a textbox whose getter method was called GetCurrentBrick (not quite its real name).

Take just a moment to try to guess what the setter was called. The answer here is white text on white background, so select between the arrows to view: > Brk <

[Just discovered that it’s not obvious how to highlight text on some mobile devices, so will say here that Brk is the name given to the setter.]

Nice, huh?

If there is going to be a getter/setter method pair (and we'll get to that question in a minute), they should have consistent naming. A start would be GetCurrentBrick and SetCurrentBrick. Actually, though, a textbox doesn’t have any content but the “current” one, so it would be better to say just GetBrick and SetBrick.

But why have two methods at all? The setter should return the previous state, in case the caller needs to restore the previous value. Therefore it’s simple and useful to have a single method that always gets and can, optionally, set.

Thus a call to method Brick() with no value parameter is a pure getter, while a call with a value parameter Brick("in the Wall") is a setter that returns the previous value. This means there’s only one method name to learn, and it’s pretty intuitive that the value-less call is a getter, while the value-bearing call is a setter.

The exact implementation of this method would depend on the programming language at hand. In C#, which is what I’m using at the moment, the signature for a method of type String would be:

  • public String Brick(Locator locator, String value=null)

where the method tests value for nullity and acts accordingly. (The locator is something that tells CUIT how to find the control. I’ll be writing about class Locator in a future post.)

There will be text that’s displayed but can’t be set, and for that we’d need:

  • public String Brick(Locator locator)

And text that can be set but not got (password, for example):

  • public void Brick(Locator locator, String irretrievable)

Of course none of this is new. But as the anecdote at the beginning of this post demonstrates, Dr. Johnson’s famous observation remains all too true: People more frequently require to be reminded than informed.

Burdette Lamar

Keep Your Page Objects DRY

The page object pattern is an extremely important pattern that’s well described over at Selenium. If you don’t know about the pattern and haven’t read their article, go read it now.

Everything said in the article also applies to dialogs, so don’t be misled by the word page. They could just as well have written about dialog objects.

The article also suggested a wonderful practice that’s new to me:  Having a method in a page object return another page object. I’m now doing this whenever a method lands the application on a different page. Example:  Completing the sign-in on the sign-in page lands the app on the home page, so method SignInPage.SignIn returns a HomePage object.

So what can I add?  Well, DRYness! (Don’t Repeat Yourself!)

[This post originally emphasized inheritance. David Green commented that composition is more flexible. I agree, so I’ve revised the post.]

I’m going to talk about composition and inheritance here because the language I’m using is C#. The corresponding strategy in a different language might be different: Ruby mixins, Python modules, etc.

Let’s get to it. The web application I’m testing, like many others, has some elements that appear on many but not all of its pages. For the sake of DRYness, it’s useful to handle these elements with composition and inheritance (or other code-sharing strategy, as above).

_BasePage

The first class for page encapsulation is the base class _BasePage. I’ve given the class name an underscore to emphasize that it’s not an ordinary page class — it is not itself the encapsulator of a single web page.

Every page class derives from _BasePage.

What’s in _BasePage? Only those things needed for every page in the application:

  • A Context object.
  • Support for the Locator objects that will tell CUIT how to find controls.

I’ll write about classes Context and Locator in other posts.

Compositors

In the application:

  • The menu bar appears on every page except a popover and the sign-in page.
  • The footer appears on every page except a popover. In this particular app, a popover is sufficiently page-like to be treated as a separate page.

The other elements that are shared among pages are handled via composition, because different pages may have different mixtures of those elements.

Each of the compositors is a class whose constructor accepts a page object. The compositor defines locators and adds those locators to the given page.

_Menubar

Almost all pages have the menu bar, which has the basic navigation for the application. The page objects for such a page declares an instance variable _Menubar menubar and assigns it a new instance of _Menubar, whose constructor adds the appropriate locators to the page object.

_Footer

Like the menu bar, most pages have footer boilerplate. The page object for such a page declares an instance variable _Footer and assigns it a new instance of _Footer, whose constructor adds the appropriate locators to the page object.

“Tabbed” Pages

A few pages in the application have tab-like behaviors. On such a page, there’s an upper area with a title and two or more links (tabs). Below there’s content that can be changed by clicking one of the links.

Let’s say that there are four tabs, for the four seasons.

Then a class _Seasons encapsulates the elements in the upper part of the page.

Each of the tabs is encapsulated by a page object (derived from _BasePage). Each page object declares an instance variable _Seasons seasons and assigns it a new instance of _Seasons, whose constructor adds the appropriate locators to the page object.

So each season tab has its own locators, plus those in _Seasons, plus any it chooses to get from _Menubar and _Footer.

Now that’s DRY!

Burdette Lamar