The Agile Way

The Agile Way

Share this post

The Agile Way
The Agile Way
Functional Test Refactoring: Extract Page Function

Functional Test Refactoring: Extract Page Function

Many testers are aware of Page Object Model, but often don’t do it because time-consuming and error-prone. This refactoring helps! I have been using it many times every working day since 2006.

Zhimin Zhan's avatar
Zhimin Zhan
Mar 22, 2023
∙ Paid
1

Share this post

The Agile Way
The Agile Way
Functional Test Refactoring: Extract Page Function
Share

This is one of the 6 Functional Test Refactorings (see the introduction here):

  • Extract Function

  • Move Function to Helper

  • Move

  • Extract Page Function

  • Introduce Page Object

  • Rename

I have been using “Extract Page Function” refactorings many times daily when working on automated test scripts, since 2006. A quick and reliable practice transform raw test automation steps into a more readable and maintainable version in Page Object Model design.

In my opinion, “Attach test execution to the existing browser” and this “Extract to Page Function” refactoring are the top 2 reasons and practices for my high productivity (10X+ compared to other senior QA engineers) in developing/maintaining high-quality automated end-to-end (via UI) test scripts.

Table of Contents:
∘ Introduction of Page Object Models
∘ Knowledge Point: Page Object Model makes Automated Test Scripts easier to read and maintain
∘ Demonstration (video)
∘ Motivation
∘ Sample Test Case (before)
∘ Sample Test Case (after refactoring)
∘ Mechanics
∘ Refactoring in TestWise
∘ Expected Result
∘ Test Data
∘ “Extract to Page Function” refactoring in steps
∘ How did it work?
∘ Continue “Extract to Page Function …” Refactoring
∘ Sample Page Class (after)
∘ Benefits
∘ Exercises
∘ Related Refactorings

Introduction of Page Object Models

Page Object Models (POM) is the most well-known design pattern in test automation. Selenium documentation lists POM as the first best practice.

“Page Object is a Design Pattern that has become popular in test automation for enhancing test maintenance and reducing code duplication”. [Selenium Doc]

The POM pattern is not new, it existed a few decades ago, i.e., it has been battle-field tested.

One veteran tester in Canberra messaged me in 2009,

“Just finished reading your book (Practical Web Test Automation) and I like it. I am writing to let you know that I have used the page object pattern in 80s. Glad to see you include in the Maintainable Automated Test Design and the support in TestWise”.

The “Object” in POM comes from Object-Oriented Design. Testers without a programming background, don’t worry, the OO knowledge required for test automation is minor. Check out the 10-Minute Guide to Object-Oriented Programming for Automated Testers.

Knowledge Point: Page Object Model makes Automated Test Scripts easier to read and maintain

Let me illustrate it with an example. What do you think of the test script below:

It is not too bad, some may think. But it is no good, from a maintenance perspective. Suppose, you have 100 test scripts like the above, and the user name textbox’s name is changed from `fromPort` to `fromCity` (on the flight page), what will happen? Will you do a global search and replace in 100 test script files, it’s not good, isn’t it?

Now hold that thought. Have a quick look at the design below.

I break the test steps into four sections, each section corresponding to the user operations on a web page:

  • Home page
    - enter a user name
    - enter password
    - click the sign in button

  • Flight page
    - Select from city
    - Select the destination city
    - Click the next button

  • Passenger page
    - Enter the passenger’s first name
    - Enter the passenger’s last name
    - Click the next button

  • Confirmation page
    - Assertion

This design is clearly better. During my training, some manual testers might worry that some level of coding will be involved with implementing this. Yes, there is a bit of coding, but you rarely need to code it, and this often turned out to be the most satisfying part of the training for them. How? That’s what “Extract to Page Function” refactoring comes in, using this in TestWise is fun! They don’t need to code classes or functions, TestWise does these for them.

Demonstration (video)

Motivation

You have long logically grouped test steps

Extract test operations on a web page into a function in a new or existing Page Class.

Sample Test Case (before)

Below are several linear test steps in a test case. I purposely choose some long ones (to make it look complex).

it "User can select one way trip" do
  driver.find_element(:xpath, "//input[@value='oneway']").click
  Selenium::WebDriver::Support::Select.new(driver.find_element(:name, "fromPort")).select_by(:text, "Sydney")
  Selenium::WebDriver::Support::Select.new(driver.find_element(:name, "toPort")).select_by(:text, "New York")
  driver.find_element(:xpath, "//input[@value='Continue']").click
  expect(page_text).to include("Sydney to New York")
end

Issues with the above test case

  • Not easy to understand

  • Hard to maintain

Sample Test Case (after refactoring)

  it "User can select one way trip" do
    flight_page = FlightPage.new(driver)
    flight_page.select_oneway_trip
    flight_page.select_from_city("Sydney")
    flight_page.enter_to_city("New York")
    flight_page.click_continue
    expect(page_text).to include("Sydney to New York")
  end

It is a lot better, isn’t it?

Mechanics

  1. Identify operations on a web page

  2. Select the first operation on the page

  3. Create a Page Class file, giving a meaningful name

  4. Create a function in the page class with the selected operation

  5. Replace the original test step with a reference to the page class’ operation

  6. Rerun all tests

Refactoring in TestWise

  1. Select the test steps in the test script file

  2. Invoke the refactoring

  3. Enter new or Select existing Page name

  4. Enter a function name

  5. Adjust parameters if necessary (TestWise will analyze the test steps and pre-determine the parameters)

  6. Preview the new function

  7. Apply the refactoring

Expected Result

  • A new function with the supplied name is inserted in the new/existing Page Class

  • The test steps in the test case are replaced with a call to the new Page’s function

Test Data

The same test project that helps you do refactoring exercises quickly:

> cd my-working-dir
> git clone https://github.com/testwisely/agiletravel-ui-tests

The test project is at my-working-dir/agiletravel-ui-tests/pre-refactoring .

“Extract to Page Function” refactoring in steps

Keep reading with a 7-day free trial

Subscribe to The Agile Way to keep reading this post and get 7 days of free access to the full post archives.

Already a paid subscriber? Sign in
© 2025 Zhimin Zhan
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share