locked
How to test WCF Web Service (.svc) using VSTS 2008 Test Edition

    Question

  • Hi there,

    I am new to the VSTS 2008 Test Edition and I am a tester without much coding skills. I am learning how to use this tool to test our WCF Web Service (file extension .svc). I have learned how to test XML Web Service with file extension (.asmx) from some articles/walkthrough on MSDN - How to: Create a Web Service Test (http://msdn2.microsoft.com/en-us/library/ms182557.aspx).

     

    Note that in this walkthrough you can copy the XML portion of SOAP request from the Web service description page:

    <?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" xmlnsTongue Tiedoap="http://schemas.xmlsoap.org/soap/envelope/">

        <soap:Body>

            <CheckStatus xmlns="http://tempuri.org/">

                <userName>string</userName>

                <password>string</password>

                <orderID>int</orderID>

            </CheckStatus>

        </soap:Body>

    </soap:Envelope>

     

    Our WCF Web service (.svc) does not provide such SOAP body description page and is expecting to receive byte () data type. Our developer team created a test client application to test our WCF web service. Below is its code. Hope helps explaining my problem:

     

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

            Try

                'Load in the XML message as an XDocument

                Dim Message As XDocument = XDocument.Load("C:\Enrollments.xml")

                Dim Result As String = ""

     

                'Convert XDocument to byte array

                Dim encoding As UTF8Encoding = New UTF8Encoding()

                Dim Enrollments As Byte() = encoding.GetBytes(Message.ToString)

     

                'Create a new PASIEnrollmentService, accessed thru a Web Reference

                Dim S As New PASIEnrollmentService.PASIEnrollmentService

     

                'Submit the enrollments to the Web Service

                Result = S.SubmitEnrollment("SenderInfo", "CallerInfo", Enrollments)

                Response.Write("Confirmation number: " & Result)

     

            Catch ex As Exception

                Response.Write("Error: " & ex.Message)

     

            End Try

     

        End Sub

     

    1.       What is the best approach to test WCF Web Service (.svc)?

    2.       Do .svc WCF Web service test scripts have to involve a lot of customized coding? In the walkthrough article, it almost involves no coding at all for testing .asmx web service which is what testers would like to see.

    3.       Is VSTS 2008 Test Edition the right test tool for testing WCF web service (.svc)? Any suggestions/comments.

     

    Thanks for your help. Let me know if you need more info.

     HaYin

    Friday, February 15, 2008 10:39 PM

Answers

  • Hi HaYin,

     

    The typical way of testing WCF services is to create a test project, add a service reference to the project, and then write a test against the client object that is automatically created for you:

    • Create a test project
    • Right-click References and select Add Service Reference
    • In the Address box, type in the URL to the SVC file that is hosted on a web server. You can use the Discover button to find WCF services in the same solution.
    • Select a namespace to use for the service client that will be created, and press OK

    This will create a class called <Namespace>.<ServiceName>Client for you, which will act as a client proxy to the WCF service. You can then write unit tests against that class just as you would write unit tests against a regular class. You could have a helper method that would convert some input parameters to the Byte array the WCF service takes, and returns the result. Then, each unit test would just call the helper method with the appropriate input parameters, and do validation on the output. The amount of code needed in each unit test can be minimized, but depends on how much validation needs to be done.

     

    It looks like what you have is a web page that acts as a client to the WCF service. It is possible to have the web page take input parameters as query-string parameters in the URL, and have it write the result to the response, as it is already doing. With this, it would be possible to create web tests to test the WCF service through the web page. However, this requires that the web page be hosted on a web server, and separates related parts of test code. I would recommend the above approach.

     

    To answer your questions specifically:

    1. The first approach I mentioned above is probably the best way to test a WCF service. It allows you to test methods/properties exposed in the service contract in the same way as any other client application would use the service.
    2. The amount of code that is necessary really depends on how much validation needs to be done on what is being tested. You can use a web page client as an alternative, in which case the amount of code that is needed may be slightly reduced, but you still need the same inputs to the service and the same validation on the outputs, so if it is not through code, it will be through searching the response from the web page. Using a web page client may even unnecessarily complicate your test code, in things such as parsing the query strings to convert the input parameters to the right types, and then parsing the response text to do validation.
    3. VSTS 2008 Test Edition is definitely the right tool for testing WCF services. With the service client that is automatically created for you, testing a WCF service becomes a task as simple as testing a regular class.

    Hope that helps.

     

    Thanks,

    Kount

    Monday, February 18, 2008 5:48 PM
  •  

    The "Add Service Reference" dialog is targeted towards .NET Framework 3.0 and 3.5. It will create a WCF client for a WCF service or a web service. Since WCF does not exist in version 2.0 of the framework, code generated using this option cannot target .NET Framework 2.0.

     

    The "Add Web Reference" dialog does not support WCF services, and generates an ASP.NET SOAP client for a web service. The code generated can target .NET Framework 2.0, since it creates an ASP.NET client.

     

    Here are a couple of links with information on testing WCF services:

    http://blogs.msdn.com/ploeh/archive/2006/12/03/UnitTestingWCFServices.aspx

    http://blogs.msdn.com/ploeh/archive/2006/12/04/IntegrationTestingWcfServices.aspx

    http://blogs.msdn.com/martijnh/archive/2007/05/17/testing-wcf-service-implementations.aspx

     

    If you want to do some manual verification of a WCF service, or quickly test some input parameters, you may be interested in the WCF Service Host and WCF Test Client. Here are a couple of links on those:

    http://msdn2.microsoft.com/en-us/library/bb552363.aspx

    http://msdn2.microsoft.com/en-us/library/bb552364.aspx

     

    Thanks,

    Kount

    Thursday, February 21, 2008 6:21 PM

All replies

  • Hi HaYin,

     

    The typical way of testing WCF services is to create a test project, add a service reference to the project, and then write a test against the client object that is automatically created for you:

    • Create a test project
    • Right-click References and select Add Service Reference
    • In the Address box, type in the URL to the SVC file that is hosted on a web server. You can use the Discover button to find WCF services in the same solution.
    • Select a namespace to use for the service client that will be created, and press OK

    This will create a class called <Namespace>.<ServiceName>Client for you, which will act as a client proxy to the WCF service. You can then write unit tests against that class just as you would write unit tests against a regular class. You could have a helper method that would convert some input parameters to the Byte array the WCF service takes, and returns the result. Then, each unit test would just call the helper method with the appropriate input parameters, and do validation on the output. The amount of code needed in each unit test can be minimized, but depends on how much validation needs to be done.

     

    It looks like what you have is a web page that acts as a client to the WCF service. It is possible to have the web page take input parameters as query-string parameters in the URL, and have it write the result to the response, as it is already doing. With this, it would be possible to create web tests to test the WCF service through the web page. However, this requires that the web page be hosted on a web server, and separates related parts of test code. I would recommend the above approach.

     

    To answer your questions specifically:

    1. The first approach I mentioned above is probably the best way to test a WCF service. It allows you to test methods/properties exposed in the service contract in the same way as any other client application would use the service.
    2. The amount of code that is necessary really depends on how much validation needs to be done on what is being tested. You can use a web page client as an alternative, in which case the amount of code that is needed may be slightly reduced, but you still need the same inputs to the service and the same validation on the outputs, so if it is not through code, it will be through searching the response from the web page. Using a web page client may even unnecessarily complicate your test code, in things such as parsing the query strings to convert the input parameters to the right types, and then parsing the response text to do validation.
    3. VSTS 2008 Test Edition is definitely the right tool for testing WCF services. With the service client that is automatically created for you, testing a WCF service becomes a task as simple as testing a regular class.

    Hope that helps.

     

    Thanks,

    Kount

    Monday, February 18, 2008 5:48 PM
  • Hi Kount,

     

    Thank you so much! Your reply was really helpful, especially you pointed out that writing unit tests is the best way to test a WCF service. Can you provide me some documents/links regarding testing WCF web service? I have hardly found articles/links on internet (MSDN) regarding testing WCF web service.

     

    For adding reference, why using Service Reference to add WCF web service, instead of using Add Web Service? Does it matter which one is used? What are the differences?

     

    Thanks,

    HaYin

    Wednesday, February 20, 2008 5:58 AM
  •  

    The "Add Service Reference" dialog is targeted towards .NET Framework 3.0 and 3.5. It will create a WCF client for a WCF service or a web service. Since WCF does not exist in version 2.0 of the framework, code generated using this option cannot target .NET Framework 2.0.

     

    The "Add Web Reference" dialog does not support WCF services, and generates an ASP.NET SOAP client for a web service. The code generated can target .NET Framework 2.0, since it creates an ASP.NET client.

     

    Here are a couple of links with information on testing WCF services:

    http://blogs.msdn.com/ploeh/archive/2006/12/03/UnitTestingWCFServices.aspx

    http://blogs.msdn.com/ploeh/archive/2006/12/04/IntegrationTestingWcfServices.aspx

    http://blogs.msdn.com/martijnh/archive/2007/05/17/testing-wcf-service-implementations.aspx

     

    If you want to do some manual verification of a WCF service, or quickly test some input parameters, you may be interested in the WCF Service Host and WCF Test Client. Here are a couple of links on those:

    http://msdn2.microsoft.com/en-us/library/bb552363.aspx

    http://msdn2.microsoft.com/en-us/library/bb552364.aspx

     

    Thanks,

    Kount

    Thursday, February 21, 2008 6:21 PM
  • Thank you Kount. You have been very helpful.

     

    Sorry, I have 2 questions here:

     

    1. Our current WCF web service contains only function (see below).

     

    Function SubmitEnrollment(ByVal Sender As String, ByVal CallerContext As String, ByVal XMLdocument() As Byte) As String

    Member of PoC_PASITestProject.PASIServices.IPASIEnrollmentService

     

    I need to do load testing for it by simulating multiple users sending the XML file via this WCF web service. What I have done so far was that I have created multiple Unit Tests - all the code in these Unit Tests are the same but just pointing to different XML files. Then creating a Load Test and add these 'tests' as different scenarious into the Load Test.

     

    I am wondering what would be the best approach to test (load test) such WCF web service which has one single function? Should I create just ONE single Unit Test but contains multiple <TestMethod()> OR multiple Unit Tests which each Unit Test contains only one <TestMethod()>? OR either way works?

     

     2.  when I run a load test with multiple scenarious (unit tests) I got an error:

     

    System.InvalidOperationException: Could not find default endpoint element that references contract 'PASIServices.IPASIEnrollmentService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element..

     

    I checked the "app.config" file and it has the 'endpoint' (see below). What do I miss here? Thank you so much for your help.

    <?xml version="1.0" encoding="utf-8" ?>

    <configuration>

    <configSections>

    </configSections>

    <system.diagnostics>

    <sources>

    <!-- This section defines the logging configuration for My.Application.Log -->

    <source name="DefaultSource" switchName="DefaultSwitch">

    <listeners>

    <add name="FileLog"/>

    <!-- Uncomment the below section to write to the Application Event Log -->

    <!--<add name="EventLog"/>-->

    </listeners>

    </source>

    </sources>

    <switches>

    <add name="DefaultSwitch" value="Information" />

    </switches>

    <sharedListeners>

    <add name="FileLog"

    type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"

    initializeData="FileLogWriter"/>

    <!-- Uncomment the below section and replace APPLICATION_NAME with the name of your application to write to the Application Event Log -->

    <!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->

    </sharedListeners>

    </system.diagnostics>

    <system.serviceModel>

    <bindings>

    <basicHttpBinding>

    <binding name="BasicHttpBinding" closeTimeout="00:01:00" openTimeout="00:01:00"

    receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"

    bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"

    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"

    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"

    useDefaultWebProxy="true">

    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"

    maxBytesPerRead="4096" maxNameTableCharCount="16384" />

    <security mode="None">

    <transport clientCredentialType="None" proxyCredentialType="None"

    realm="" />

    <message clientCredentialType="UserName" algorithmSuite="Default" />

    </security>

    </binding>

    </basicHttpBinding>

    </bindings>

    <client>

    <endpoint address="http://7k0g091/PASIServices_SYST/EnrollmentService.svc" <==========

    binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding"

    contract="PASIServices.IPASIEnrollmentService" name="BasicHttpBinding" />

    </client>

    </system.serviceModel>

    </configuration>

     

    Thursday, February 21, 2008 7:02 PM
  • I would suggest that you post the questions regarding load tests in the Web and Load Testing forum, as you will probably get more comprehensive answers there.

     

    1.

     

    You do not have to create multiple unit tests with the same code except using a different set of data for inputs. This is precisely what data-driven tests can solve. You can create a data-driven unit test that specifies a data source to use (an XML file, database, spreadsheet, etc.). Then, in the unit test body, you can use TestContext.DataRow to obtain the current row of data to use as the input for the test. The test will run as many times as you have data rows in the data source.

     

    Since you are using one XML file per test as the input for the test, you can create an XML file containing the list of XML files and use that as a data source for your test. Here is a good starting point for more information on creating data-driven tests: http://msdn2.microsoft.com/en-us/library/ms182519.aspx.

     

    2.

     

    I have a couple of questions here. Is it working with a single unit test under a load test? What about a single unit test that is not run under a load test? If none of these are working, then can you also try typing in the endpoint address in Internet Explorer on the computer where the test is running and see if you get anything. If this doesn't work, then you may be getting that error because the service is not available at that endpoint address.

     

    Depending on what kind of authentication the service is using, you may need to provide an <identity> element under <endpoint> with the appropriate authentication information and a DNS to use to do the authentication. Here is some information on the <identity> element: http://msdn2.microsoft.com/en-us/library/ms731721.aspx. If you can verify that the service is available and can be reached through Internet Explorer on the test machine, then you can try deleting the service reference and recreating it to see if the problem gets solved.

     

    Thanks,

    Kount

    Friday, February 22, 2008 1:41 AM
  • Im using the approach you tell about creating the <Namespace>.<ServiceName>Client however i need to use a FileStream to go as input for the service, the generated "about to serialize" classes generated does not contain a definition for File.Open() so i cant create the FileStream object, is there anyway to generate this methods for this helper classes? or what approach should i take? thanks
    Friday, April 25, 2008 2:35 AM
  • Hi Kount,

     

    I need some help on code coverage. Actually we are using a customised dll to call the WCF methods, my dll will initiate the service host and call my contracts in my service and will give the result. I need to get code coverage percentage of my dll. After running the test I am getting this message from code coverage " Empty results generated: none of the instrumented binary was used. Look at test run details for any instrumentation problems."

     

    Thanks

    Kavitha

     

     

     

    Wednesday, June 11, 2008 10:10 AM
  • Hi Kavitha,

     

    Which binaries have you marked for instrumentation?

     

    Ensure that the active test run configuration is the correct one (if you have more than one test run configuration in the solution items). Double-click the active test run configuration to edit it, and in the Code Coverage page, please ensure that your customized DLL is in the list of assemblies to instrument, and checked.

     

    If that still does not work, you can try manually instrumenting the assembly to see if it is actually being hit by your test or code under test. Instructions on doing that are available here, under the subheading "Scenario 3: Product and Test Binaries Only".

     

    Thanks,

    Kount

    Tuesday, June 24, 2008 8:24 PM
  •  

    Hi Kount,

     

    Thanks for the reply.

     

    I have tried that manually instrumenting scenario also, but not getting the code coverage. Actually I am calling my WCF services in my client, and the methods in the WCF will call another dll to complete the functionality. Are my client application and the WCF services will run the same process? I came to know that "Code coverage collection works only on the same session and IIS worker process runs usually on session 0" from this forum - "http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=102398&SiteID=1". Will it might be the problem?

     

    Thanks,

    Kavitha

    Friday, June 27, 2008 7:42 AM
  • You could also give WCFStorm a shot.  It can handle both load and functional test cases.
    Tuesday, July 07, 2009 3:13 AM
  • Hi,

    And what would be the best way to test it (the above example) without creating a reference to the service and using Mtom encoding (just sending SOAP requests - POST method)?  In other words, I don't want to create a reference for any new services and don't want to have to specifically handle any methods.  I just want to send a generic soap request, substituting in any of my parameters/method name.  I can make a call to a .asmx web service, by UTF8 encoding the message...but how would one do it calling a .svc using Mtom encoding?

    thanks!

    Monday, April 05, 2010 4:00 PM
  • Hi,

    And what would be the best way to test it (the above example) without creating a reference to the service and using Mtom encoding (just sending SOAP requests - POST method)?  In other words, I don't want to create a reference for any new services and don't want to have to specifically handle any methods.  I just want to send a generic soap request, substituting in any of my parameters/method name.  I can make a call to a .asmx web service, by UTF8 encoding the message...but how would one do it calling a .svc using Mtom encoding?

    thanks!

    Mr. GoodFun

    Monday, April 05, 2010 4:45 PM
  • Hi.

    I haven't use VSTS; however, the work that I'm involved with is using VSTS 2010 and I'm a tester assigned to test WCF. I don't have any technical background. Could you please help me create a test approach for this for assembly testing? or are there any tutorial links or sample documents you can provide? especially in creating assembly test plans.

    Thanks in advance for your help.

    BB

     

     

     

    Friday, October 22, 2010 7:41 AM