Geeks With Blogs
// ThomasWeller C#/.NET software development, software integrity, life as a freelancer, and all the rest

When doing software development the lean/agile way, you don't have much requirement documents produced upfront - and right so, because they tend to become outdated and useless within a couple of days, after the 'real' development phase of a project has started.

However, a developer might occasionally write down some informal specs on the fly while he's coding. Personally, I often do this, when I'm implementing a feature that spans more than some minutes of programming time and is somewhat more complex. It helps me to clarify my thought process and to keep track of things, as I develop them in a step-by-step manner. Here's an example of such an "ad-hoc specification":


- There are 5 different types of books.

- Each single book costs EUR 8.00.

- Discount is calculated according to the following rule:

   One copy of any of the five books costs 8 EUR. If, however, you buy two different books from the

   series, you get a 5% discount on those two books. If you buy 3 different books, you get a 10%

   discount. With 4 different books, you get a 20% discount. If you buy all 5, you get 25%.


001: Basics

a) A not existing basket must have the price 0.0 (no exception).

b) An empty basket must have the price 0.0.

c) A basket of same-typed books costs the respective multiple of the single price (no discount).


002: Simple, one-dimensional discounts

a) For any set of zero to five different-typed books, discount is given according to the above rule.


003: Complex, multi-dimensional discounts

a) If there can be multiple different combinations from a given basket, then the cheapest possible

    price is applied.

This is taken from my solution of the KataPotter Code Kata (see my last post), and quickly summarizes the rules for price calculation, that have to be implemented.

With Gallio/MbUnit 3.1, such a quick text document can be easily incorporated into a test report from a test fixtures FixtureSetUp method:


public class PriceCalculationFixture



    public void FixtureSetUp()


        Stream stream = Assembly.GetExecutingAssembly()

                                .GetManifestResourceStream(this.GetType(), "KataPotter-Specs.txt");

        if (stream != null)


            StreamReader reader = new StreamReader(stream);

            TestLog.EmbedPlainText("List of Specifications", reader.ReadToEnd());



        stream = Assembly.GetExecutingAssembly()

                         .GetManifestResourceStream(this.GetType(), "Testcases.xml");

        if (stream != null)


            StreamReader reader = new StreamReader(stream);

            TestLog.EmbedXml("Test cases for price calculation (xml)", reader.ReadToEnd());





This code assumes, that the files (there's also an xml file with test data) are embedded resources of the test assembly - File.ReadAllText(path) would be an alternate solution for 'normal' text files. The resulting test report will have the files included as attachments:







Then you can apply references to your embedded document on an individual test method via MbUnit's MetaData attribute:

[Test, Metadata("Specification", "002.a")]

[Description("Asserts that the price for a number of books (each one " +

             "of a different type) is calculated as expected.")]

[SequentialNumbers(Start = 0, End = 5, Step = 1)]

public void CalculatePriceForABasketOfDifferentBooks(int numberOfBooks)



This will show up in the test report as follows:


Nice, and not much work...

All in all, I'd say that the here shown method can increase the expressiveness and intelligibility of a test report without much effort.


delicious facebook digg reddit linkedin stumbleupon technorati mrwong yahoo google-48x48 twitter email favorites
Posted on Thursday, November 12, 2009 3:23 AM Unit Testing/TDD , Project Management | Back to top

Comments on this post: Including ad-hoc specifications in your test report

No comments posted yet.
Your comment:
 (will show your gravatar)

Copyright © Thomas Weller | Powered by: