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.