Automating the automation

Have you ever find yourself writing the exact same basic tests for certain objects over and over again? With the only difference on the id or path or even the element retrieval?

Wouldn’t it be nice to have some way of doing this bit faster? Automation is about making your computer do repetitive tasks for you, and this can be applied to everything, including, yes, writing code.

The process to automation is as follows:

  1. Identify repetitive tasks
  2. Write code that would do these tasks for you
  3. Identify when the code needs to be executed
  4. Execute the code or automate the execution

In order to give an example or something being repetitive during automation, I would like to introduce the page object model. If you already know about this, maybe you should skip the next section.

Page object model

The page object, in short, it’s a model for organising functional testing classes and objects so the code is cleaner and easier to modify. These sort of models are also known as design patterns (note to any developer reading this: yes, there are design patterns for testing and you should be using them!).

There is plenty of information about POM (page object model), starting on selenium website (http://www.seleniumhq.org/docs/06_test_design_considerations.jsp#page-object-design-pattern), so I am just going to summarise it here.

In POM, we have (at least, depending on the implementation) two different types of classes:

  1. A class (page class) that would gather all the information of the objects that we need from a website’s page (for example, a button or a text box) and micro-methods to preform common tasks (such as click, type, select, verify existence…). If you are very newbie, just open your browser’s developer mode (usually f12 does it) and using the selector hover over the website to see the objects that it has and their associated values.
  2. Another class (model class) would implement the more sophisticated methods (test cases) using the objects and methods exposed by our page class.

In this way, if the website changes layouts it would be easier to retrieve the objects again without the need of finding every instance of that object throughout the code.

1. Identify the repetitive tasks

So, you need to extract some of the elements on a website page, and add small known methods… We have found our repetitive tasks!

However, our job is not done here. There are still many things to take into account for automation:

  1. The tools: What tools are the developers using? What programming language? And how are we going to design the system in respect to this? We should, within possible, try to align with the development tools, but sometimes this is not the best choice. For example, imagine that developers use both javascript and ruby to build a website, but that you have a team full of knowledgeable test engineers experienced in Java, shall we train them and align with the developers or take advantage of their current skills? This would have to be taken case by case.
  2. Dynamic programming: Would we need to extend our framework to support elements that would be refreshed in the screen without fully re-loading the website? (Nowadays, you most likely would!)
  3. Number of elements/iframes: If we have a lot of iframes, or elements in the website (such as many nested divs), but we only need to access certain elements, we might prefer to write an automated solution that allows us to input the elements that we want. However, it could be possible that we want to define everything on a page automatically, because that takes away one manual step while keeping a reasonable load.

2. Write code that does the tasks for you

To give an example and in order to simplify things, let’s say that we have decided to create a solution in Java, that there is no dynamic loading and that we are going to say which elements and properties we want rather than getting them all.

The idea of the code is as follows:

Allow input of a list of elements, the type, the selector type and the selector for each of them. We could use a csv file for this, for example:

name= loginbox, type=input, selector=id, id=loginbox;
name= password, type=input, selector=xpath, id=…;
name= loginButton, type=button, selector=name, id=loginButton;
name= textSuccess, type=textBox, selector=text, id=success;

  1. For each of the lines on the input file, create an object with the name and selector given.
  2. For each of the lines on the input file, create a method for the object Type:
    1. For input: type method
    2. For button/href: click method
    3. For textBox: method to verify test
    4. For all: exist method

It would look something like this:

// retrieval of the fileLines left out for exemplification
for (Object o : fileLines) {

switch(o.type) {

case "input":

toPrintInPageClass += "WebElement " + o.name + " = driver.findElement(By." + o.selector+ "(\"" + o.id + "\"));\n";

toPrintInPageClass += "void " + o.name + "_type(string toType) { \n\t" + o.name + ".sendKeys(toType); \n}";

break;

case "button":

...... (you should have gotten the idea now)

This should take less than an hour to build, but after that, every page would be built in no time and the code would be less prone to errors as opposed to copy-pasting the same code over and over again. (You write one class as opposed to one per page)

An additional benefit is that if you have a manual tester in the team, now you can assign him or her the definition of the inputs and execution of the code. And you just made that person able to “program” with this “very high level programming language”.

Bonus: After this is built, we can create another class that would extract the items from the website into the input file for this class. That way we can retrieve all the elements in one go without human intervention.

3. Identify when the code needs to be executed

What happens if a developer changes the website and adds an element? Shall we execute the whole thing again or just add manually the missing element?

Even if it is tempting to add the missing element manually, I would suggest to add it to the input file, otherwise if someone decides to execute this code, your element would be missed. It is likely to still be faster to execute the code than to add an element manually.

But what if it is not? What if we have so many elements at the moment than executing the code can take longer than adding just one more?

I would still run the code rather than add elements manually, because it could as well be that some of those elements do not exist anymore. But if it is only one quick change, please remember to change the input file too.

As an addition, we could add into the code functionality to modify the class already created rather than create a new one, but I’d say this could be a lot of overhead for the benefit that you can get out of it.

4. Execute the code or automate the execution

Lastly, especially if you have the object retrieval automated too, you might want to automate the execution. For example, you can say to the computer (using a cron file could be a way): run this code every evening at 8pm. Or once a week… once a month… That way you could “completely” forget about the page definition side of the POM and just focus on the functionality.

Alternatively, if you have a way of retrieving the objects from the website, you could check that the original input is the same one as the newly generated and only execute the page class creation if they are different. That should be faster to run and it would allow you to change the actual code only when required.

However, be careful with this approaches, because you might miss when you need to add new functionality.

This is quite common in automation: you need to keep an eye on it. After it is built, it usually needs maintenance and refactoring. The better built, the less maintenance, but that does not mean 0 maintenance.

Conclusions:

Many sources would recommend to make short and simple tests, with the idea of identifying the failing parts easily and clearly. Nonetheless, sometimes you can spend longer in creating these simple tests than in actually testing the parts that are likely to fail, so the right balance is important.

What we’ve looked at today would help creating many simple tests, but you still should be careful not to over-test things as sometimes it could be too expensive or not really needed.

On the other hand, this could be a difficult task to do if we find with dynamically created objects or/and dynamically assigned id’s/properties. There are ways of dealing with these as well, but that’s…well…another story.

Advertisements

4 thoughts on “Automating the automation

    1. Hi there, thanks for your comment. I don’t have it because I think it really depends on your requirements, but I can upload one if that’s something that people are interested on 🙂

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s