Blue flashes
04
Dec 09

MSpec

Here at Perfect Image we have just switched from using Test Driven Development (TDD) to Behaviour Driven Development (BDD). The library we have chosen to use for writing our BDD tests is Machine Specifications (MSpec). It’s a great framework and if you are interested in doing some BDD yourself you should take a look at it here and download it from Github here.

This was actually the first time I had used Git and it took some getting used to as a SVN user but after a little resistance (and moaning) I found it’s actually pretty easy to use. Don’t be put off by the command line interface, it does have a GUI but I actually found it best using bits of both. There are plenty of tutorials out there on the web to help you out too.

MSpec includes its own test runner whereas before we used MBUnit. We had no problems wiring it into our NAnt build scripts to work with NCover. It even produces a nice HTML output of the results from the tests ran. The only issue we had was that it did not have the option to produce an XML output which we needed to be able to display reports in Cruise Control .Net - our Continuous Integration server.

My team leader James had looked at the problem a little and was able to point me in the right direction to start off, which saved me having to track down the significant code in the project. What I ended up having to do was add an option to the runner for an XML output and then add the functionality of mapping the results to XML. Luckily, it is very similar to how the HTML is produced so I was able to use that as a skeleton to base my work off. The XmlWriter made this very easy to do:

public void Render(XmlWriter reportBuilder, Dictionary<string, List<ContextInfo>> contextsByAssembly)  
{
      reportBuilder.WriteStartDocument();
      reportBuilder.WriteStartElement("MSpec");


      if (_showTimeInfo)
      {
             RenderTimeStamp(reportBuilder);
      }


      RenderAssemblies(reportBuilder, contextsByAssembly);


      reportBuilder.WriteEndElement();
      reportBuilder.WriteEndDocument();
    }


...


private void RenderAssemblies(XmlWriter reportBuilder, Dictionary<string, List<ContextInfo>> contextsByAssembly)
{
      contextsByAssembly.Keys.ToList().ForEach(assembly =>
                                                 {
                                                   reportBuilder.WriteStartElement("assembly");
                                                   reportBuilder.WriteAttributeString("name", assembly);
                                                   RenderConcerns(reportBuilder, contextsByAssembly[assembly]);
                                                   reportBuilder.WriteEndElement();
                                                 });
}

The XML structure itself was very simple. Basically, all you need are nodes for assemblies, concerns, contexts and specifications. Each of these has a name with the specification also having a status to show whether it passed or failed. I also added a section for displaying the time when the report was generated so that it looked like this:

<MSpec>
<generated>
<date>23 October 2009</date>
<time>17:37:05</time>
</generated>
<assembly name="MyAssembly">
<concern name="MyClass">
<context name="When doing something">
<specification name="should display something" status="passed" />
<specification name="should also do something else" status="passed" />
</context>
</concern>
</assembly>
</MSpec>

Now that we had an XML output to work with, an XSLT was needed to create the report page on the Cruise Control project page plus another one to produce a little summary box for the dashboard. Being the first XSLTs I had written, they were far from being works of art but they were close enough to the original HTML output, give or take some questionable colour choices (James made me pick magenta, honestly). All that was left to do was to tell Cruise Control to add the contents of the XML to its log file and display the summary and full report using the XSLTs which were uploaded to the server.

This is how the summary looks on the dashboard:

MSpec Summary

And here’s how the report page looks:

MSpec Summary

At this point we were finally in a position where MSpec gave us everything that we had when we were running TDD tests on MBUnit and so we thought it would be a good idea to contribute back to the community. 

This is where I was really impressed by Git. I was easily able to make a branch of the project on Github and then commit my changes to this branch. Then it was simply a case of sending a pull request to the owner of the original repository, Aaron Jensen, and waiting for him to respond. A few days later, I received a message from Aaron saying he liked my additions and after I corrected some differences with the formatting, they were added to the trunk.

You can now see for yourself if you are running the latest version of MSpec. Just add “--xml <filepath>” to your MSpec command. The XSLT files were added in the misc folder if you wish to add the reports to your Cruise Control server also.

Barry

Filed under  //   bdd   mbunit   mspec   tdd   xml   xslt  
09
Nov 09

Developer Knowledge Sharing

The typical day of a software developer, like most workplace roles, is full of time pressures. You have to demonstrate that a particular piece of functionality behaves as per a user's story by the end of the week, and delivering late will impact the projects budget.

So you need to get it done, and move onto the next as soon as you can. When the project finishes, you move straight onto another. And that's not to mention the hundred possible day to day distractions.

The result is that day to day demands can easily distract the community of developers in your company from taking that important step back to consider the bigger picture, a vital ingredient in quality software development.

Without taking some time out to get all developers together for reflective consideration of processes and technologies you are using to deliver software, you can end up grinding away with the same familiar yet flawed or outdated methods, which make projects harder to deliver with the required quality and on time.

You can also end up with isolated project teams, unaware of what each other is doing - a novel solution to a problem may not be shared across all developers.

Projects should always end with a post-mortem. This usually involves everyone involved on the project: the PM, consultants, developers, testers, designers. Thus it is an invaluable project review, concerned with the successfulness of planning, meeting targets and deadlines, customer satisfaction, communication etc. However it is not a place for a developer code review, as it will be relatively non-technical, and only involves the subset of developers who worked on that project.

Therefore we need a different kind of review - a regular code review of a particular project (whether just started or long finished) or a technology, involving the entire development team. The goals should be:

  • To discuss and debate interesting, new or problematic processes and technologies, including everything from macro architecture to tiny code fragments.
  • To have as many developers as possible critically questioning why things were done as they are.
  • To highlight what code performed well, was easy to extend and maintain, and is easy to read and understand.
  • To highlight what code performed poorly, was hard to extend and maintain, and is difficult to read and understand.
  • To share software engineering tips, tricks and technologies across project teams, so everyone learns from other teams.
  • To share business knowledge across project teams, so everyone learns the business rules of new clients, what the solution does and how it benefits the client.

For example, in just a one hour session over some lunch to review a recently completed Windows Forms application, we covered the following topics:

  • AutoMapper, it's pros and cons, when to use it, problems encountered integrating it with Castle Windsor dependency injection container.
  • Accessing NHibernate entity collection properties (e.g. lists) - protection of a private instance, and exposing collection add and remove methods.
  • NHibernate configuration conventions.
  • Persisting 3 closely related entities in one database table using NHibernate, discriminating them using a table column. Pros and cons of this approach, how successful it was.
  • Managing database transactions in a Windows Forms application - use of conversation attributes, discussion of what application layer should be responsible.
  • Use of Behavior-Driven Design principles and rich domain objects, what effect this had on ease of development, readability and testing.

Topics like these are discussed day to day by developers within a team or between yourself and the person sitting next to you. The benefit of getting this discussion out into a larger debate involving all developers at the same time has been invaluable at Perfect Image.

James Allen

Filed under  //   automapper   bdd   development   knowledge sharing   nhibernate