31 July 2012

Watir: simple automation sample that's far too brittle

Once Watir is installed, along with Ruby and the Ruby DevKit (instructions for which are at www.watir.com), I was able to write out the following after reading their basic manual:

require "watir-webdriver"
browser = Watir::Browser.new :ff
browser.goto "google.com"
browser.link(:text => "Images").click
browser.text_field(:name => "q").set "plane"
browser.button(:value => "Search by image").click


I saved it to a .rb file and ran it: ruby google_search.rb 

Is there any problem with this example?

Yes, there is.  It works, for now.  That's the problem.  It's entirely too brittle.  In fact the example that comes with Watir doesn't work.  Google has changed their value for the Search button since the documentation was written. 

The Watir example used a value of "Search Images" - which has since changed to "Search by image" - if you use this type of automation text will no doubt change often.  It's best to use CSS ID's or Classes as often as you can. 

I'm not sure yet if Watir supports ID's, i'm sure it does.  But I'll need to dig into it further

Watir and Ruby

I started QA / Web automation in a language called Groovy.  I found it very difficult to pick up.  The people who suggested it as a useful language felt it was easy for newcomers to pick up. 

The problem with Groovy is:
  • The training resources are written for Java developers.  If you're not a Java developer you almost need to pick up Java first then learn Groovy - which is entirely backwards to the goal
  • Groovy has little support out there, compared to Ruby
  • Pain in the Ass to set up an automation framework in it.  Very fragile.  I've been using GEB - but you end up having all sorts of conflicts with the Groovy compiler verison, Webdriver verison, Spock version, etc.   It's constantly needing supervision and maintenance. 
The upside of Groovy is:
  • Native use of Java (you can just type Java code and the Groovy compiler will run it)
  • Native support for JODBC drivers.
But tonight, having never used Ruby, I decided to try and install Watir to see how daunting a task it would be. 

In less then about 20min (10min to install Ruby and Watir) I was able to write a test in the Watir framework. 

Groovy took me months to get the GEB framework going. 

I love IRB - interactive ruby is so great to actually see how to drive the browser before comitting to code... I can just type:
irb
>require "watir"
>browser=Watir::Browser.new

At this point a default browser spawns!

>browser.goto "watir.com"

It pulls up www.watir.com

Pretty nifty and easy.  IRB is great to just see what you want to get done. 

I'm not sure yet if Watir will have the great JQuery that Groovy has built in, but I'll give it a spin and see how it works out.

27 March 2012

using .times in a test

When you have a selection of items you want to run the same action on, you can use .times.  .times will execute the action in the closure the specified amount of times.  For example, if you have a page with 20 checkboxes, and you want to check 8 of them and save, you could run:

8.times {
    clickCheckBox(it+1).click()
}

In the example it will execute the closure statement 8 times.

Within the closure the clickCheckBox is a reference to static content defined on the page object.  Like:
clickCheckBox {checkBox->$("#value input[value='$checkBox'")]}

A developer on my team (Ishwinder) helped me out with this.  I would have just used the typical $(#value input[value='1']) but he made it more elaborate by putting a integer here.  Then he says back in the test's closure:

(it+1).click()

Which is setting the integer value.

Of course this works in an example where the value of each checkbox is a sequential number.

When the test is run, it runs this action 8 times, incrementing the value by 1 each time, and since in this case the check box value identifiers in the html are sequential numbers, it works beautifully. 

This can be useful in other cases as well, where you want to run the actions within a closure repeatedly.  It certainly refactors a lot of code into a nice little snippet.

26 March 2012

The input type of the launch configuration does not exist

I was hitting this error msg, when trying to run some GEB tests via JUnit in STS.

I googled and found this guy's page:


which gave me the answer.  The answer is to add the folder with the test to the build path of the source folder.

Just right click the test's folder in STS/Eclipse and click Build Path and then "Add to build path."


02 March 2012

More on Modular Tests

When looking at modular tests, it's looking like the best way to utilize GEB is to improve the at function.

In the beginning we would test a page and through an assertion of at page. like at HomePage.  The at closure, by default, would check the title.  But we're now putting in all the main modules of the page into the at closure.

This way, when we check at Page, we will get a verification that all appropriate div's are loaded.

This way, the main page spec will verify the page modules.

The actual content itself should be verified in separate classes/tests.

This makes the test more clean and easily readable.

Assertions shouldn't be made at markup level

It's often tempting to make assertions at the markup level.  But in practice the assertions at the markup level, like:
td.header.text().equals("Test") are very fragile.  If the page layout changes the test will break.

This might be a good practice if the testing expectation is to break anytime layout changes.  But in general, for my use of the tests, it makes more sense to not break on layout changes, but to verify the content loading.

In those cases, we are working with Front End Developers to insure that page layout changes keep to a standard.  Like having a Div ID or Class that could be referenced. 

DRY

In our code review today, this subject of DRY tests came up.
"Dont RepeatYourself."

When we write tests, sometimes the test class can get really busy and code can sometimes be repeated again and again for different iterations of the test. 

Once the test is green, it's time to refactor it and make it shorter and shorter - by making use of good coding practices to keep the test DRY.