The rule of thumb when writing code is not to repeat oneself. The same code reused several times means messy and unclear code, and we want to avoid it by all means. One of the ways to do that is to use the powerful map() method. It will allow you to reduce lines of code into one single line.


What is the map method?

The map method is a built-in, ready-to-use function that allows you to perform an action on elements in an array or a hash. Its main purpose is to transform data. It will iterate through each element in an array and do on each element whatever you need it to do. Unlike each method which only iterates through an array, the map method will modify the array and return a new array containing the modified elements. It is important to emphasize that the map method DOES NOT alter the original data. If we want to change the original data, instead of .map, we will use its destructive twin .map!

One of the typical basic examples is the transformation of an array of strings into upper-case strings. In all the examples below, we have used Ruby and RSpec combo, but it can be adapted to any of the testing frameworks you are using:

initial_array = ["my", "array", "of", "strings"]
new_array = initial_array.map { |item| item.upcase }

puts new_array 
OUTPUT => ["MY", "ARRAY", "OF", "STRINGS"]

Or we can transform an array of integers, where we want to multiply by 5 each of the numbers in an array:

initial_array = [1,2,3]
new_array = initial_array.map { |numbers| numbers * 5 }

puts new_array 
OUTPUT => [5, 10, 15]

Here we have our original array of elements in initial_array. We call out the .map method on it and save it into a new variable called new_array. We will temporarily assign a variable name to each element (in these cases |item| and |numbers|) that will be used during the iteration. Then we will add the action that we want to perform, i.e., upcase for transforming strings into uppercase, or * 5 to multiply the initial values. Here, you can check out the visual representation of the map method.

“Ok, but what should I do as a tester with an uppercase array or an array with multiplied numbers?”, you might wonder. Don’t worry, here are some practical examples of using the map method in your automation test scripts.

Map method in automation scripts


Use map in the parameters

Let’s say you want to write an automation script for an address book. In your script, you will have a hash containing contact information for two persons living at the same address. You already have a shared context containing methods to create entries in the address book, and you want to add these two persons to it. In the parameters section of your script, you might use the following code:

contact_data = [
                {
                 'name' => 'John Smith',
                 'address' => 'Main Street, 1',
                 'city' => 'Springfield'
                },
                {
                 'name' => 'Joe Smith',
                 'address' => 'Main Street, 1',
                 'city' => 'Springfield'
                }
               ]

Then you will call these parameters for the address book in the existing shared context:

contact_data.each do |contact|
include_context 'Add people to the address book', contact
end

Instead of repeating the same information in your parameters, you might as well call the map method to replace the name in the hash and leave the rest of the contact information unchanged:

contact_data = %w[John Joe].map do |name|
               {
                'name' => "#{name} Smith",
                'address' => 'Main Street, 1',
                'city' => 'Springfield'
               }
end

Then you will call your shared context with each loop that will iterate through your hash and replace only the name field:

contact_data.each do |contact|
    include_context 'Add people to the address book', contact 
end

Quick note

First, let’s explain the %w part (also known as a “word array”). It is a special syntax in Ruby for creating an array of elements, where the individual elements are separated by whitespace. Basically, we can write an array of elements without using the quotes and separating them with a comma. If we want to include an element with two words, we will simply add \ followed by a space between the elements. 

Example:

standard_array = [“This”, “is”, “an”, “array”, “of words”, “and”, “numbers”, “like”, “123”]

w_array = %w(This is a an array of\ words and numbers like 123)

Now back to our example of the map method. You see now what we have done? We have removed all the unnecessary lines of repeated code by first telling Ruby through %w[John Joe] to break up the input strings into words and to return an array of words (i.e. [“John”, “Joe”]), we have used the map method to replace the name of each person and reused the rest of the contact information. First, we will execute the code inside the shared context ‘Add people to the address book’ for John Smith, then we will do the same for Joe Smith.

Use map inside your methods


Let’s see another example.

In your automation script, you have to check the headers of a table. You want to compare the headers from the table with the expected headers to ensure they match. You might want to create first an empty array for your extracted headers, then iterate through the existing headers, extract the text from them, add them to your new array, and return the new array with the extracted headers. This operation could look as follows:

def take_headers_and_add_to_an_array
    extracted_headers = Array.new
    headers = xpath_for_the_headers.to_a
    headers.each do |h|
      extracted_headers.push h.text.strip
    end


    extracted_headers
  end

Here comes all the power of the map method to reduce your code. Instead of all these lines, you can use the following:

def take_headers_and_add_to_an_array
    xpath_for_the_headers.to_a.map { |header| header.text.strip }
end

Et voilà! Instead of six lines of code, we have performed the exact same action in only one line. We added the headers to an array through the xpath locator and used the map function with the temporary header variable. We have transformed these headers into text, then we have removed the whitespaces through strip. Now we can use our take_headers_and_add_to_an_array method to compare it to the expected result.

Bottom line

Whenever you need to perform an action on an array to get another array in return or whenever you see a repeated code in a hash, think of the map method. It is definitely a method worth mastering and digging deeper into. 

Don’t repeat it, recycle it!


“Reducing a Code with the Map Method” Tech Bite was brought to you by Maja Mujanović, Junior Quality Assurance Engineer at Atlantbh.

Tech Bites are tips, tricks, snippets or explanations about various programming technologies and paradigms, which can help engineers with their everyday job.

Leave a Reply