Overview
Software Testing is becoming an increasing important area of software develoment lifecycle, and rightfully so. Approaches such as TDD (Test-Driven Development) are quickly becoming the standard way of developing software, and system-, regression and load testing are now applied throughout the development process, and not just at the end of development cycle, when critical architecture and design flaws and performance bottlenecks are more expensive to correct.
Visual Studio Team Edition for Software Testers, introduces a brand new set of powerful tools for Web and load testing. Team Suite is a tremendous improvement as compared to the old ACT product that shipped with the previous versions of Visual Studio. The web testing tools are fully integrated into Team Suite, and tie in nicely with Team Foundation Server and the team's overall software development lifecycle.
The Web testing tools allows us to test an application in the same way that a user would actually use our application. The tools accomplish this by filling in the fields on a web page, submitting the page, following navigation links and so on. Note that at this time, Team Editor for Software Testers does not yet support Windows Forms applications.
What is less known in the development community is that you can leverage the Web Testing tools in Team Suite as a Web Service testing tool. This post will cover this subject. It will illustrate the following topics:
- Creating a Web Test Project
- Creating a new empty Web Test
- Add a Web Service request to Web Test, and specifying the SOAP header and the SOAP body for the Web request.
- Modifying a test to be data-driven.
- Creating a custom extraction rule to extract information from the SOAP response.
- Creating a custom validation rule to validate the result returned from the Web Service request.
- Writing a custom WebTest Plug In to modify the SOAP request before it is submitted to the Web Service.
As testing target, we will use the Email Validation Web Service, which was created in the context of my previous SqlClr post. This web service has a very simple API, which consists out of one method which enables us to validate an email address. The implementation of the Web Service uses a regular expression to validate the passed-in email address.
Note that is order to re-create the topics covered in this post, you should have access to either Visual Studio Team Edition for Software Testers, or Visual Studio Team Suite.
Creating a new Web Test Project
Follow these steps to create the Web Test Project:
- Create a new empty solution, called "Team Suite Web Service Testing".
- Add a new testing project to the solution by right-clicking the solution and selecting Add | Add New Project. In the dialog, open the Visual C# tree node, and click on the Test node. In the right pane, select Test Project, and enter the name of the project, as is shown in the figure below:

After you click OK, a number of files will be added to your solution and project.:
The following files are added to your solution:
- A localtestrun.testrunconfig file. This file will contain our test run configuration.
- Team Suite Web Service Testing.vsmdi. This file contains our project's meta-data information.
The following files are added to your project:
- AuthoringTests.txt. This text file explains how to create the various types of tests, how to use the Test View etc. The contents of this file should be the first resource you turn to when you have any questions regarding test authoring, and working with the test project.
- ManualTest1.mht. This is a manual test template. Double clicking this file will start up Word with the "Manual Test Template". Manual tests are tests that the tester performs without any support of Team Suite. Typically, manual tests are used when the test steps are too difficult or time-consuming to automate, or when the tests really cannot be automated.
- UnitTest1.cs. This is a skeleton unit test. We will not address unit testing in this post.
- MyProject/AssemblyInfo.cs: This is our standard assemblyInfo file.
The files in the solution and project are shown below:

Creating a new empty Web Test
Now, we are ready to add a web test to the project. In this case, we want a completely empty web test to start out with. To create this test, follow these steps:
- Right click the project, and select Add | Web Test. An instance of IE will come up, containing the Web Test Recorder, as is shown below

- We don't want to record anything, so immediately push the Stop button.
- A new test with name WebTest1.webtest will be added to your project.
- Rename this file to the more meaningfull TestEmailValidationWebService.webtest.
Add a Web Service Request
We now have a blank test that we can use to create our Web Service Test. The recommended way to author these tests is to use the built-in test pages that ASP.NET creates for you when you test a web service. Therefore, you should open the corresponding Web Service Project, set the .asmx file that you want to test as the startup page, and start debugging. This will bring up the test page, as is shown below:

