One Method To Rule Them All: Execution Behavior Manager

Most user actions in an application can be executed in different ways. As I mentioned earlier, creating a new document can be done via the following methods:

  • Clicking the File menu, clicking the New submenu, then clicking the New Document menu item
  • Clicking the New Document toolbar button
  • Typing Ctl+N

The test code infrastructure required for each of these execution variants are typically identical. The entire test case for each variant, in fact, is often identical except for the details of how the actions are implemented. Anyone who has written such cookie cutter test cases has surely wished for a better way.

We developed Execution Behaviors to eliminate this duplicated effort by pushing the variability in execution method from individual test cases into our LFM. An Execution Behavior is nothing more than one possible implementation of a given LFM method. We have two types: Composite Execution Behaviors that know they are implemented via one or more specific implementations, and child Execution Behaviors that represent a particular way of implementing an action that is semantically equivalent to every other child Execution Behavior for its “parent” Composite Execution Behavior.

The power this technique presents should be clear. Because the selection is taken out of the hands of the test case, we can write a single test case and run it a number of times (getting a different execution method each time) rather than write separate test cases for each execution method. Perhaps more importantly, any test case that calls a Composite Execution Behavior may end up using any of that Composite Execution Behavior’s child Execution Behaviors. Thus the test case exercises parts of the application it likely would not otherwise hit and is executed in a variety of contexts, all without doing anything special!

Execution Behaviors can be composed into other Execution Behaviors, so invoking a Composite Execution Behavior may cause a variety of other Execution Behaviors to be invoked as execution travels down through its tree of children. Child Execution Behaviors can also be accessed directly allowing test cases to invoke specific execution methods directly.
The Execution Behavior selection process can be customized in a variety of ways. First, the amount of time during which the Execution Behavior Manager will “remember” the choices it has made and use that knowledge when making further choices can be scaled from the execution of a single test case on the low end to include every test case run in the entire product cycle on the high end. Second, the Execution Behavior Manager can be configured to use any child Execution Behavior selection strategy you like. Third, the default selection process can be biased along several axes:

  • Globally in relation to any property with which child Execution Behaviors are labeled. For example, if the menuing system has just been completely rewritten, we could instruct the Execution Behavior Manager to choose child Execution Behaviors that use the menus most of the time but still select ones that use shortcut key sequences occasionally.
  • Locally to the test case in relation to any of these same properties. A test case may want to ensure that the mouse is used for all of its actions, for example.
  • Locally to the child Execution Behavior. A child Execution Behavior can disable itself if the application is in a state in which it cannot execute.
Comments (8)
  1. Alf says:

    This is a great idea! How do you control which cases get executed? I’m assuming there’s a common Execution Behaviour object that is inherited from… does it have a concept of "I use menus" or "I use the keyboard" or something?

  2. In our particular implementation, each Composite Execution Behavior is marked by an attribute that identifies its child Execution Behaviors. When a Composite Execution Behavior is called, it asks the Execution Behavior Manager to select one of its children and then executes the selected child. No common ancestor required — both Composites and children are just normal LFM methods.

    Execution Behavior Manager is completely responsible for deciding which children get executed for any particular Composite Execution Behavior. The biasing I mentioned in my post is accomplished via attributes on each child Execution Behavior that indicate data about the child such as "I use the mouse" or "I use the menus". Execution Behavior Manager combines this information with the local and global weighting factors when it decides which child to choose.

  3. Once you create your Logical Functional Model the other pieces can follow in any order immediately as…

  4. My next step in implementing an automation stack is to begin thinking about what execution behaviors each of my aforementioned user functions could possibly have. For the switchboard web application I believe I am going to choose behaviors that are more g

  5. I think my team – much of Microsoft, in fact – is going about testing all wrong.

    My team has a mandate…

  6. In many of my posts I have alluded to the automation stack my team is building, but I have not provided…

  7. Last week, I was testing a new way of using an existing feature. There was already an existing way…

  8. First up today was Linda Hayes talking about Cost Effective Test Automation Strategies. She grabbed…

Comments are closed.

Skip to main content