Visual Studio 2005 web tests could be effectively used to test the web services too. However there are some key points which one should keep in mind for writing those web service tests. Let us go through them and see what they are:
1. To begin:
We should have a web test project at hand. Right-click on the test, and select “Add Web Service Request” from the context menu.
The URL property of the newly added web service request should point to the asmx file of the web service which you wish to test.
e.g. http://www.w3shools.com/webservices/tempconvert.asmx
2. SOAPAction Header:
The SOAPAction header must be added to the web service request. This is a hint to the servers that the HTTP POST contains SOAP request and the value of the header is the URI indicating the intent of the SOAP request.
e.g. SOAPAction = http://tempuri.org/CelsiusToFahrenheit
This could be selecting “Add Header” from the context menu of the web service request. Then set the “Name” property as “SOAPAction” and the value as URI of the web service function to be invoked.
3. String Body:
This is the actual body of the SOAP request and is basically a SOAP envelop which looks something like:
<?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>
<CelsiusToFahrenheit xmlns="http://tempuri.org/">
<Celsius>value to be sent</Celsius>
</CelsiusToFahrenheit>
</soap:Body>
</soap:Envelope>
The Content type of the String body should be kept as: text/xml.
NOTE:
a.) Ease of changing the value.
b.) Data driving the whole web service test.
The name of the context parameter should be used inside double braces.
e.g. {{param-name}}
4. Validation Rules:
The pre-canned validation rules provided with the web tests are not good enough for validating the web service tests, as they are designed to work with the HTML documents whereas the web services (SOAP) responses are XML documents. So we have to write our custom validation rules for the web services validation.
Following are the steps to write a custom validation rule:
public class CustomValidateTag : ValidationRule
{
public override string RuleName
get { return "Validate TagContent"; }
}
public override string RuleDescription
get { return "Validates whether tag in question contains the intended value"; }
private string TagNameValue;
public string TagName
get { return TagNameValue; }
set { TagNameValue = value; }
private string IntendedTagValue;
public string IntendedValue
get { return IntendedTagValue; }
set { IntendedTagValue = value; }
public override void Validate(object sender, ValidationEventArgs e)
e.IsValid = false;
XmlNodeList nodes = e.Response.XmlDocument.GetElementsByTagName(TagName);
if (nodes.Count > 0)
e.IsValid = true;
foreach (XmlNode node in nodes)
if (!string.Equals(node.Value, IntendedValue,
StringComparison.InvariantCultureIgnoreCase))
break;
// If the validation fails, set the error text that the user sees
if (!e.IsValid)
e.Message = String.Format("{0} Tag does not contain {1}",TagName,IntendedValue);
public class FaultCodeValidaionRule : ValidationRule
get { return "Fault Code Validation"; }
get { return "Validates if SOAP response contains some fault code"; }
bool validated = true;
XmlNodeList faults = e.Response.XmlDocument.GetElementsByTagName("soap:Fault");
if (faults.Count > 0)
validated = false;
foreach (XmlNode node in faults)
e.Message = String.Format("SOAP Error: ");
foreach (XmlNode child in node.ChildNodes)
e.Message += String.Format("{0}= {1}, ", child.Name, child.InnerText);
e.IsValid = validated;
5. Extraction Rules:
On the parallel line we shall create custom extraction rules for the web service tests. That would require extending ExtractionRule base class, providing the RuleName, RuleDescription read-only public properties, and overriding the Extract method.
Here is an example extraction rule which evaluates the given XPath query against the SOAP response.
public class EvaluateXPathQuery : ExtractionRule
get { return "Evaluate XPath Query"; }
get { return "Evaluates the given XPath Query"; }
private string XPathQueryValue;
public string XPathQuery
get { return XPathQueryValue; }
set { XPathQueryValue = value; }
public override void Extract(object sender, ExtractionEventArgs e)
XmlNamespaceManager nsManager
= new XmlNamespaceManager(e.Response.XmlDocument.NameTable);
nsManager.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
XPathNavigator navigator = e.Response.XmlDocument.CreateNavigator();
XmlNode body = e.Response.XmlDocument.SelectSingleNode("//soap:Body", nsManager);
// Very first child of soap response envelope's body tag is the response tag.
string responseNameSpace = body.FirstChild.Attributes["xmlns"].Value;
if (responseNameSpace != null && responseNameSpace.Length > 0)
nsManager.AddNamespace("response", responseNameSpace);
// Now prefix temp namespace for every node in the query.
int index = 0;
while ((index = XPathQuery.IndexOf('/', index)) != -1)
if (XPathQuery[index + 1] == '/')
index++;
if (!XPathQuery.Substring(index + 1, 4).Equals("soap",
XPathQuery = XPathQuery.Insert(index + 1, "response:");
++index;
XPathNodeIterator iterator
= navigator.Evaluate(XPathQuery, nsManager) as XPathNodeIterator;
if (iterator.Count > 0)
string val = string.Empty;
while (iterator.MoveNext())
val += String.Format("{0}: {1}", iterator.Current.Name,
iterator.Current.Value);
e.Success = true;
e.WebTest.Context.Add(this.ContextParameterName, val);
else
e.Success = false;
e.Message = String.Format(CultureInfo.CurrentCulture,
"No result for query: {0}", XPathQuery);
return;
6. IMPORTANT:
XPath expressions do not have the concept of a default namespace. Omitting the prefix from an XPath looks for nodes in the empty namespace, and finds nothing. So we must use an arbitrary prefix for xml namespace in the SOAP response envelope. This namespace is attribute of the Response tag, which is the first child of the soap:Body tag.
7. XPath Query Tools:
http://www.stylusstudio.com/xpath_editor.html
http://www.freewarefiles.com/program_4_50_14082.html
http://www.topxml.com/xselerator/