This page contains all information that is required to create out test.
To create the Web Service, switch back to the test project, and right-click the TestEmailValidationService node, which is so far the only node in our test. In the context menu, select Add Web Service Request. This will add a new node to our test, with a default URL of http://localhost. Instead of this default, enter the URL of the web service in the URL property of the node's property sheet. In our case here, that URL is http://localhost/EmailValidation/EmailValidation.asmx.
When you look at the property sheet for the node you will notice that the only transport method available at this time is an HTTP POST call. The body of the request can either be an HTTP request or a SOAP request. We will of course use the standard SOAP request. The benefit of using SOAP is that it allows us to leverage standard XML tools and .NET API's for the creation and manipulation of both the Web request and the Web response.
Next, we need to add a SOAPAction header to our request, with as value the full endpoint of the method that we would like to call. To do this, follow these steps:
- Right click the .asmx node in our test, and select Add Header. This will add a header node under our .asmx web service request node.
- In the property sheet of the header, select SOAPAction as the name of the header.
- Switch back to the Web Service test page, and copy the value of the SOAPAction header (in this case http://asiqs.com/WebServices/EmailValidation/ValidateEmail), and paste it in the value of the header.
Next, we need to set the SOAP Body of our Web Service request. Click on the String Body node, and in the property sheet, select text/xml as the Context Type of the body. Next, switch to the test page, and copy the entire SOAP 1.1 request from the browser, and paste it into the String Body property of our Test's Web Request, as is shown in the figure below:

In the above screen, replace the 'string' placeholder with a valid email address.
Now, we are ready to run the test, right click the top node of our test, and select Run Web Test. The results will look as follows:

The upper pane shows the Web Request, and the bottom pane shows the received response, which in this case contains a ValidateEmailResult of true, since we entered a valid email in our SOAP body. You can use the tabs in the lower pane to look at the request, the response and the Web test context (more on that later in this post).
Modifying the test to be Data-Driven
In a real-world environment, we don't want to create a large number of tests by hand. The above example is rather simple, but in real-life scenarios, you are likely to have a large number of tests, with multiple parameters which have a variety of data types.
Team Suite supports data binding for web tests. Data binding allows a data source to provide the parameters to the web tests, so for example, we can use a data source to provide us with a large number of sample email addresses to validate. Data binding can be used for individual data-driven web tests or for load testing (look for some coverage of load testing in future posts). For data-driven web tests the test will cycle through a table in the database and run the test once for every row in the table. Alternatively, you can also instruct Team System to randomly select different records from your database to run the tests.
In our case, we will use a SQL Server database table to supply the data. The database is called EmailValidationTestDB, and the table is called EmailAddressTestData. The structure of the table is shown below:

We first column contains the email address, the second column indicates whether or not the email address is valid. We will use the last two fields (ValidTestResult and LastUpdated) later on in this post.
Now that we have our data table, we need to connect it to our Web Test. Right click the root node of the test, and select Add Data Source. Use the SQL Server native provider, and fill in the server name and the database name to use. After you add the data source, you have the ability to select which tables should be connected to your test. In this case, we only have one table, which is EmailTestData. At this point, we should also go ahead an enter one row of test data into our table, so we have some data to test against.
The individual paramters of the Web Service Requests can be hooked up to specific columns in the data source. To specify a data-bound field, use the following syntax:
{{datasourceName.table.field}}
In this case, our data source name is EmailValidationTestDB1. Edit the string body of the test, and change the hard-coded email address to the syntax above. Our SOAP body will look as follows after this:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ValidateEmail xmlns="http://asiqs.com/WebServices/EmailValidation">
<email>{{EmailValidationTestDB1.EmailAddressTestData.EmailAddress}}</email>
</ValidateEmail>
</soap:Body>
</soap:Envelope>
At this point, run the test again. When you look at the request that is sent out, you will notice that Team System indeed used your test data for the test. By default, it will only use one row (the first row), but if you want to run one test for every row in the database, perform these steps:
- In Team Suite's main menu, select Test | Edit Test Run Configuration | Localtestrun.testrunconfig.
- In the dialog, select Web Test.
- In the number of run iterations panel, select One run per data source row.

Now, enter some more data in the data table, and run the test again. You will notice that mutliple tests are run, once for each row in the table:

Validation and Extraction Rules
Our testing framework is now more robust and we can easily test a large batch of addresses, but so far, we have not really verified that the results that we received are correct. Remember that our test data table already contains a 'Email Valid' column which indicates whether or not the test email address is valid. In this section, we will extract the received result (true of false) from the SOAP response, and we will compare it with the data in our database table. If both are NOT the same, we will go ahead and fail the test.
To implement scenarios like the one above, Team Suite supports concepts called "Extraction Rules" and "Validation Rules":
- An Extraction Rule can extract values from a test result
- A Validation Rule can apply logic to the received results, and can fail or pass a test accordingly.
Out of the box, Team System provides a number of extraction rules that can extract form post parameters, HTML elements etc, but nothing is provided to extract values from a SOAP response. Luckily, Team System is designed as an extensible platform, and allows us to create custom extraction rules in our preferred .NET language (which is of course C# ;-).
So, as a first step, we will create a custom extraction rule to extract a value from a SOAP result with an XPath expression, and then we will use a validation rule to compare the boolean result in the data table to the result from the Web Service.
Creating a Custom Extraction Rule
The requirements for our custom extraction rule are as follows:
- The rule needs to be able to interpret a SOAP response.
- The user should be able to use a standard XPath expression to specify what should be extracted from the SOAP response.
The above requirements result in an extraction rule, which can be applied to any Web Service test project, and not just to the limited scope of this example.
To create this rule, follow the steps outlined below:
- Add a new C# class library called CustomExtractionRules to the solution.
- Add a reference to the Microsoft.VisualStudio.QualityTools.WebTestFramework.dll assembly. For a standard Visual Studio installation, this assembly is located in the C:\Program Files\Microsoft Visual Studio 8\Common 7\IDE\Public Assemblies folder.
- Change the generated class (Class1) to XPathExtractionRule.cs (make sure to rename the code file as well).
- Add the following using statements to the top of the class file:
using System;
using System.Xml;
using System.Xml.XPath;
using System.Globalization;
using System.ComponentModel;
using Microsoft.VisualStudio.TestTools.WebTesting;
using Microsoft.VisualStudio.TestTools.WebTesting.Rules;
Change the class to inherit from the ExtractionRule class. This class is the common base class for all extraction rules. This class provides the following virtual methods and properties:
- public string RuleName: We can override this property to provide a suitable name for our rule. The user will see the string we return from this method in the Extraction Rule dialog.
- public void Extract(object sender, ExtractionEventArgs e): This is extraction method itself.
- We will also need to provide a public property (backed by a private field), which allows the user to define the XPath Expression to be evaulated. Team System will automatically show each public property in the Extraction Rule dialog. We will call this property XPathExpression.
The skeleton of our class now looks as follows:
using System;
using System.Xml;
using System.Xml.XPath;
using System.ComponentModel;
using Microsoft.VisualStudio.TestTools.WebTesting;
using Microsoft.VisualStudio.TestTools.WebTesting.Rules;
namespace CustomExtractionRules
{
public class XPathExtractionRule : ExtractionRule
{
private string xPathExpression;
/// <summary>
/// This is our XPath Expression
/// </summary>
[Description("XPath Expression to evaluate against the response")]
public string XPathExpression
{
get { return xPathExpression; }
set { xPathExpression = value; }
}
/// <summary>
/// This is our Extraction method
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public override void Extract(object sender, ExtractionEventArgs e)
{
} // method Extract
/// <summary>
/// This method returns the Name of our Rule.
/// </summary>
public override string RuleName
{
get { return "XPath Extraction Rule"; }
}
}
}
Next, we need to implement the body of the Extract method. Let's look at a typical SOAP response first:
1 <?xml version="1.0" encoding="utf-8"?>
2 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
5 <soap:Body>
6 <ValidateEmailResponse xmlns="http://asiqs.com/WebServices/EmailValidation">
7 <ValidateEmailResult>
8 false
9 </ValidateEmailResult>
10 </ValidateEmailResponse>
11 </soap:Body>
12 </soap:Envelope>
The soap Envelope and body have a standard "soap" prefix, but as you can see, the payload inside the soap Body has its own namespace, but this namespace has no prefix. Because this is a bit inconvienent, our code will make up the prefix "response". This implies that when we write our XPath expression later, we will have to use the response prefix accordingly.
The full code for our method is shown below:
1 /// <summary>
2 /// This is our Extraction method
3 /// </summary>
4 /// <param name="sender"></param>
5 /// <param name="e"></param>
6 public override void Extract(object sender, ExtractionEventArgs e)
7 {
8 XmlDocument doc = e.Response.XmlDocument;
9
10 // Create a new namespace manager with the response's name table
11 XmlNamespaceManager nsMgr =
12 new XmlNamespaceManager(doc.NameTable);
13 nsMgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
14
15 // Create a XPath navigator over the document, and select the body
16 // node
17 XPathNavigator nav = doc.CreateNavigator();
18 XmlNode responseBody = doc.SelectSingleNode("//soap:Body", nsMgr);
19
20 // Get the response namespace, and add it to our namespace
21 // manager with the prefix "response"
22 string responseNS =
23 responseBody.FirstChild.Attributes["xmlns"].Value;
24 if (responseNS != null && responseNS.Length > 0)
25 {
26 nsMgr.AddNamespace("response", responseNS);
27 }
28
29 // Now, we can evaluate our XPath expression
30 XPathNodeIterator iterator =
31 nav.Evaluate(xPathExpression, nsMgr) as XPathNodeIterator;
32 if (iterator.Count > 0)
33 {
34 //
35 // Collect the complete value of the iterator
36 //
37 string value = string.Empty;
38 while (iterator.MoveNext())
39 {
40 value += iterator.Current.Value;
41 }
42
43 // Indicate success, and set the Context Parameter
44 // selected by the user to the value of the XPath
45 // expression
46 e.Success = true;
47 e.WebTest.Context.Add(this.ContextParameterName, value);
48 }
49 else
50 {
51 // Indicate failure, and populate a message with some
52 // explanation of the failure
53 e.Success = false;
54 e.Message = string.Format(
55 CultureInfo.CurrentCulture,
56 "No result for query: {0}",
57 xPathExpression);
58 }
59
60 } // method Extract
61
A couple of remarks regarding the code are listed below:
- Line 8: The second argument (ExtractionEventArgs) contains the response. We can simply use it's XmlDocument property to access the Xml document of the response
- Lines 10-13: Here, we create a namespace manager with the document's name table, and we add the standard soap namespace with the "soap" prefix.
- Lines 17-18: Here, we create an XmlNavigator over the Xml document, and get the SOAP Body.
- Lines 22-27: Here, we get the first child of the body, and get it's namespace, and add that namespace with the made up "response" prefix to our namespace manager.
- Lines 30-32: Here, we evaluate the XPath Expression specified by the user, and save the result in a node iterator.
- Lines 37-47: We get the value of the XPath Expression, and set the success status, and add a Context Parameter to the WebTest. The name of this context parameter is specified by the user in the Add Extraction Rule dialog, and is available to our method through the ContextParameterName property.
- Lines 50-58: If our XPath expression fails, we set our Success field to false, and set a status message. This status message will be shown in our test result when the extraction fails.
Using our Custom Extraction Rule in our Test
Now that we have finished the code for our rule, we are ready to start using it in our test as follows:
- First, we need to set a project reference to our CustomExtractionRules assembly in our test project.
- Next, we right-click our test, and select Add Extraction Rule. In the Add Extraction Rule dialog box, we select XPath Extraction Rule. As Context Parameter name, we enter ValidationResult, and as XPath Expression, we enter: //response:ValidateEmailResult/text(), as shown below:

Now, when we run our test, our extraction rule will run. we can check that our Context Parameter gets populated correctly, by going to the Context tab in the lower pane:

As you can see, we have create a new context parameter named "ValidationResult", and its value is set correctly by the extraction rule.
Adding the Validation Rule
As part of our testing process, we want to make sure that the validation result that is returned from the Web Service is correct. Our test database table EmailAddressTestData contains a column named EmailValid, which indicates whether or the email in the column EmailAddress is valid. We want to compare the EmailValid column with the result that is returned from our Web Service.
Team Suite offers validation rules for this purpose. Out of the box, Team Suite offers the following validation rules:
- Form Field. This rule verifies the existence of a form field with a specified name and value. Forms field validation rules are only applicable to "classic" web test.
- Find Text. This rule verifies the existence of a specified string in the response. The "Find Text" rule can be applied to both "classic" Web tests and Web Service tests.
- Maximum Request Time. This validation rule verifies that the request finishes within the specified amount of time.
- Required Attribute value. This rule verifies the existence of a specified HTML or XML tag that contains an attribute with a specified value.
- Required Tag. This rule verifies the existence of a specified HTML or XML tag in the response.
The last three rules can be applied to any type of test. While the above validation rules are very applicable to a wide range of validation issues, none of them can be readily applied to our problem. In our case we want to compare the following:
- A column value from our data source -to-
- A context parameter (in this case, the ValidationResult context parameter extracted from the SOAP respone with our custom extraction rule).
Again, the rich extensibility features built into Team System come to the rescue. Just like we can write custom extraction rules, we also have the ability to write custom validation rules. Creating a custom validation rule is almost identical to creating a custom extraction rule.
The class library to house our custom validation rule will be called CustomValidationRules. The class that implements the rule itself will be CompareContextParameterToDataField.cs. To create the custom validation rule, follow the steps outlined below:
- Create a new C# class library called CustomValidationRules to the solution.
- Add a reference to the Microsoft.VisualStudio.QualityTools.WebTestFramework.dll assembly. For a standard Visual Studio installation, this assembly is located in the C:\Program Files\Microsoft Visual Studio 8\Common 7\IDE\Public Assemblies folder.
- Change the generated class (Class1) to CompareContextParameterToDataField.cs (make sure to rename the code file as well).
- Add the following using statements to the top of the class file:
using System;
using System.ComponentModel;
using System.Globalization;
using Microsoft.VisualStudio.TestTools.WebTesting;
using Microsoft.VisualStudio.TestTools.WebTesting.Rules;
Change the class to inherit from the ValidationRule base class. This class is the common base class for all validation rules. This class provides the following virtual methods and properties:
- public string RuleName: We can override this property to provide a suitable name for our rule. The user will see the string we return from this method in the Add Validation Rule dialog.
- public override void Validate(object sender, ValidationEventArgs e). This is validation method itself.
We will also need two public properties, backed by two properties to represent:
- The name of the Context Parameter to compare.
- The data field value to compare against the context parameter.
The public properties are ContextVariableName and DataFieldValue respectively.
The skeleton of our class now looks as follows:
/// <summary>
/// Custom validation rule, which compares a context
/// parameter field to
/// </summary>
public class CompareContextParameterToDataField : ValidationRule
{
private string contextVariableName;
private string dataFieldValue;
[Description("Context Variable Name to compare")]
public string ContextVariableName
{
get { return contextVariableName; }
set { contextVariableName = value; }
}
[Description("Data Field Value to compare")]
public string DataFieldValue
{
get { return dataFieldValue; }
set { dataFieldValue = value; }
}
public override string RuleName
{
get { return "Comparion of Context Param to Data Field"; }
}
public override void Validate(object sender, ValidationEventArgs e)
{
}
}
The implementation of the Validate method is actually very straightforward, since we simply need to compare the Context Parameter to the data field value:
public override void Validate(object sender, ValidationEventArgs e)
{
if (((string)e.WebTest.Context[contextVariableName]).
Equals(dataFieldValue, StringComparison.InvariantCultureIgnoreCase))
{
e.IsValid = true;
}
else
{
e.IsValid = false;
e.Message = string.Format(
CultureInfo.CurrentCulture,
"The context variables {0} and {1} did not match!",
e.WebTest.Context[contextVariableName],
DataFieldValue);
}
}
Note that we set e.IsValid to true if the context parameter and the data field value match up. If they don't, we set e.IsValid to false, and add an explanatory message.
Using our Custom Validation Rule in our Test
Now that we have finished the code for our validation rule, we are ready to start using it in our test as follows:
- First, we need to set a project reference to our CustomValidationRules assembly in our test project.
- Before we add the validation rule to our test, there is one very important detail that we should be aware off: Within the same web request, the validation rule will ALWAYS run BEFORE the extraction rule. This of course, would completely mess up our elaborate scheme, since our validation rule depends on the Validation Result, which is created by the extraction rule. Luckily, the solution to this is very simple:
- We can just copy our Web request, and paste a new instance right below the first one.
- Now, what we will do is, we will run just the extraction rule in the first Web request, and the validation rule in the second Web request. Since context parameters are passed from one Web request in our test to the next, our validation rule will have the extracted value available. We do incur the overheader of two web requests instead of one, but for a test harness like this, that is not really a critical issue.
- Right click the (copied) second Web request, and select Add Validation Rule. In the Add Validation Rule dialog box, we select "Compare Context Parameter to Data Field" rule. As Context Parameter name, we enter ValidationResult, and as Data Field Value, we enter: {{EmailValidationTestDB1.EmailAddressTestData.EmailValid}}, as shown below:

When we now run our test, we will notice that our Validation Rule does indeed run, and that it will indeed correctly compare the extract Context Variable to the EmailValid data source field, as you can see if you look at the Details tab:

Writing the Test Result to the database with a custom Web Request Plugin
As a final excercise, we will take the result that was received from our Web Service to our EmailAddressTestData table. Remember, this table thas two columns that we have not used so far:
- The ValidTestResult column. In this column, we will write the Web Request result received from our Web Service.
- The LastUpdated column. This column will be updated with the timestampt of the Web Request.
The Team System Testers API provides two types of Test Plug-ins, which have been designed as "extension points" for the test developer:
- Web Test Plug-in. A Web Test Plug-in provides a means to run code and access a Web Test before and after the Web Test is run.
- Web Request Plug-in. A Web Request Plug-in provides a means to run code before and after a Web Request is processed.
To support our scenario, we will need a Web Request Plug In, since we want to be able to run code after each Web request is run. Implementing a Web Request Plug In is very simple. The Team System API provides an abstract base class called WebRequestPlugIn in the Microsoft.VisualStudio.QualityTools.WebTesting namespace.
Creating the Web Request PlugIn
The WebRequestPlugIn defines two abstract methods whic must be overriden by a sub-class:
- public override void PreRequest(object sender, PreRequestEventArgs e): This method is called right before the Web request is submitted.
- public override void PostRequest(object sender, PostRequestEventArgs e): This method is called after the Web Request response has been received back from the Web Service.
To create the PlugIn, follow the steps outlined below:
- Add a new C# class library called CustomWebRequestPlugIn to the solution.
- Add a reference to the Microsoft.VisualStudio.QualityTools.WebTestFramework.dll assembly. For a standard Visual Studio installation, this assembly is located in the C:\Program Files\Microsoft Visual Studio 8\Common 7\IDE\Public Assemblies folder.
- Change the generated class (Class1) to EmailAddressTableUpdate.cs (make sure to rename the code file as well).
- Add the following using statements to the top of the class file:
using System;
using System.Data;
using System.Data.SqlClient;
using Microsoft.VisualStudio.TestTools.WebTesting;
As before, the implementation of the PreRequest and PostRequest methods can access the context parameters, to write the received result to our database table, as is shown below:
/// <summary>
/// This method is executed after our web request has been completed.
/// Here, we update
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public override void PostRequest(object sender, PostRequestEventArgs e)
{
// Get our values from the Web Test Context
bool validationResult = bool.Parse(
(string)e.WebTest.Context["ValidationResult"]);
string emailAddress = (string)
e.WebTest.Context["EmailValidationTestDB1.EmailAddressTestData.EmailAddress"];
// Execute our SP to store the result
using (SqlConnection conn = new SqlConnection(
"Data Source=(local);Initial Catalog=EmailValidationTestDB;Integrated Security=SSPI"))
{
using (SqlCommand cmd = new SqlCommand("uspUpdateTestResult"))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Connection = conn;
cmd.Parameters.AddWithValue("@EmailAddress", emailAddress);
cmd.Parameters["@EmailAddress"].Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("@ValidTestResult", validationResult);
cmd.Parameters["@ValidTestResult"].Direction = ParameterDirection.Input;
conn.Open();
cmd.ExecuteNonQuery();
}
}
} // method PostRequest
this method leverages a stored procedure called uspUpdateTestResult, which is shown below:
CREATE PROCEDURE uspUpdateTestResult
(
@EmailAddress nvarchar(200),
@ValidTestResult bit
)
AS
BEGIN
SET NOCOUNT ON;
UPDATE dbo.EmailAddressTestData
SET ValidTestResult = @ValidTestResult,
LastUpdated = getdate()
Where EmailAddress = @EmailAddress
END
GO
Using the WebRequestPlug-in in our Web Test
Now that we have finished the code for our PlugIn, we are ready to start using it in our test as follows:
- First, we need to set a project reference to our CustomWebRequestPlugIn assembly in our test project.
- Next, we select the root node of our test, and in the property sheet of the test, we click on the browse button next to Request Plug-in, and select our Plug-in as shown below:

Now, when we re-run the tests, we can see that our database table gets updated correctly:

Summary
Web Service Testing with Visual Studio has come a long way. In this post, we looked at how we setup a Web Test to perform a Web Service request, how to add data binding, the creation of custom extraction and validation rules and finally the creation of a web request plug in. Any comments, questions and feedback is (as always) greatly appreciated.