CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Peter's Gekko

public Blog MyNotepad : Imho { }

March 2007 - Posts

  • 500. And now this blog is out of control

    Yesterday Jeffrey published his 500th post without even mentioning the milestone. Scott Sam was aware of his 150th New and Notable. And today this is my 500th post. Some short words looking back and ahead.

    Over the posts and years a lot has happened. To me the most fascinating is that I'm no longer writing all content by myself. The long list of comments on some posts have turned into an autonomous form of community life. Recently I publicly asked for advice on how to manage that. Which led to good feedback and a plan : Hereby I'm giving up control over (part of) my blog. I've created a new post category: out of control and will use that to mark (old) posts. Which indicates that I will only do the primal moderation; that is delete comments which are abusive or (to far) off topic. But I am not going to go into all content myself. Anybody else who would like to say something on the subject is more than welcome. Be my guest.

    Looking ahead there are more plans than time. The TDD virus has also hit me which already resulted in a public confession. (The newly converted are the worst..) At the moment I'm working with a team who's making their first steps using the VSTS test tools instead of the usual nUnit. There is fodder there, after all it's the methodology, not the tool. But first comes the man. On staying in physical shape by living better I want to do more with my (other) CycleBetter blog. IT and cycling do share interesting things like a Vista gadget helping me to plan a dry ride or a Windows mobile device helping me to find my way touring the hills of France.

    Of course, there will be more of the usual tidbits I meet in the huge world .NET and whatever crosses it's path. But whatever what I've written or am going to write, the Codebetter community is a fantastic place to do that. I have learned so much over here and hope that me and all commenting co-writers can keep up for another 500.

  • Formatting source code in a blog post

    For some time now I'm using Word 2007 to write my blog posts. Which works quite well, except when it comes to source code. This is a public experiment.

    This source was inserted with using a straigth copy.

    [Test]

    public void IsDeceased()

    {

    VecozoLib.ServiceWrapper sw = new ServiceWrapper();

    VecozoLib.VecozoService.RetourinfoCovType data = sw.PersonData(DateTime.Parse("1-5-1945"), 141919723);

    Assert.AreEqual(VecozoLib.ResultaatRaadpleging.PersoonIsOverleden, (VecozoLib.ResultaatRaadpleging) data.ResultaatcodeCOV);

    }

    Looks great in Word, but not that good online. The line spacing is far to great and all the indentation is gone.

    To compare, this is the same using CopySourceAsHtml to do the copy.

    [Test]

    public void IsDeceased()

    {

       VecozoLib.ServiceWrapper sw = new ServiceWrapper();

       VecozoLib.VecozoService.RetourinfoCovType data = sw.PersonData(DateTime.Parse("1-5-1945"), 141919723);

       Assert.AreEqual(VecozoLib.ResultaatRaadpleging.PersoonIsOverleden, (VecozoLib.ResultaatRaadpleging) data.ResultaatcodeCOV);

    }

    Which does not look that good in Word, but looks better on line. The line spacing is still too big, but the indentation is preserved.

    And this is CopySourceAsHtml with linebreaks stripped

    [Test]



    public



    void IsDeceased()



    {



       VecozoLib.ServiceWrapper sw = new



    ServiceWrapper();



       VecozoLib.VecozoService.RetourinfoCovType data = sw.PersonData(DateTime.Parse("1-5-1945"), 141919723);



       Assert.AreEqual(VecozoLib.ResultaatRaadpleging.PersoonIsOverleden, (VecozoLib.ResultaatRaadpleging) data.ResultaatcodeCOV);



    }



    Which is a mess.

    Brendan pointed me to dp.SyntaxHighlighter. Since then this post keeps getting updated.

    This source code formatter requires the syntaxhighligher scriptlibrary, which is available on Codebetter. For this tool to work you have to enclose the source code in a pair of tags.

    <textarea name="code" class="c#" cols="60" rows="10">   

    ... source code here ...   

    </textarea>   

    This is difficult to do in Word 2007, as you cannot directly edit the html it publishes. Just like images this requires some fiddling by hand in the HTML in the blog dashboard. I paste the source as plain text, and do the HTML fiddling in the dashboard.

    Due to the "inteligence" built into the CS rich text control this can be quite a job. But as you see the result can be nice.

    Word 2007 is a great blogwriter. But the downside is that it's not that good with source code and there is no way (I know) to edit specific HTML. CopyAsHtml can come in handy.

  • TDD: Test driving the Vecozo webservice

    This is not my usual kind of subject. Most of my post are on the diversity of share worthy tidbits I encounter while building apps. Test Driven Design is quite a hot topic here on Codebetter. So far I had nothing to add to the great writings of Jeremy et al. But a discussion on a post by Jay on Javascript struck me. It gave the impression TDD as something too big or complicated to get started with. In this post I will describe some of my experiences with TDD. It's a very simple story on a very simple problem but it makes clear how TDD is also for me an easy way to tackle problems.

    This story deals with the Vecozo web service. This secured web service offers a way to check Dutch medical insurance data. The number of pages in the documentation is gigantic but there is no clear example, not even a hint, how to use the service from code. I will use TDD to explore the service and will end with the base for a simple API.

    The Vecozo package contains:

    • An url to (a test location of) the web service
    • A certificate (obtainable on request)
    • A huge document describing the inner decision paths and return codes of the web service
    • A description of the request and the response messages
    • Spreadsheets describing available test data
    • The remarks that the service has been built using .NET 1.1 and WSE

    What is lacking is the way to combine all of this to make successful requests.

    This is where TDD comes in. I am using nunit the mother of all unit test frameworks. My tests are located in a new class library project added to my solution. The test project references the nunit framework and the application project. In the tests I can call all public members of the application. The test code has a reference to the application I'm building but the application itself does not reference anything extra; I do not force my customer into automated testing.

    There are several tools available to actually run the tests, both command line and GUI versions. Resharper has a nice testrunner which integrates into Visual Studio. As an alternative Nunit contains one which looks and behaves just the same.

    The test have to be public classes of the new lib. The test runner instantiates objects of Classes decorated with the TextFixture attribute. Public methods in the classes, decorated with the Test attribute, contain the test code to be executed.

    What code the test will execute depends. A way to start could be to take existing code and automatically test metrics to check the behavior of that code. A test passes when it runs without throwing an exception. To harden a test you can conditionally raise (assertion) exceptions, the nunit Assert class has loads of usable members to do that. Designing and coding these kinds of test is not always easy. What metrics can/should you test ? What algorithm you need to assert that the test passes ?

    The methodology of Test Driven Development approaches the matter the other way round. The first line of code is the test itself. The implementation of the application is code built to pass those tests. Quite an eye-opener on where to start is Jimmy Nilson's book on Domain Driven Design I read last summer. At first read it chatters away, writing almost trivial code. In tests. But building test upon test a quite good application emerges.

    Let's give this a try on the Vecozo web service. I start writing out questions in code on what I want to build.

    The first question:

    • Can I create an object to wrap up handling the web service?.

    Written out as test

    [TestFixture]

    public class VecozoWebServiceTests

    {

       [Test]

       public void CanCreateWrapper()

       {

          VecozoLib.ServiceWrapper o = null;

          Assert.IsNotNull(o);

       }

    }

    For the test code to build I need to write the ServiceWrapper class.

    namespace VecozoLib

    {

       public class ServiceWrapper

       {

       }

    }

    The code builds but the test fails. For it to pass the wrapper object has to be properly instantiated.

    [Test]

    public void CanCreateWrapper()

    {

       VecozoLib.ServiceWrapper;

       o = new ServiceWrapper();

       Assert.IsNotNull(o);

    }

    This test may seem quite trivial. But it does assert that a ServiceWrapper object can be instantiated, it's constructor did not raise an exception. When refactoring the test will become even more valuable. When the constructor is refactored into a factory, the (slightly rewritten) test will assert the factory does create objects.

    Here's the unit testing mantra: Red, Green, Refactor. Write a test which fails, write the code to make it pass and safely refactor the code to the evolving needs. For the latter the tests will guard the code to keep working

    Now the first test reads green and we have a starting place. The object is going to invoke the web service. I do have an url for that so I can add a web reference. VS generates a proxy to the web service. The service appears to have one web method which does all the work. The next question is:

    • Can I invoke this webmethod ?

    I don't care yet whether I'm invoking it correctly, I just want to see whether the web service accepts my requests and returns something. The simplest request sends an empty list to validate. This is implemented in a new method of the service wrapper.

    public class ServiceWrapper

    {

       public object InvokeVecozoService()

       {

          vz3738 ci = new vz3738();

          Console.WriteLine(ci.Url);

          ControleerInput requestMessage = new ControleerInput();

          requestMessage.Verzekerden = new AanvraagCovType[0];

          object responseMessage = ci.controleer(requestMessage);

          return responseMessage;

       }

    }

    Vz3738 is the webservice, the webmethod is named Controleer. Note that the method writes the url of the service to the console. All the test does is call this method.

    [Test]

    public void CanInvokeService()

    {

       VecozoLib.ServiceWrapper sw = new ServiceWrapper();

       object response = sw.InvokeVecozoService();

       Assert.IsNotNull(response);

    }

    The test fails on an exception.

    The nice thing is that the test runner catches the output. The url is there and also a stack trace. The message is loud and clear : no Access (Geen toegang). It's time to do something with my Vecozo certificate.

    Next question:

    • Can I get a (non expired) certificate

    I want the serviceWrapper to expose the Vecozo certificate. Written out in a test

    [Test()]

    public void ValidCertificateAvaliable()

    {

       VecozoLib.ServiceWrapper sw = new ServiceWrapper();

       System.Security.Cryptography.X509Certificates.X509Certificate cert = sw.VecozoCertificate;

       Assert.IsTrue(DateTime.Parse(cert.GetExpirationDateString()) > DateTime.Now);

    }

    Unless a valid Vecozo certificate is installed the test will fail. The implementation of the code to get the certificate is pretty straightforward.

    public X509Certificate VecozoCertificate

    {

       get

       {

          X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);

          certStore.Open(OpenFlags.ReadOnly);

          X509Certificate2Collection certs = certStore.Certificates.Find(X509FindType.FindByIssuerName, "Vecozo", false);

          if (certs.Count == 1)

             return certs[0];

          else

             return null;

       }

    }

    Now the test shows I do I have a certificate. But what to do with it? Sign the message? Encrypt it ? There are a lot of possibilities. The Vecozo docs are blank on this. Googling around I found the simplest thing to do with a certificate is just pass it to the service in the ChildCertificates collection of the proxy. Let's try this.

    public object InvokeVecozoService()

    {

       vz3738 ci = new vz3738();

       Console.WriteLine(ci.Url);

       ci.ClientCertificates.Add(VecozoCertificate);

       ControleerInput requestMessage = new ControleerInput();

       requestMessage.Verzekerden = new AanvraagCovType[0];

       object responseMessage = ci.controleer(requestMessage);

       return responseMessage;

    }

    This simplest thing is exactly what this service demands. When the certification test passes now the connection test also passes. And now I start communicating with the service. The unit test are a great status monitor; they test the status of the certificate and the availability of the service in a single click.

    Now my tests can jump right into testing the domain specific features of the service itself. The Assert class of the nUnit framework has loads and loads of (static) methods to compare expected values with the actual values returned from the service.

    There are many ways to request data from the Vecozo web service. The documentation does give a good overview. In the next example I am requesting the data of one person based on birth date and BSN (you can compare that to a SSN). In case you are going to work with the actual web service check the documentation on this. In case you are just interested in TDD it suffices to say that the method returns some domain specific data. Note that the actual invocation of the web service has already been refactored into a (private) method. The earlier test will make sure I have done that correctly.

    public RetourinfoCovType PersonData(DateTime birthDate, int bsnNummer)

    {

       ControleerInput requestMessage = new ControleerInput();

       requestMessage.Verzekerden = new AanvraagCovType[1];

       requestMessage.Verzekerden[0] = new AanvraagCovType();

       requestMessage.Verzekerden[0].PeildatumVerzekering = DateTime.Now;

       requestMessage.Verzekerden[0].SoortVerzekering = 92;

       requestMessage.Verzekerden[0].GeboorteDatum = birthDate;

       requestMessage.Verzekerden[0].BSN = bsnNummer;

       requestMessage.Verzekerden[0].BSNSpecified = true;

       return getResponseMessage(requestMessage)[0];

    }

    A simple straightforward test against the test data available to check the domain specific functionality of the code:

    [Test]

    public void IsDeceased()

    {

       VecozoLib.ServiceWrapper sw = new ServiceWrapper();

       VecozoLib.VecozoService.RetourinfoCovType data = sw.PersonData(DateTime.Parse("1-5-1945"), 141919723);

       Assert.AreEqual(0, data.ResultaatcodeCOV);

    }

    The assertion compares the result with 0. The test will fail.

    Again the output clearly tells why the test failed. The return code was not 0 but 6420. The documentation lists all return codes, where 6420 stands for deceased. Which matches the description of the test data on this "person". To make my code better maintainable I've written out a descriptive enumeration of these return codes.

    public enum ResultaatRaadpleging : int

    {

       OK = 0,

       NietGeauthoriseerdBijAangegevenVerzekeraar = 6400,

       ……

       BSNvakerGevonden = 6419,

       PersoonIsOverleden = 6420

    }

    Using that to make the test pass:

    [Test]

    public void IsDeceased()

    {

       VecozoLib.ServiceWrapper sw = new ServiceWrapper();

       VecozoLib.VecozoService.RetourinfoCovType data = sw.PersonData(DateTime.Parse("1-5-1945"), 141919723);

       Assert.AreEqual(VecozoLib.ResultaatRaadpleging.PersoonIsOverleden, (VecozoLib.ResultaatRaadpleging) data.ResultaatcodeCOV);

    }

    Here I am writing tests which describe the actual desired domain specific functionality of my app. The code I am writing to fulfill the test is code which also fulfills my customers demands. Adding all desired functionality will result in a lot of refactoring. Adding the functionality test by test will make sure that no existing code breaks in the process.

    So far the TDD gospel in my words. I hope to have made clear that using TDD as a methodology is nothing mysterious, just an easy way to gain and keep control over the app you are building. Nothing more, nothing less.

More Posts