Case Study: Leveraging Dynamism in Automated E2E Test Scripts with Ruby
How Ruby's dynamic features reduce boilerplate and enable flexible, easier-to-maintain E2E test scripts
Ruby is a 100% object-oriented dynamic programming language (while Java is not), everything in Ruby is an object.
1.class #=> Integer
“23”.class #=> String
[4, 5, 6].class #=> Array
For test automation engineers: in Ruby, you don’t need to worry about data types as you would with static type checking in compiled languages.
Let me illustrate with an example. Below is an API test script. As we know, a significant portion of API test scripting involves generating test data.
def generate_customer(email)
result = Customer.new(email: email,
first_name: Faker::Name.first_name, last_name: Faker::Name.last_name)
return result
end
it “API Testing: create customer” do
customer_json = generate_customer(”a@agileway.com.au”).to_json
# invoke API with the above payload
end
The generate_customer
function can generate a random customer, using the “Faker” library.
Suppose that a new API service is added to support creating multiple customers.
I can create another function generate_customers
.
def generate_customers(email_array)
result = []
email_array.each do |email|
result << Customer.new(email: email,
first_name: Faker::Name.first_name, last_name: Faker::Name.last_name)
end
return result
end
it “API Testing: create mulitple customers” do
customer_json = generate_customers([”a@c.com”, “b@c.com”]).to_json
# invoke new API the above payload
end
This is fine, but there is some duplication in the test data generation, i.e., generate_customers
and generate_customer
functions. Duplication is no good (DRY principle). So I refactor them to use just one function, handling one or multiple customers.
it “API Testing: create one customer” do
customer_json = generate_customer(”a@agileway.com.au”).to_json
# invoke API the above payload
end
it “API Testing: create two customers” do
customer_json = generate_customer([”a@c.com”, “b@c.com”]).to_json
# invoke API the above payload
end
People with programming in a compiled language might think: You are doing method overloading, with two function definitions, like the one below in Java:
public void generateCustomer(String email) {
// ..
}
public void generateCustomer(ArrayList emails) {
// ..
}
Not really. Ruby is a dynamic scripting language; we can do with just one function, handling both types of input arguments.
def generate_customers(email)
if email.is_a? Array
result = []
email_array.each do |email|
result << Customer.new(email: email,
first_name: Faker::Name.first_name, last_name: Faker::Name.last_name)
end
else
Customer.new(email: email,
first_name: Faker::Name.first_name, last_name: Faker::Name.last_name)
end
end
end
Neat, isn’t it? This is just one of the many strengths of Ruby — a dynamic language highly suited for E2E test automation scripting.
Related reading: