A repost of my daughter’s article with permission. I added a few notes. This is also included in the 10-minute guide series:
10-Minute Guide to Set up Test Automation using Selenium WebDriver with Ruby
10-Minute Guide to Object-Oriented Programming
Most modern programming languages support object-oriented programming (OOP). Mastering OOP is a must for software engineers and test automation engineers nowadays. This quick guide is intended for non-programmers to get a quick understanding of OO, in particular, to become automated testers.
Object-Oriented Concept in a Nutshell
OOP sounds like a complicated concept, at least for me when I was 13 years old. It turned out to be quite simple after my father illustrated with this example:
Car is a class, a type of something, it has the following two functions (plus many more…):
accelerate
brake
My car (the one in my garage) is an object of Car, it can ‘brake’ and ‘accelerate’. I can physically drive it.
Now have a think about the statements below:
my_car = Car.new
my_car.accelerate
your_camry = Car.new
your_camry.brake
.new
creates an instance of a Class, in this case, Car. The returned instance is also known as an Object.
In Ruby, everything is an object (or class)
Ruby is a pure Object-Oriented language, comparatively, Java is not as it has primitive types. Learning OO with Ruby is easier.
a_string = "Ruby is cool"
a_string.size # => 12
iphones = ["iPhone 4s", "iPhone 5S", "iPhone 5C"]
iphones.sort #=>["iPhone 4s", "iPhone 5C", "iPhone 5S"]
a_string
is an object of String class, and iphones
is an object of the class Array. Here is how to find out an object’s class.
a_string.class # => String
iphones.class # => Array
The reason we are able to use.size
and .sort
is because these functions are defined in the String and Array classes respectively.
an_object.function
Class Inheritance
Inheritance is one type of relationship between two classes. For example, seagulls and parrots are both birds, thus they share the common features of a bird.
The code below defines three classes: Bird, Seagull, and Parrot.
class Bird
def fly
puts "I am flying"
end
end
class Seagull < Bird
end
class Parrot < Bird
def speak
puts "if someone teaches me"
end
end
Inheritance can be described as “is-a” relationship. For example, we can say “Parrot is a Bird” and “Seagull is a Bird”, but not “Parrot is a Seagull”.
An object of a child class can invoke a function defined in the parent class.
a_seagull = Seagull.new
a_seagull.fly # => "I am flying"
my_parrot = Parrot.new
my_parrot.fly # => "I am flying"a_seagull.is_a?(Bird) # => true
my_parrot.is_a?(Bird) # => true
As you can see, by using inheritance, the code (defined in functions, such as fly
in Bird
class) can be reused.
A child class can define its exclusive functions, such as speak
in Parrot class.
my_parrot.speak # => "if someone teaches me"
a_seagull.speak # NoMethodError: undefined method `speak' for #<Seagull:0x..>
Child Class Can Override Behaviours
A function defined in a class is also known as “Behaviour”. A child class can override the behavior defined in its parent class, like the example below.
class Ostrich < Bird
def fly
puts "I'd rather run"
end
end
ostrich = Ostrich.new
ostrich.is_a?(Bird) # => true
ostrich.fly # => "I'd rather run"
This has a fancy term, Polymorphism, one of the most asked questions in programmer interviews. Don’t overthink it, do some OO practices, and you will get a deep understanding. For now, at least for test automation engineers, my one-line explanation will do.
Use your newly learned OO knowledge to understand Automated Test Script
Below is a raw Selenium WebDriver test that follows the Maintainable Automated Test Design.
it "Select One-way trip" do
driver.get("https://travel.agileway.net")
login_page = LoginPage.new(driver)
login_page.enter_username("agileway")
login_page.enter_password("testwise")
login_page.click_sign_in
flight_page = FlightPage.new(driver)
flight_page.select_trip_type("oneway")
flight_page.select_depart_from("Sydney")
flight_page.select_arrive_at("New York")
flight_page.select_depart_day("02")
flight_page.select_depart_month("May 2023")
flight_page.click_continue
expect(page_text).to include("2023-05-02 Sydney to New York")
end
Two classes:
These two Page Classes represent the two web pages you see in the browser.
LoginPage
FlightPage
Three objects:
driver
, the instance of Selenium WebDriverlogin_page
andflight_page
are instances ofLoginPage
andFlightPage
respectively.
Several functions:
You can think a function in a page class is an operation that a user can perform on the web page.
enter_username
,enter_password
andclick_sign_in
inLoginPage
classselect_trip_type
,select_depart_from
,select_arrive_at
,select_depart_day
,select_depart_month
, andclick_continue
inFlightPage
class
What does a page class look like?
Here is the content of flight_page.rb
file, which defines FlightPage
class.
require File.join(File.dirname(__FILE__), "abstract_page.rb")
class FlightPage < AbstractPage
def initialize(driver)
super(driver, "") # <= TEXT UNIQUE TO THIS PAGE
end
def select_trip_type(trip_type)
driver.find_element(:xpath, "//input[@name='tripType' and @value='" + trip_type + "']").click
end
def select_depart_from(from_port)
Selenium::WebDriver::Support::Select.new(driver.find_element(:name, "fromPort")).select_by(:text, from_port)
end
# more functions ... def click_continue
driver.find_element(:xpath,"//input[@value='Continue']").click
end
end
Now with this quick guide, do you understand the above test scripts better?
Review by Zhimin
I remember that it took me quite a long time to understand object-oriented concepts when I was at university in the early 90s. I had no tools to try, just read theories from books.
In fact, the OO concept is not hard to understand, the proof is my daughter could do basic OO programming at the age of 13. Many OO books or tutorials were doing it wrongly. Those instructors like to dump the concepts or items such as Polymorphism, Override, Overload, …, etc. (by the way, these are frequently asked terms in programmer interviews). I was taught this way since primary school, I did not like it. IMO, it was not an effective teaching method.
My teaching style:
Using simple words.
Using simple and easy-to-understand examples.
Carefully designed short hands-on exercises.
Intentionally ignore some concepts initially, and introduce them gradually.
Students do need to learn all, learning enough to practise, with an instructor’s coaching, is much more fun and effective.Build up the attendee’s confidence with repeating and hands-on exercises, then a new piece of knowledge.
Good preparation. I get the environment set up ready so that the students can focus (you know the attention span of the new generation).
For example, I have seen Selenium instructors spend the first hour setting up Java and Eclipse. In my training, yes, I taught attendants to set up the environment from scratch as well, in less than a minute, using the TestWise Ruby edition.
That’s why my Web Test Automation with Selenium Training only requires one day, and most attendees could start working on real tests (still require coaching now and then) the next day.
For more on learning Ruby programming, check out my book: Learn Ruby Programming by Examples.
Related reading
My eBooks:
- Practical Web Test Automation with Selenium WebDriver
- Practical Continuous Testing: make Agile/DevOps real
- Learn Ruby Programming by Examples
- Learn Swift Programming by ExamplesSoftware Design Pattern By Example:
- Singleton
- Strategy
- Template Method