Action Sets in QTP

Assume you have some data that tells your scripts how to function when they run a particular set of actions. Instead of this logic being stored in a test script, common action sets are stored off in a data source. In this case, I’ll use Excel but you can use any data source at all. One thing I’ve found fairly effective in terms of an approach here is to create a class that contains the methods for building a dictionary that will essentially bring in the “action sets.” Here an action set refers to the data plus the test actions to take with that data against the application.

Let’s say I have data that looks like this:

Action Sets Data Source

To reference that data, after I have brought it into my framework, I ultimately want to use simple commands like this:

Those will give me the current value for whatever I’m querying. More specifically those lines are essentially asking this:

  • What screen am I on?
  • What object should I be dealing with?
  • (Any help on the locator description would be great.)
  • What action should I take with that object?
  • Assuming I need data for that action, what is that data?

Those are the context of my action. When all of that data is taken together, I have a test fixture. In order to make this work, I have to load the data into a dictionary type object. Here’s what that would look like:

Here I just pass in the name of the workbook, then the name of the worksheet within that workbook to read, and finally a row from that worksheet. What that’s basically saying is:

  • “I want to get the second row of the ActionSet worksheet from TestFixture.xlsx and make that the current test fixture.

Okay, great, but what’s testContext? What’s the Load method a part of? Well, testContext is an instance of a class and Load is a method on that class. Here’s an example of what that class might look like. First I declare an instance of a class:

Here is one possibly implementation of the class that testContext is an instance of:

What this class allows me to do is build my action set (and thus my test fixture) at run-time and I can use the testFixture object to query what was returned from the row. Therein, however, lies a problem. When this script runs it only grabs one row. That’s wonderfully fantastic if I just want to grab that one row. Yet the action set is all of those rows taken together. So clearly the idea here is that I want to grab a set of rows and have those be my test fixture.

That means I want to modify the class to handle that new requirement but I want keep the interface to the class the same. The major modification is to the BuildContext method as well as the addition of a new method:

Here you can see the changes I had to make highlighted. Notice, however, that the line you would use to call this functionality is still the same, in terms of the information you would pass:

But now that row number at the end tells the test logic how many rows to process — in other words, how much of the action set to grab in and do something with. In the first implementation it was just indicating which row to grab. Now it’s saying what range of rows to grab. In the above case, it will grab from row six back to the start (excluding the header row, of course). Also, as you can see, in the ProcessSet method I was just printing out the items with a message box but this is where logic could go to actually do something with the data returned, such as drive the application.

Note that may action sets could be in any format. For example, they could look like this:

Action Sets in BDD Style

Obviously in this case I would need mechanisms to parse out those statements and while that may be a bit of extra work — actually, more than a bit — it is certainly possible.

Now, you may ask: is the ProcessSet function the best place to handle the actual logic? Well, it seems that a good way of utilizing an object of type clsTestActions would be to place it within a framework object that acts as a test runner. Here’s an example of how this could be utilized in terms of a framework:

The idea I hope I conveyed here is focusing on a single structure — in this case, currentFixture — to store all my test actions in a descriptive way. This makes it easier to know what data is being input to my application’s screen fields and what actions are being taken. You can also see that the test runner is designed to follow a setup and teardown pattern. In this case, the setup is getting the action set that will be executed against the application. The teardown here isn’t so much about getting the system itself back to some defined state, but rather making sure that my test fixture is cleared out.

I’m still playing around with these ideas but so far I’ve found this to be a powerful approach to allowing people to write sets of actions in certain ways and having a QTP framework read those actions and then process them accordingly.

Share

About Jeff Nyman

Anything I put here is an approximation of the truth. You’re getting a particular view of myself … and it’s the view I’m choosing to present to you. If you’ve never met me before in person, please realize I’m not the same in person as I am in writing. That’s because I can only put part of myself down into words.

If you have met me before in person then I’d ask you to consider that the view you’ve formed that way and the view you come to by reading what I say here may, in fact, both be true. I’d advise that you not automatically discard either viewpoint when they conflict or accept either as truth when they agree.

This entry was posted in Automation, QTP. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *