I need to create a test harness for testing one method on a pre-existing web service. That web service even comes with a test harness in the code but it's very old-school .Net and I can't fathom it - or learn for myself if I just try and pick it up.
There were several things I had to learn to do:-
1. Consume/wire up to the WCF service.
2. Read in test data from an input file.
Consuming a WCF Service
This was harder - or at least took me longer - than it should have been. It helps if you're in a Unit Test project, rather than a class library (doh!) and in the end was relatively simple - when you know how. I referred to the section "Accessing a service" at this page https://msdn.microsoft.com/en-us/library/bb386386.aspx to help. It was the first I found that talked about adding a Service Reference. Prior to that I was using the svcutil tool to create a client class, but still had some problems with that. It looked like it was going to work but I went the "Add a Service Reference" route.The beauty of programmatically testing a service is that in code it is just another class, and its public methods exposed are methods of that class. So you just need to create an instance of that class and you can call its methods. Don't forget to close it! I used [TestInitalize] and [TestCleanup] methods to ensure I did this properly.
A few quick tests proved I was able to all the service, receive an answer and Assert if it was right or not. Now to automate the data input from a file.
Read in test data from an input file
Again a microsoft page was a huge help - Walkthrough: Using a configuration file to define a data source. It struck me as odd that I found Microsoft resources more useful that StackOverflow. I guess there's a first time for everything...Several steps are required here, and it took some jiggery pokery to run correctly on my system but it worked. Perhaps most imporantly, I don't (yet) understand all the decorators that were suggested.
- Update app.config with custom configuration settings. Follow through the notes in the above link, bear in mind that at the end of that page is a complete example you can copy and paste. In summary you need to create something like this:-
A <configuration> section containing
<configSections> /// Standard text for a named section
<connectionStrings>
<named section> /// <microsoft.visualstudio.testtools> is the standard text
<dataSources>
I've used the full path to my input file in the connectionString attribute of the add element, with escaped backslashes \\ in the path. I've used an excel spreadsheet as the input file because this Microsoft page gives the correct info for connecting to a spreadsheet. I'd rather connect to a csv file, to be honest, but needs must.
- Add a TestContext into the TestClass
- Decorate your Test Method
[DeploymentItem("TestProjectFolder\\InputFile.xlsx")]
[DataSource("UseTheNameAttributeFromTheAddElementInDataSourcesInAppConfig")]
- Import System.Data
- Write your test.
//Arrange string MPString = context.DataRow["MP"].ToString(); if (!(String.IsNullOrEmpty(MPString))) { mp = Int32.Parse(MPString); } string idPrefix = context.DataRow["Prefix"].ToString();
Invoke the DataRow method of the TestContext to get the current row of your input file. The ToString() method is available which is useful.
As you can see above, to get an int you first call the ToString method and then parse it into an int. As I may not have any value in that column in the input spreadsheet I have to perform a check first.
You can read the expected result in from this spreadsheet too.
The Act part of the test is to call your web service, passing in whatever input parameters you require.
//Act string actualResult = client.GetData(mp, idPrefix); //Assert
Assert.AreEqual(expected, actualPrefix);
I'm using Assert.AreEqual but I find if a row fails that the only clue I get from the output is "(Data Row x)" where the first test is Row 0 (the heading row is ignored in the counting). Perhaps a different Assert method that lets me output what the expected result or some input was would help. For now I've added a column of numbers into my test input file as a guide.
Useful Note
I've also found that storing the test input file in my test project's folder means I can add it into the solution easily. Then when I want to edit the input file I just double click on it in solution explorer and it launches Excel.
Summary
Add a service reference to your existing WCF service.
Import System.Data and include it in your test class file
Add a TestContext member into the test class
Use TestInitialize and TestCleanup to ensure you instantiate the service and close it properly at the end of a test.
Add a custom section into your app.config file in the test project's folder
Write your tests, with two additional decorators. Use TestContext.DataRow to read a value from a column into a variable.