James's profileJames McCaffreyBlogLists Tools Help

James McCaffrey

Occupation
Location

James McCaffrey

Software Development, Testing, and Management
November 22

Testing WCF Services using TCP Sockets

Over the past few days I've been looking at testing WCF services using a network socket based approach. I got a proof-of-concept demo program up and running. As usual, there were several glitches along the way. The key to resolving most of these glitches was to examine network traffic between a WCF service and a client, using a traffic examination tool. I used Fiddler, which has come in handy many times. See screenshot below. In a larger perspective, software testing is often all about understanding some software system. Once a system is fully understood, testing the system manually or programmatically usually comes pretty easily (relatively anyway). I am writing up an article on the technique of testing WCF services using sockets for MSDN Magazine and I'm happy with the way it is going.
 
November 16

Programmatically Intercepting WCF Messages

Suppose you are testing a WCF (Windows Communication Foundation) service. In some situations you may want to view the low level traffic between a WCF client and the service. The easiest way to do this in general is to use a network analyzer such as netmon and capture the traffic as the client sends a request and receives a response. However in some test automation situations you may want to programmatically capture WCF traffic. There are several good blog posts on this topic but I couldn't find a complete end-to-end example so I experimented and came up with an example of how to do this.
 
First, let's assume we have a WCF service name MathService running in either a Console host, or in a Windows Service host, or in an IIS host:
 
[ServiceContract]
public interface IMathService
{
  [OperationContract]
  double Sum(double x, double y);
}
public class MathService : IMathService
{
  public double Sum(double x, double y)
  {
    double answer = x + y;
    return answer;
  }
}
 
To programmatically capture WCF traffic you can first create a Console Application client like so:
 
EndpointAddress epAddress = new
  EndpointAddress("
http://machine:8000/MyWCFMathService/Service/MathService");
MathServiceClient sc = new MathServiceClient(new WSHttpBinding(), epAddress);
// wire up traffic interceptor here in a moment
Console.Write("\nEnter a number: ");
double x = double.Parse(Console.ReadLine());
Console.Write("Enter another: ");
double y = double.Parse(Console.ReadLine());
Console.WriteLine("\nSending " + x + " and " + y + " to Sum in WCF Math Service");
 double ans = sc.Sum(x, y);
Console.WriteLine("\nThe response was: " + ans);
 
Next you can add two classes to the client like so:
 
class MyClientMessageInspector : IClientMessageInspector
{
  public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
  {
    Console.WriteLine("\n\n" + reply.ToString());
  }
  public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
  {
    Console.WriteLine("\n\n" + request.ToString());
    return null;
  }
}
class MyEndpointBehavior : IEndpointBehavior
{
  public void AddBindingParameters(ServiceEndpoint serviceEndpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    { }
  public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, System.ServiceModel.Dispatcher.ClientRuntime behavior)
  {
    behavior.MessageInspectors.Add(new MyClientMessageInspector());
  }
  public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
  { }
  public void Validate(ServiceEndpoint serviceEndpoint)
  { }
}

And then you can wire up the two classes in the client like so:
 
sc.Endpoint.Behaviors.Add(new MyEndpointBehavior());
 
When you execute the Console Application client program, WCF traffic will be echoed to the shell as demonstrated in the partial screenshot below.
 

November 07

Silverlight Application UI Test Automation

I have been looking at Silverlight lately and have been investigating how to create UI test automation for Silverlight applications. As far as I can tell so far, it looks like there are two main approaches. First, you can use the Microsoft UI Automation (MUIA) library to create C#, shell-based test automation. A second approach is to use JavaScript-to-Silverlight interoperability and create browser-based test automation. I haven't tried ether approach but I'm fairly confident I could work out the details. A third possibility is to somehow use Silverlight technology to create UI test automation for a Silverlight application. I'm not sure how this would work, or if the technique is even possible, but the idea sounds interesting.
October 31

Testing Contravariant and Covariant Methods

The .NET Framework version 4.0 supports a new programming language feature called variant methods. Let me cut to the chase and state I think variant methods are an example of solutions in search of a problem, but they're fascinating anyway. So what are contravariant and covariant methods, and how do you test them? In order to test variant methods you need to understand what they are. In short, MSDN Library documentation states that contravariance is the ability to use a less derived type, and covariance is the ability to use a more derived type than that originally specified. My initial reaction was pretty much WFH (what the heck). I couldn't entirely follow the MSDN examples so I played around with some code myself. After some experimentation, I believe that the scenario where contravariance and covariance are most likely to be used is when you 1.) have a generic interface, and also 2.) have a base class which implements the generic interface, and also 3.) a second class which is derived from / inherits from the base class. For example, suppose you have some generic interface IConsoleDisplayable<T>:
 
public interface IConsoleDisplayable<T>
{
  . . .
}

and a class Person which implements IConsoleDisplayable<>, and also a class Employee which is derived from class Person. Without contravariance and covariance the following code does not work:
 
IConsoleDisplayable<Person> p = new Person("Smith", "Chris"); // OK
. . .
IConsoleDisplayable<Employee> e = p; // error
 
and requires an explicit cast like this:
 
IConsoleDisplayable<Employee> e = (IConsoleDisplayable<Employee>)p; // OK
 
But if you declare the generic interface as contravariant by adding the "in" keyword like this:
 
public interface IConsoleDisplayable<in T>
{
  . . .
}
 
then the code above (without an explicit cast) compiles. Well this is just plain psycho on a variety of levels and seems like the C# language team had way too much time on their hands. Just because you can create some new language feature doesn't necessarily mean you should. (Of course, there's no reason why application or system developers have to use variant methods). In my opinion, the advantage gained by eliminating an explicit cast is not worth the additional complexity of a contravariant interface. But it's an interesting language concept for sure.

 
October 23

Testing Curried Functions

The new F# programming language allows you to write curried functions. I am not a fan of using curried functions, at least from my point of view as a software tester. By the way, the term "curried" comes from Haskell Curry, a mathematician. Consider this normal F# code:
 
printfn "\nBegin curried function demo\n"
let s1 = "Hello"
let s2 = "world"
 
let prependString p s =
  let result = p + s
  result
 
let r1 = prependString "//" s1
let r2 = prependString "//" s2
printfn "r1 and r2 are %s %s \n" r1 r2
 
The result would be, as you'd expect "r1 and r2 are //Hello //World". Now here's a way to use curried functions:
 
let curriedPrependSlashes =
  prependString "//"
 
let r3 = curriedPrependSlashes s1
let r4 = curriedPrependSlashes s2
printfn "r3 and r4 are %s %s \n" r3 r4
 
The result would be identical, "r3 and r4 are //Hello //World". From a usage point of view curried functions allow you to reduce the number of arguments passed to a function when the function is called. I don't like this from a testing point of view because currying usually involves an extra call to a non-curried helper function, which makes testing a bit more opaque so to speak. In other words, the call:
 
let r1 = prependString "//" s1
 
is more clear to me as a tester than the call:
 
let r3 = curriedPrependSlashes s1
 
But, this is really more opinion than technical and some people whose opinions I respect think curried functions are great things.
 
 
Software Testing: Fundamental Principles and Essential Knowledge
.NET Test Automation Recipes: A Problem-Solution Approach