Suppose you have a very simple page that permits you to search customers in northwind database and visualize orders, a classic master-detail page.
Figure 1: A classic Master-Detail page
Now suppose that you need to create a VS web test to search for each letter of the alphabet, and for each result page you should visit order details. Thanks to VS 2010 we have another construct for Web test called Loop, but there is no out-of-the-box loop condition to iterate with all the letters of the alphabet, so I need to build a custom one. To create a plugin for loop test you need simply to inherit from the ConditionalRule class and write a little bit of code:
1: public class CharLoop : ConditionalRule
2: {
3: // Fields
4: private ForLoopComparisonOperator _comparisonOperator;
5: private string _contextParameterName;
6: private Int32 _incrementValue;
7: private Char _initialValue;
8: private Char _terminatingValue;
9:
10: // Methods
11: public override void CheckCondition(object sender, ConditionalEventArgs e)
12: {
13:
14: Char num = Convert.ToChar(e.WebTest.Context[this._contextParameterName]);
15: num = (Char)(num + _incrementValue);
16: e.WebTest.Context[this._contextParameterName] = num;
17: switch (this._comparisonOperator)
18: {
19: case ForLoopComparisonOperator.LessThan:
20: e.IsMet = num < this._terminatingValue;
21: return;
22:
23: case ForLoopComparisonOperator.LessThanOrEqual:
24: e.IsMet = num <= this._terminatingValue;
25: return;
26:
27: case ForLoopComparisonOperator.GreaterThan:
28: e.IsMet = num > this._terminatingValue;
29: return;
30:
31: case ForLoopComparisonOperator.GreaterThanOrEqual:
32: e.IsMet = num >= this._terminatingValue;
33: return;
34: }
35: e.IsMet = false;
36: }
37:
38: public override void Initialize(object sender, ConditionalEventArgs e)
39: {
40: if (e.WebTest.Context.ContainsKey(this._contextParameterName))
41: {
42: e.WebTest.Context[this._contextParameterName] = this._initialValue - this._incrementValue;
43: }
44: else
45: {
46: e.WebTest.Context.Add(this._contextParameterName, this._initialValue - this._incrementValue);
47: }
48: }
49:
50: public override string StringRepresentation()
51: {
52: return string.Format(CultureInfo.CurrentCulture,
53: "Initialvalue{0} increment {1} context {2} terminating {3}",
54: new object[] {
55: this._initialValue,
56: this._incrementValue,
57: this._contextParameterName, str,
58: this._terminatingValue });
59: }
60:
61: // Properties
62: [Description("Operator to compare to compare the value with the actual one"),
63: DisplayName("Comparison operator"), DefaultValue(0)]
64: public ForLoopComparisonOperator ComparisonOperator
65: {
66: get
67: {
68: return this._comparisonOperator;
69: }
70: set
71: {
72: this._comparisonOperator = value;
73: }
74: }
75:
76: [Description("Name of context parameter where the current value should be set"),
77: DisplayName("Context parameter"), IsContextParameterName(true)]
78: public string ContextParameterName
79: {
80: get
81: {
82: return this._contextParameterName;
83: }
84: set
85: {
86: this._contextParameterName = value;
87: }
88: }
89:
90: [Description("Value to increment, it should be an integer"),
91: DisplayName("Increment Value")]
92: public Int32 IncrementValue
93: {
94: get
95: {
96: return this._incrementValue;
97: }
98: set
99: {
100: this._incrementValue = value;
101: }
102: }
103:
104: [DisplayName("Initial value"), Description("Initial Value")]
105: public Char InitialValue
106: {
107: get
108: {
109: return this._initialValue;
110: }
111: set
112: {
113: this._initialValue = value;
114: }
115: }
116:
117: [DisplayName("terminating value"), Description("terminating value")]
118: public Char TerminatingValue
119: {
120: get
121: {
122: return this._terminatingValue;
123: }
124: set
125: {
126: this._terminatingValue = value;
127: }
128: }
129: }
This class is based on the classic for Loop with integer values, and it iterate simply from a starting char to an ending char. Now if you reference the project that contains this class into a test project, you can use this loop in your test.
Figure 2: adding a custom rule for a loop in web test.
With this sample I want to iterate from the letter ‘a’ to letter ‘z’ incrementing each time by 2 chars, so I’ll have the sequence a,c,e,g,i…. Then I need to specify the Context parameter property, the property that will store the value of the sequence during each iteration, in Figure 3 you will see all the properties specified for our loop.
Figure 3: full configuration for the Loop iteration.
Now you can use that ContextParameter into a POST Variable
Figure 4: Use the variable in loop to pass parameter with post.
If you run the test you can verify that it iterates in your sequence doing a series of requests, each one for each value of the loop.
Figure 5: During test execution, for each iteration a different request was issued.
Thanks to this new feature of Visual Studio 2010 web test and very few lines of code, we are able to create, with little effort, an interesting test that can be used in load testing to simulate a series of search. In a subsequent post I’ll explain how to add another custom loop to select the detail page of each customer that satisfies the filter.
alk.
Tags: Visual Studio
