TestWise IDE
Next Generation Functional Testing Tool
Refactoring
The article Refactoring Automated Functional Test Scripts with TestWise introduces the ‘page objects’ and covers the refactoring step by step. It is highly recommended to read it or the Practical Web Test Automation book first.
Refactoring has been widely used in programming, and its practices are regarded as one of the most important advancements in software development in recent decades. Test refactoring applies the code refactoring principals to test scripts. Now with TestWise, you can perform test refactorings with ease. For users with programming knowledge, some of the practices may be familiar; For those who haven’t had programming experiences, don’t worry, it is easier than your thought, with TestWise.
- Extract to Function
- Move to Helper
- Move
- Extract to Page Function
- Introduce Page Object
- Copy Page File
- Rename
Extract to Function
- Motive
- There are test steps that are performing common operations such as Log In, and User Sign Up. You want a simple way to reuse them.
- Outcome
- The selected test steps are extracted to a function and moved to a helper file, where they can be shared by all test cases.
- Benefits
- More readable scripts; Less duplication; Test scripts reuse.
Steps:
-
Identify the test steps
For example, here is a test case containing user login test steps.
it "[124] Sample test case name" do # steps before ... enter_text('username', 'john') enter_text('password', 'foobar') click_button('Login') # steps after ... end
I want to extract three login steps (starting with
enter_text('username', ...)
into a reusable function.
-
Select the identified test steps
If there is only one test step, then you may skip this step. TestWise will take the current line as selected test step.
-
Invoke the refactoring
Select the Extract to Function menu under ‘Refactor’ Menu or use the shortcut key (
Ctrl + Alt + M
).
-
Enter function name in the Extract Function dialog
You will get:
def login enter_text('username', 'john') enter_text('password', 'foobar') click_button('Login') end it "[124] Sample test case name" do # steps before ... login # steps after ... end
Move to Helper
- Motive
- You want a locally defined function in a test script to be accesible by all test scripts
- Outcome
- The function defintion is moved to test_helper.rb
- Benefits
- The function is now reusable for all test scripts, possible auto completion if IDE supports
Steps:
-
Move caret to the function name and invoke the refactoring
Select Extract to Function menu under ‘Refactor’ Menu or use the shortcut key (
Ctrl + Alt + H
).
-
Confirm
Click OK button, the
login
function will be moved totest_helpe.rb
, if you follow TestWise convention.# Now in test_helper.rb def login enter_text('username', 'john') enter_text('password', 'foobar') click_button('Login') end
Now this function is available to all test scripts. For example, to use it in a new test, type lo
then press Ctrl + Space
, which will show matching helper functions for you to select.
Move
- Motive
- You use the same set beginning or ending test steps in multiple test cases.
- Outcome
- Move the common test steps into the shared sections that will run before/after each test case.
- Benefits
- Script reuse, concise and show the purpose of the test case better.
Steps:
-
Select the common steps
The steps are common to multiple test cases in the same test script file, just select one instance of them.
-
Invoke refactoring
Either from Move under Refactor, or shortcut key (
Shift + F7
).
-
Select target
A context menu will be shown (next to the selected test steps), choose the target scope.
-
Preview the refactoring
Preview the change to the target, and check “Replace occurences in other test cases” checkbox if it applies to more than one test cases.
Here is what the test script looks like after the refactoring:
Extract to Page Function
- Motive
- You have recorded or entered some test steps, and noticed duplications. As time goes by there will be more duplications which will lead to hard-to-maintain test scripts.
- Outcome
- The selected test steps are extracted to a function in a page class which will be shared by all the test scripts. The page class provides the context, which makes maintenance easier.
- Benefits
- More readable code by expressing operations in DSL Test Scripts Reuse; More immune to application changes; Enable other convenient operations to auto-complete in TestWise.
Steps:
-
Identify the test steps on a web page
Quite often, we hear people saying something like “On homepage, click sign up link to get to the signup page, then enter preferred login …”.
In this example, we will try to extract operations to SignUpPage. In the sample script below, line 3 to line 8 are operations on the sign up web page.
it "[124] signup a new user" do logout # a function click_link 'Signup' enter_text("login", "John") enter_text("password", "foo") enter_text("passwordConfirmation", "foo") select_option("country", "Australia") click_button("Submit") # steps after ... end
-
Move the caret to first operation on wanted page
In this case, it is
enter_text(“login”, “John”)
.
-
Invoke ‘Extract Page’ refactoring
Either from the menu
Or use shortcut key (
Ctrl + Alt + G
).
-
Enter the page and operation names
It is like filling “on ___ page do ___”. In our example, we fill ‘SignUpPage’ and ‘enter_login’.
Please note the convention here, Camel Case for page names, and lower case (joined with _) as operation (or function) names.
Also I added a function parameter
username
to replace the text “John”, this will provide more flexibility for the test scripts.The test script is now changed to:
it "[124] signup a new user" do logout # a function click_link 'Signup' sign_up_page = SignUpPage.new(driver) sign_up_page.enter_login("John") enter_text("password", "foo") # more ... end
And a new file
sign_up_page.rb
is created under pages folder with the following content:require File.join(File.dirname(__FILE__), "abstract_page.rb") class SignUpPage< AbstractPage def initialize(driver) super(driver, "") # <= TEXT UNIQUE TO THIS PAGE end def enter_login(username) enter_text("login", username) end end
Rerun the test case.
-
Continue refactorings to remaining operations
The complete refactored test case:
it "[124] signup a new user" do logout # a function click_link 'Signup' sign_up_page = expect_page SignUpPage sign_up_page.enter_login('john') sign_up_page.enter_password('foo') sign_up_page.select_country('Australia') sign_up_page.submit # steps after ... end
In SignUpPage (file:
sign_up_page.rb
)class SignUpPage< AbstractPage def initialize(driver) super(driver, "") # <= TEXT UNIQUE TO THIS PAGE end def enter_login(username) enter_text("login", username) end def enter_password(pwd) enter_text("password", pwd) enter_text("passwordConfirmation", pwd) end def select_country(country) select_option("country", country) end def submit click_button("Submit") end end
Introduce Page Object
- Motive
- You want to use one of already defined page classes in test script
- Outcome
- A new page object is declared in the test script
- Benefits
- Efficient, page class discovery and avoid typos
Steps:
-
Type
ep
followed by aTab
in a test scriptA list of defined page class name will be shown in a pop up for selection.
-
Select one page class.
A page object is declared in the test script,
flight_page = FlightPage.new(driver)
.
Copy Page File
- Motive
- You want to create a similar page class like an existing one
- Outcome
- A new page class is created with same content, but with correct class name
- Benefits
- Efficient
Steps:
-
Open an existing page file
The page you want to copy from.
-
Invoke the refactoring
Either from the ‘Refactor’ menu or simply press
Shift + F5
.
-
Enter new file’s name
A new page (
user_profile_page.rb
) is created with the content from the copied page, except the page name which is based on user-entered new page file.
Rename
- Motive
- The terminology or application changes make names used in existing test cases incorrect or lead to misunderstanding. Or just find a better name
- Outcome
- The terms used in test cases are up to date with your domain language
- Benefits
- More readable test cases; No error-prone ‘search and replace’ in the whole projects
This refactoring can also be further classified into the following sub ones.
- Rename Page Class
- Rename Function Name
- Rename Local Variable
- Rename Instance Variable
- Rename Global Variable
Steps:
-
Identify a function name, class name, variable name
Just move the caret to the name you wish to change.
-
Invoke the refactoring
Either from the ‘Refactor’ menu or simply press
Shift + F6
. TestWise will analyse the script and choose appropriate sub-refactoring. -
Enter the new desired name and apply
Depending on the sub-refactoring, changes will be made accordingly.
- Rename Page Class
- Page Class declaration and all appearances of the page class name.
- Rename Function
- Function declaration and all references to that function.
- Rename Local Variable
- All appearance of variable in that scope.
- Rename Instance Variable
-
All appearances of the instance variable (like
@username
) in current file. - Rename Global Variable
-
All appearances of the global variable (like
$SERVER_NAME
) in all project files.
Here is what looks like after renaming a page object variable in one test case:
© 2006 - 2024 AgileWay Pty Ltd. Powered by SiteWise CMS