Verification

In the previous examples we have used a string in the test class to supply the expected value of the mark of rendered by the WebPart. A better technique is to store these in a file. This can be achieved with a few additional lines of code, although this technique is implemented more elegantly in the Approvals test verification framework at http://approvaltests.sourceforge.net/. You may want to use the Approvals framework, although it is not essential, and does introduce another dependency into your project. Here we provide a simple method to get most of the benefit.

    public static bool Verify(string value)
    { // create an empty "expected" file if it doesn't already exist
      string path = System.Reflection.Assembly.GetCallingAssembly().CodeBase.Replace("file:///", "");
      path = Path.GetDirectoryName(path).Replace("\\bin\\Debug", "");
      var method = new StackTrace().GetFrame(1).GetMethod();
      string fileName = path + "\\" + method.DeclaringType.Name + "." + method.Name;
      var fs = new FileStream(fileName + ".expected", FileMode.OpenOrCreate);
      var sr = new StreamReader(fs);
      string contents = sr.ReadToEnd();
      sr.Close();
      fs.Close();
      if (value != contents)
      {
        var sw = new StreamWriter(fileName + ".actual");
        sw.Write(value);
        sw.Close();
        return false;
      }
      else
      {
        File.Delete(fileName + ".actual");
        return true;
      }
    }

This code can be incorporated into your test class and adapted as necessary, or as a convenience you can use the version we have incorporated into the fake point assembly. In order to use it we only need to pass this verify method a string containing the output of the WebPart. The Verify method returns a Boolean and so it can be wrapped by an Assert method from whatever test framework is in use. The test method shown above can now be modified to use the Verify method as follows:

    [TestMethod]
    public void RenderContents_Tasks()
    {
      ListName = "Tasks";
      StringWriter sw = new StringWriter();
      HtmlTextWriter writer = new HtmlTextWriter(sw);
      EnsureChildControls();
      RenderContents(writer);
      Assert.IsTrue(FakePoint.Test.Verify(sw.ToString()));
    }


When the Verify method is called for the first time an empty file will be created with a file name that derives from the Test Method, and with the file extension “.expected”. Generating the filename in this way ensures that multiple tests can coexist in the same directory; you just need to ensure that there is only one Verify method call per Test Method (a limitation that could easily be removed by passing a file name to the Verify method). Assuming the WebPart has generated some output, the verification will fail because the .expected file is empty. This will result in a second file being created with the extension “.actual” which of course contains the actual results of the rendering of the Web Part.

The usual workflow is to inspect the .actual file and see if the output is satisfactory, for example by dragging it on to the Visual Studio editor. If it is not, the code is modified until the .actual file matches expectations. At this point the contents of the .actual file can be placed in the .expected file, for example by renaming it to replace the expected file. This process is known as “approval”. The Approvals framework mentioned above supports this by providing tooling to achieve this with a single button click, although this is not essential in order to get the benefit of using this approach.

Although TDD purists would insist that the expected file should be created in the first instance, it can sometimes be quite tedious to manually create a file containing the HTML mark-up that has been output by a WebPart, if which might iterate over many list items. In this case the approvals process can offer a considerable time saving, while still retaining the spirit of the “test first” methodology.

As further tests are created there will come a point where it has to be decided whether to manually change the .expected file or simply copy across (or approve) the .actual file. Unless the .actual file is inspected very carefully, there is a risk that an error could be introduced into the output and then copied into the .expected file. This would defeat the purpose of the regression tests. For this reason it is probably safer to manually edit the .expected file, or failing that, to find another way of verifying the output contained in the .actual file before using it as the replacement .expected output.

The Approvals approach to verification tests described here can of course equally well be used in building integration tests running against an actual SharePoint instance.

Last edited Jan 12, 2010 at 9:44 AM by SPDoctor, version 4

Comments

No comments yet.