Click here to Skip to main content
15,892,674 members
Articles / Programming Languages / C#

User Story Source Code Layout with MSpec

Rate me:
Please Sign up or sign in to vote.
3.36/5 (4 votes)
14 Feb 2010Ms-PL2 min read 30.3K   11   7
An example showing a source code structure that reflects user stories using MSpec.

Introduction

With this article, I am demonstrating a certain source code structure for behavior-driven development (BDD) compatible with many testing frameworks.

One advantage of this style is how it integrates with source code viewing tools such as Solution Explorer and ReSharper (R#). Another is that the tests are very easy to read and understand, even for less-technical people.

For my example, I will use Machine Specifications (MSpec) because I prefer that framework's syntax.

Background

This article is intended for people with some familiarity with BDD. Wikipedia's article on the topic is here and the BDD wiki sits here. Another link that some readers may find helpful is the one I have included on MSpec. A tutorial for wiring R# and MSpec together can be found here.

Using the Code

The code is divided into two projects: Banking (the main project) and Banking.Behavior (the test project).

What I am showing here is the source that mirrors a user story: As a\[Role]\I Want\[Feature]\so that\[Benefit]:

Banking.Behavior\As an\account holder\I want\to transfer 
   money from my savings account\so that\I can get cash easily from an ATM

Typically, a single user story is comprised of many scenarios. Therefore, the source structure mirrors this fact as well: As a\[Role]\I Want\[Feature]\When\[Scenarios]:

Banking.Behavior\As an\account holder\I want\to transfer money 
  from my savings account\When\I_transfer_an_amount_less_than_my_savings_account_balance.cs

Each scenario has one-to-many assertions, which sit inside the associated scenario file:

C#
using Banking;
using Machine.Specifications;
using NUnit.Framework;

namespace When
{
    public class I_transfer_an_amount_less_than_my_savings_account_balance
    {
        static Account _savings;
        static Account _checking;

        Because of = () =>
        {
            _savings = new Account(100);
            _checking = new Account(10);
            new Bank().Transfer(_savings, _checking, 20);
        };

        It should_subtract_the_amount_from_my_savings_account_balance = () =>
            Assert.That(_savings.Balance, Is.EqualTo(80));

        It should_add_the_amount_to_my_checking_account_balance = () =>
            Assert.That(_checking.Balance, Is.EqualTo(30));
    }
}

The scenario here is I_transfer_an_amount_less_than_my_savings_account_balance, and the assertions are should_subtract_the_amount_from_my_savings_account_balance and should_add_the_amount_to_my_checking_account_balance. Notice that I have placed this class inside the When namespace. This provides clarity when viewing the source code from a test runner.

I use ReSharper (R#) for my test runner. Here is the view from R#'s 'Unit Test Explorer' with the 'Projects and Namespaces' option:

unit-test-explorer.jpg

Here is the view from R#'s Unit Test Sessions with the 'Projects Structure' option:

unit-test-sessions.jpg

Here is the view from Solution Explorer:

solution-explorer.jpg

Note: to run the example project, you will need to include the Machine.Specifications, Machine.Specifications.NUnit, and the NUnit.Framework DLLs yourself. I did not include these DLLs because of potential licensing conflicts between Coderoject.com and those products. The MSpec source can be found here (you have to build it yourself), and the NUnit downloads can be found here.

Points of Interest

This source code structure is portable to many other testing frameworks, such as pure NUnit. In the case of pure NUnit, we would port the It delegates to [Test]-decorated methods, the Because delegates to [SetUp]-decorated methods, and add the [TestFixture] attribute to each test class.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 4 Pin
Bardy8523-Mar-11 20:42
Bardy8523-Mar-11 20:42 
GeneralProject structure, NUnit Pin
User 24213614-Feb-10 13:48
User 24213614-Feb-10 13:48 
This is actually an interesting project structure you describe here. One problem I see with it is that you encode a lot of information about the story in the directory structure, namespaces and files that are not picked up by MSpec. Keep in mind that namespace information and the "so that" folder will never be considered by MSpec and thus will not be available in the HTML report that the console runner produces. The only place these are available are the ReSharper runner and the Solution Explorer.

Encoding user stories in such a way might work well for the example like the one you talk about in your post. Consider the situation of a customer project with hundreds or thousands of stories. From my experience I think it will become unwiedly quickly. A while ago I also practiced "one cs file per context" and have found it to become a file management nightmare quickly. Today, I usually have one BankingSpecs.cs file with all banking-related contexts ("test classes") in that one file. This makes understanding and navigating contexts easier by keeping those things together that naturally belong to each other. MSpec has a sample project that shows that structure.

On another note, MSpec removed the NUnit assertion library a while ago and now has its own assertion library that does not require NUnit nor xUnit (the two assertion libraries you could choose from previously).

The latest version of MSpec can be either found at GitHub (source code)[^] or on the CodeBetter TeamCity instance (binaries)[^].

modified 13-Feb-22 21:01pm.

GeneralRe: Project structure, NUnit [modified] Pin
erik.f15-Feb-10 5:18
erik.f15-Feb-10 5:18 
QuestionWhat is MSpec and why should I care about it? Pin
#realJSOP14-Feb-10 11:26
mve#realJSOP14-Feb-10 11:26 
AnswerRe: What is MSpec and why should I care about it? Pin
erik.f14-Feb-10 12:04
erik.f14-Feb-10 12:04 
GeneralCorrect MSpec link Pin
erik.f14-Feb-10 8:02
erik.f14-Feb-10 8:02 
GeneralRe: Correct MSpec link Pin
erik.f15-Feb-10 5:22
erik.f15-Feb-10 5:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.