Reputation: 1364
I have written a Test Automation Framework. The framework is build around objects and actions. An object might be a text box. The actions for it might be things like set-text, clear, verify-text, verify-enabled, etc. The framework is independent of the acitons, so we can add more actions over time without having to respin the framework itself. I considered two approaches for the actions. The first was to use the command pattern. In this case I would have an interface that looks something like this:
public interface IAction
{
void Execute(StringDictionary properties);
}
The issue is that we would end up with many of these command classes.
public class SetTextAction : IAction
{
public void Execute(StringDictionary properties)
{
}
}
public class ClearAction : IAction
{
public void Execute(StringDictionary properties)
{
}
}
public class VerifyTextAction : IAction
{
public void Execute(StringDictionary properties)
{
}
}
public class VerifyEnabledAction : IAction
{
public void Execute(StringDictionary properties)
{
}
}
Furthermore any shared code will need to be in yet another class. It seems to increase the noise to signal ratio in the code.
The alternative I have come up with is to use a utility class for the type and methods for the actions. This ends up looking like this:
public class TextboxActions
{
public static void set-text(StringDictionary properties)
{
}
public static void clear(StringDictionary properties)
{
}
public static void verify-text(StringDictionary properties)
{
}
public static void verify-enabled(StringDictionary properties)
{
}
}
This has the advantage that the code for textboxes is all together. In addition, any code that is common to multiple actions can be in the same class. Unfortunately, this approach requires that I use reflection to "find" the action method. This is obviously not type safe and can be time consuming. It is slow enough that I have added a cache so I do not have to find the same action twice, but this adds to the code complexity.
Either of these solutions works, but they both have undesirable characteristics. Is there an alternative approach to this problem that someone can suggest?
Upvotes: 2
Views: 2684
Reputation: 1
The delegate approach would be something along the lines of this?
public abstract class TestObject
{
public delegate void TestAction(StringDictionary properties);
public void AddTestAction(TestAction action)
{
}
public void Execute()
{
// foreach test action etc.
}
}
public class TestTextBox : TestObject
{
TestTextBox()
{
Initialize();
}
private void Initialize()
{
AddTestAction(new TestObject.TestAction(this.SetText));
AddTestAction(new TestObject.TestAction(this.Clear));
}
public void SetText(StringDictionary properties)
{
}
public void Clear(StringDictionary properties)
{
}
}
Upvotes: 0
Reputation: 30165
Why can't you use delegates? That is, follow a first-class function approach. If you were thinking of making individual IAction concrete instances, you might as well just have a concrete function pointers instead. That way your code can continue to look like your last example, but not use reflection.
Upvotes: 1