Tasks and plans
A task is a grouping of actions that fail or succeed as a group. A plan is an ordered list of tasks that instructs Puffin how to execute the tasks. The best way to understand both is to see a brief example.
Listing 6 is a simple plan called simplePlan.txt:
Listing 6. Simple plan
|
But wait! These aren't tasks. These are just the actions we defined in the last section. In the simple plan format you simply list actions you wish Puffin to execute, and Puffin executes them one after another. It won't stop if one fails, but it will manage inputs/outputs as described in the last section. Simple format plans are useful for testing actions and for simple setups where very little is involved in running your plan.
Just for information, Puffin really does treat these individual elements as tasks, just tasks that involve the execution of only a single action apiece. You don't need to worry about that, though, as that happens in the background.
Now the action definitions plus this simple format
for plans is of some use in simple scenarios, but often you would like
to short-circuit the process if something fails. For example, it is
useless to have Puffin execute the getSalesByUser
action if the USER_ID
output is not successfully extracted from the results of the login
action.
This is where the advanced plan format comes into play. The advanced plan format allows you to wrap one or more actions into a task element that Puffin executes as a unit. All its actions must succeed for the wrapper task to succeed.
Listing 7 puts the setLoginInfo
and login
actions together into a task in an advanced plan:
|
You now have a login
task made up of the two actions setLoginInfo
and login
. For this task to succeed, both setLoginInfo
and login
will both have to succeed.
Now add a second task. This second task will be made up of only the getSalesByUser
action, but it will be dependent on the login
task above:
|
This second task demonstrates two things. The first is the
abbreviated format for tasks in an advanced plan that contain only a
single action. The second is the inclusion of the dependsList
attribute. This attribute instructs Puffin that the getSalesByUser
task should be executed only if the tasks (comma-separated) listed in the dependsList
attribute all succeed.
That's enough on tasks for now. Let's look at some other powerful features for advanced plans. The first is the repetition of tasks.
I should warn the XML seniors among you that the <repeat>
tag makes for UGLY xml. However, it allows for some incredibly powerful
execution scenarios. If you want to repeat a task, all that is required
is for you to insert that task inside a repeat tag like this:
|
You can wrap any task or group of tasks in a repeat tag. The repeat tag can have a name
attribute (optional), which is used in reporting, and a second
attribute that indicates when Puffin should stop repeating the contents
of this repeat tag. The example above uses a count
attribute to indicate to Puffin that it should execute the getSalesByUser
task twice.
The count will do what you need in most cases. There are also while
and until
repeat attributes that take the name of an action token as a value.
These work on whether the token evaluates to TRUE or FALSE as you'd
predict. For example, suppose you want to run a set of tasks that
affect every record in a table one at a time. At the end of these
tasks, one of the outputs updates an action token with the remaining
records. If that token evaluates to TRUE (there are more records), you
want it to repeat. If not, you want it to stop. In this case, you'd use
a while
attribute in the repeat tag.
There are other features of the repeat tag (including the ability to repeat a task or set of tasks until one fails, for example), and you can, of course, include a repeat inside other repeat tags. Needless to say, the use of repeat tags can make for some very complex and powerful Puffin plans.
As a last example of a plan file, take a look at this advanced plan (from the Puffin distribution) in Listing 10:
Listing 10. Complex plan
|
Spend some time looking into this plan when you start working seriously with Puffin. Until then, use the simple format.
Before
leaving plans, I want to introduce one last concept. Many Puffin users
have indicated that they want to be able to extend the framework in
Python and thus completely control how plans are executed. This allows
you even more flexible control over plans and task execution. Until I
can cover this topic in a future article, I will simply say that the
Puffin plan is a class called (not surprisingly) Plan
. This plan can be subclassed to make your very own custom
plan class, like this one shown in Listing 11 (special thanks to
Webware's Chuck Esterbrook for his suggestions on how this should work):
|
If you don't know (or care) about Python, you can safely skip to Results processing below (though I strongly encourage to try Python and come back!).
Listing 11 is a simple subclassing of the Puffin Plan
class, paf.core.plan.Plan
.
With this subclass, you have everything that the Puffin framework gives
you (tasks, task dependencies, etc). For example, even if you use executeTask
to execute the getSalesByUser
task, Puffin will handle dependencies (such as not executing
that task if the login task failed) and other complexities. However, in
this example, you can see how I've introduced my own spin on execution.
In this example, if my starsAligned()
method comes back false, then the task execution isn't attempted. Although a simple example, you can see how subclassing Plan
will allow you very powerful control over how Puffin handles your tasks.
To execute the custom plan, you must call the execute()
method, but override the executePlan()
method. The execute()
method (part of the Plan
base class) handles initialization of the various results-processing
mechanisms (described in the next section) and some other housecleaning
chores.
View Web application testing with Puffin: Part 2 Discussion
Page: 1 2 3 4 5 Next Page: Results processing