Test Pages, Not Workflows

There can be a strong impulse to build automated testing (or even manual testing) around workflows. Makes sense, right? A workflow embodies the flow of actual work done by actual persons, so it’s good to test it.

The thing is, workflows are like chess games: many begin with similar opening moves. So when we execute a large number of workflow tests, many of the opening steps are repeated over and over again.

This is extremely wasteful of wall-clock time.

An alternative is to design testing that minimizes repetition.

What would that look like? Well, let’s take advantage of the page object pattern.

The page objects cover the application, right? So there’s a page object for each page in the application. Let’s organize the testing around that.

For each page, we can create a page test that:

  • Navigates to the page the most efficient way.
  • Performs and verifies all actions that can be initiated on the page.
  • Verifies all links on the page.

Much more efficient than a workflow test, is it not?

Like any lengthy automated test, the page test needs to guard against premature termination caused by an unhandled exception. The strategy I’ve used in the past is for the test to be divided into major parts, each of which is a function. If an exception is raised, the function catches and logs it, then returns cleanly so that the next function can continue.

(In my C# code, I’ve done this not by putting a try block into each function, but instead passing each function name to a special “catcher” function, wherein the named function is then invoked inside a try block.)

I’ll be trying out the page test concept in the sprint that starts today (yes, I’m agile!), and will report back.

Advertisements

3 thoughts on “Test Pages, Not Workflows

  1. That’s fine, if your goal is to test the functionality of a page.

    But there are 2 problems with that approach.

    1. Automation is a terribly inefficient way to test the functionality of a page. It is neither easily automated nor frequently repeatable. You spend a lot of time getting automation working (and even more time fixing when it breaks) and then you’re not actually getting good coverage.

    A human can do the job more quickly and much more thoroughly than automation. And because your automation is tied to the implementation, it never breaks unless the implementation breaks (then you need to re-write your automation) and it doesn’t test any unknowns.

    2. You’re not testing what really matters — and what’s more likely to break — the actual business requirements. Most pages do not perform a complex business function unless they’re very dynamic (in which case they’re harder to automate — see #1).

    Typically a page:
    1. renders content based on a few fixed parameters
    2. displays content in a specific way
    3. submits user input (ie. a form)

    What is the use case for a single page test? What are the expected results?

    When a user clicks a button, they should see the page displayed.
    When a user submits a form, they should see a confirmation message.

    What’s the real use case?

    When a user registers for a free account, they’re able to login and access free content, but they’re not able to access premium content until they have paid for it.

    That’s the use case that matters. And you can’t test it on a single page.

    It’s okay to think of *steps* in terms of page actions. I love page objects for how they encapsulate steps (like filling in a form) and make reuse and maintenance of those steps easier. But let’s not get short sighted and think that our implementation details are the goal of our testing.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s