Meta

Confession, this is the album where I stopped listening to REM. Dunno why, because Monster was one of the best albums I never bought.

Let us review our strategy, especially referencing our usage of White. I find it interesting that Test Complete makes it so hard to “do the right thing” as propounded by both Scripting GUI Tests in Ruby and by White. And just what is that?

The responsibility of the test script is to

perform a series of actions and verifications.

allow someone to read the script and understand what the hell is going on.

The first is a gimme. The second is interesting. When I have my developer hat on, I believe code is read more often then it is written. Wearing my manual tester hat, I believe the scripts should be clear and show intent. Tricky scripts are trouble. They are also a pain to maintain. So, if automated testing the meeting of these two worlds, the clarity and intent of the scripts must be sacrosanct. The libraries the scripts use, on the other hand, just need to be treated like code and kept maintainable.

What do I want my test scripts to look like? There are two options, DSL, or clearly abstracted test code.

open sekrit with New Document
insert image "picture.png" into sheet
first image item should match stored image "stored_0001.png"

I could do that. I could use some functional programming language. I could also use something like cucumber and code behind my feature files. But what’s the point? All I need is clarity, so the auditors / business people understand. I LIKE dsls, but this buys us nothing right now.

This is at the proper level of abstraction for a slightly motivated business user to understand. What they don’t care about at this level is the control hierarchy and control manipulation. Unless the requirements say, “via a popup menu” or some such.

If you’re going to be technical, this is a facade. It’s a wrapper to the complex underbelly of the white framework. It allows for a higher level use of the collected objects and re-use as we don’t have to repeat the code for complex actions and interactions. It also decouples our tests from changes in our application. I’ve had to chase that down in our current automation set, and I hate it.

How do we build up this abstraction? To be compatible with White’s recommended practices, I’m going to call this facade a “Screen”. We’re going to write a test for an application for which we have no source. Download blu and warm up your tweetin’ fingers. We’re going to log in!

You noticed that the BluScreen has a LoginScreen? Our application has regions and concepts to which we wish to refer. For example, we may want to represent a ribbon control, a toolbar, different types of documents, or even the clipboard.

As I malicious user, so I can't defame Brian's good twitter name,
Given blu is open
And no one is logged in
When I attempt to log in using a bad password
Then I should see a warning that my login information was incorrect

I’m holding out on you. The truth of the matter is, I started with the test steps first, then made screens that abstracted those steps. But there’s magic in the screens, they have magic strings passed around like @win.get_checkbox("Rememberage"). Where did that come from? I got it from UISpy. I’ve read about Woodstock, Snoop, and a few other tools, but UISpy is the only tool I used for this post. It is in the Windows SDK. UISpy shows a tree of controls. When you click on one, it hilights it with a red box. It also displays information such as the automation Id, those magic strings we have scattered in our code. Before my two picture tutorial on UISpy, let me note, those strings are what’s likely to break your script in the future as your application grows.

UI Spy looking at a textbox

Blu when UISpy is indicating a textfiled

what else is there?

These aren’t tests, they are automation. I’ll eventually wrap the automation with RSpec and get some real tests. I’ll get to Cucumber. I’ll publish examples. I promise.

But next, I want to address three types of custom controls:
User controls, Inhereited and Templated Controls, and Framework Elements. Another problem is finding un-named controls. I’ll see you next week.

One last bit, here’s what the white ruby library is starting to look like.

The problem, in a nutshell, is that to IronRuby MenuItemBy is actually typed as taking an array parameter. You can create a typed generic list and then call ToArray on it to cast to a typed array. See C# Lies for more detail and some code.

About Brian Ball

I'm a Software Engineer in Indianapolis. I'm interested in programming languages. I love dynamic languages like Ruby and Perl. I'm exploring functional languages like Haskell, F#, Clojure, and Erlang. I also use the .NET framework and occasionally deal with System Testing.

If you're not careful, you might also see some sketches and other art come up every once in a while.