Creating a Data-Driven Web Test against a Web Service

Okay, I'm sure some of you will tell me, "Yeah, I know this already!", but I've been asked this several times.  So in addition to pointing you to the MSDN documentation, I thought I'd give my own example.

The more mainstream recommendation for testing a web service is to use a unit test.  Code up the unit test, add a reference to the service, call the web service, and assert the results.  You can then take the unit test and run it under load via a load test.

However, what if you want a more visual test?  Well, you can use a web test to record interaction with a web service.  This is actually documented in the MSDN Library here, but below is my simple example.

Here's what we're going to do:

  1. Create the web service
  2. Create the web test
  3. Execute the web test (to make sure it works)
  4. Create the test data data source
  5. Bind it to the web test
  6. Run the test again

First, we create a web service.  In my example, it's the sample "Hello, World" service and I've created one additional method called "HelloToPerson":

<WebMethod()> _ Public Function HelloToPerson(ByVal person As String) As String Return "Hello, " & person End Function

As you can see, the method will simply say hello to the passed person's name.

Now, let's create a web test to exercise this web method (Test->New Test, select Web Test), creating a test project in the process if you don't already have one in your solution.  I named my web test WebServiceTest.webtest.

As soon as Internet Explorer opens with the web test recorder in the left pane, click the "Stop" button in the recorder.  This will return you Visual Studio's web test editor with an empty test.

Web test with no requests

Now launch Internet Explorer, go to your web service (.asmx), and select the method to test (again, in this example it's "HelloToPerson").  Examine the SOAP 1.1 message.  In my example, the message looks like this:

POST /Service1.asmx HTTP/1.1 Host: localhost Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: https://tempuri.org/HelloToPerson <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <HelloToPerson xmlns="https://tempuri.org/"> <person>string</person> </HelloToPerson> </soap:Body> </soap:Envelope>

We'll need to refer back to this information (I color-coded a couple of sections for later reference).

Right-click on the root node (WebServiceTest in my example) and select "Add Web Service Request."

Add a Web service Request

In the URL property of the new request, enter the URL of the web service (by default this value is populated with https://localhost/.

Specifying the correct URL for the web service

Now, let's make sure we use a SOAP request.  Right-click the request and select "Add Header".

Adding a header to the request

Enter "SOAPAction" in the name field.  In the value field, enter the value of SOAPAction in the message from your web service.  For my example, it's "https://tempuri.org/HelloToPerson" (color-coded in blue)

Adding the SOAPAction header to the request

Next, select the String Body node

  • In the Content Type property, specify "text/xml"
  • In the String Body property, copy/paste the XML portion of the SOAP 1.1 message of your web service method (color-coded in red).  At this time, be sure to replace any parameters with actual values you want to test (in this example, my parameter is "person", so I enter "Steve" instead of "string"

Entering the XML portion of the SOAP message, specifying a real value for the 'person' parameter

The properties dialog for the String Body node

Now, right-click on the web service request and select "Add URL QueryString Parameter."

Adding a URL QueryString Parameter

In the QueryString Parameter node, specify "op" as the name and the name of your method as the value.  In this example, it's "HelloToPerson".

Viewing the added QueryString Parameter

Finally, let's run the test and see the results!

Viewing the test results

As you can see, the test passed, and the "Web Browser" panel shows the returned SOAP envelope with the correct results.

Now for some more fun.  Let's make this a data-driven test so we can pass different values to the web method.

We'll create a simple data source so that we can pass several names to this method (very helpful so we don't have to record multiple tests against the same method).  You can use a database, XML file, or CSV (text) file as a data source.  In my example, I'm going to use an XML file:

<?xml version="1.0" encoding="utf-8" ?> <TestData> <Name>Steve</Name> <Name>Mickey</Name> <Name>Devin</Name> <Name>Joe</Name> <Name>Eric</Name> </TestData>

Save this file as "Names.xml" in your test project. 

To make this data source available to the web test, right click on the web test and select "Add Data Source" (you can also click the corresponding toolbar button).

Adding a data source

Provide a name for the data source (for me, it's "Names_DataSource") and select XML file for the data source type.

Selecting the data source type

Next, provide the path to the XML file, then select the data table containing your test data.  You'll know if you select it correctly since you'll get a preview of your data.

Selecting the XML file

Check the boxes next to the data tables you want to be available for your tests.  In my example, I only have one ("Names").

image 

Click Finish (if you're asked to include any files in your test project, just click yes to the prompts).

Now your XML data is available to bind to your web test.

Data source is now available to your test.

Finally, let's put this data source to work.  We want to bind the name values in the data source to the "person" parameter for my web service call.  If you recall, that value is specified in the String Body property.  So we inject the following syntax (using the values appropriate for this example) into the String Body property:

{{DataSourceName.TableName.ColumnName}}, so for my example, I use {{Names_DataSource.Name.Name_Text}}

 image

Now we just need to tell the web test to execute once for each value in my data source.  We can do this two ways:

If you will mostly just run this test in a single pass (not iterate through the data source), you can just run your test and "Edit Run Settings" to augment (on a one-off basis) your iteration settings.

Editing test run settings

Again, note that doing this way will affect only the current test run (i.e. next run made), and will not be saved.

If you want to specify that you want to use the data source by default, you need to open the LocalTestRun.testrunconfig file in your Solution Items folder.

 Finding the .testrunconfig file

Opening the .testrunconfig file will give you the below dialog.  Select Web Test on the left, then click the radio button to specify "One run per data source row."  Click Apply then Close.

image

Now for the beautiful part.  Go back to your web test and run it again.  This time instead of a single run, it will automatically execute a test run for each row in your data source. 

Viewing test results with multiple runs

Notice results for each run, including pass/fail information, and the resulting SOAP envelope with the appropriate method result in each (I've highlighted the second run to show that "Mickey" was used in this run).

Happy Testing!