Introducing SpecMaker “Rspec style” BDD in C#

So I’m certain this will be met with mixed response, because really .Net already has several decent BDD frameworks and many of you will chastise me for adding yet another framework when really BDD has nothing to do with what testing framework you use.  So why you ask?

  1. Most of the BDD frameworks I’ve looked at are Acceptance style and trying to make stories into executable code (NBehave, StoryTeller, Fitnesse.Net ,Acceptance, etc).  I want something that describes to other developers in a behavior centric way what my code is doing (like RSpec’s default DSL does).  This is not aimed at business analysts.
  2. The other RSpec style framework for C# I’ve played with while very nice, did not go over well with people I’ve tried to introduce to BDD.
  3. Using NUnit in a context BDD style is normally what I do but produces a lot of artifacts, is underscore heaven and provides no guidance to newer practitioners of BDD.

With all this in mind how does SpecMaker improve our situation at all?  First lets look at how I might approach a BDD test with NUnit

   [TestFixture]
    public class SpecGameWhenStartingUp
    {
      
        private Game _game;
        private void startGame(){
           // left out for clarity
        }
        [SetUp]
        public override void SetUp()
        {
           startGame();            
        }
        [Test]
        public void should_have_3_lives()
        {
           Assert.AreEqual(3, _game.lives);
        }
     }

On the surface there isn’t much wrong with this. Asserts are less than ideal (Rspec matchers would be nice), underscores on my “should_” are so so, context in the class name leads to lots of classes and me playing around a bunch with inheritance. However, none of this is a game breaker and for those of you who have a good workable flow with this approach and are happy with it, please continue to use it. I however, am not happy with the flow, also BDD really is not easy for me to teach. Some of you may get it easily and teach it easily, but .Net developers as a whole seem to be driven towards framework specific knowledge (telling them to not think “test” when test is staring at them on the method messes with their heads), and even then it’d better not be too “cutting edge” in language features or friction becomes a risk where someone may end up learning more than just BDD.

So what are my goals then for SpecMaker?

  1. It has to be terse, and be shorter than the NUnit approach.
  2. Eliminate underscores where possible.
  3. Act as a series of guidelines to beginning BDD’ers.
  4. Output spec results in a variety of formats.
  5. Remove the “Test” entirely from the vocabulary.
  6. Use convention over configuration where possible.
  7. Provide custom matchers and a DSL to make your own custom matchers.

What will it not do or be?

  1. Do acceptance testing. This could change in the future, but then I’d be inclined to borrow code from others that do this well already.
  2. Make BDD a “click next” thing. There is no substitute for continually trying to refine your approach and understand “behavior” and what that means. I’m not sure there is one true right answer here and that makes it so incredibly hard to make a framework that does that.
  3. Be as nice as RSpec.
  4. Integration tests. This is setup very much one-to-one. Again this was a simplicity choice and as I dog food this I may completely change my mind here.

So with all the ceremony out of the way here is where I’m at so far for the same BDD code above only with SpecMaker

 public class GameSpec : BaseSpec
    {
        private void startGame(){
          //left out for clarity
        }  
        public void when_starting_a_game()
        {
            startGame();
            should(“have 3 lives”, ()=>
                    {
                       _game.lives.Has(3).Total();
                    }
                );
            should(“require valid username”, RuleIs.Pending);
        }
     }

Running specmaker.exe on the the dll where this spec is located outputs something like this:

Picture 2

 

 

At this time specs come from the class name minus “Spec” at the end. Context start with “when” or the method will not get picked up as context.  This is also staggeringly new and may have bugs, issues, bad docs, ugly code, etc. But since I’ve moved this to Github I encourage everyone to have a go and improve it as they see fit or for their own purposes.  I have a number of plans and ideas to improve this, but I feel this is a good start to get some positive work done and save myself some grief over my NUnit based tests.

Let me know what you think, any and all criticism is appreciated, but at the end of the day this does actually fulfill an itch that I myself have had for some time.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Ryan Svihla

I consider myself a full stack polyglot, and I have been writing a lot of JS and Ruby as of late. Currently, I'm a solutions architect at DataStax
This entry was posted in BDD, C#, Context, Spec, SpecMaker. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Colin Ramsay

    It’s quite bracket-heavy on your first “should” example. You refer to rspec but one thing I enjoy about that is the lack of noise in the specs, I quite like the syntax of MSpec in .NET land in that respect, because even though it’s got a lot of underscores it still manages to look clean.

    I definitely think testing in .NET is a bit painful so any action in this field is positive as far as I’m concerned, keep it up Ryan.

  • http://www.lostechies.com/members/rssvihla/default.aspx Ryan Svihla

    @colin
    Thanks I appreciate the feedback. As to the brackets, yes I feel the same pain. I do think MSpec is very nice and is a clever solution. I’m hoping at least this is easier to teach other developers BDD with, and time will tell.

    I have seriously considered changing the recommended style to closer to the second should. There is no reason you cant just churn out a few test methods with a void signature to remove the bracket heaviness.

  • Eyston

    “RSpec in C#” seems to be the goal for spec style tests but isn’t one of the nice things about the CLR is you don’t have to use C# for everything? I have never done .NET programming in other than VB or C#, so I have no idea what the friction would be, but I’m curious if one of the more dynamic CLR languages could be used for testing C# code.

    I guess your goal is to keep things simple so you can focus on what you need to teach, so maybe a new language for tests wouldn’t be helpful.

  • http://kyle.baley.org Kyle Baley

    Have you looked at JP Boodhoo’s BDD framework? It has a similar kind of syntax with helper methods as well (though tied to MbUnit). It also has a spec generator that dumps everything into pretty report. You might get some ideas from it.

  • http://twitter.com/pseale Peter

    If nothing else, please look into the anyObject.Should******() extension methods the other frameworks are using…if you can adopt the same extension method library the rest of them use, it’s one less thing for us to memorize.

    So your assertion would change to be
    _game.lives.ShouldEqual(3);

  • http://www.lostechies.com/members/rssvihla/default.aspx Ryan Svihla

    @Kyle, I had not checked out JP’s BDD framework, I’m certain he has more than a few cool little tidbits in there.

    @Eyston Tooling, and uptake with other developers. Boo is a gorgeous .Net language well suited for building DSL’s and what I’d prefer, but the following make that a non-starter:

    For me from a productivity standpoint I lose easy refactoring with Resharper (this is a big time win), and that alone would slow down my BDD flow quite a bit. If i wrote my own generators and regex based renaming (I like to try that out someday) I could make this a non-issue, but not today.

    Finally, try getting your average junior developer who may not even have a great grasp of C# to learn Boo and you’ll quickly see there is a big “cost” to going that route. BDD is hard enough to teach without actively tossing extra barriers in front of it. Granted I’d get a much much nicer syntax with other languages, I am a bit held back by the realities of a lot of .Net developers reliance on Visual Studio, intellisense and “framework based” learning.

    Thanks again everyone for the feedback I really appreciate you all taking the time.

  • http://www.lostechies.com/members/rssvihla/default.aspx Ryan Svihla

    @Peter I actually had those initially, I actually decided right before this post I don’t like having “chain shoulds” like you have in RSpec. If you read your example out loud you have should twice, and while that’s a small semantic difference again I found it a pain point when teaching people bdd, especially for those that English was not their first language.

    Now that said, there are two important things you should know.

    1) You do not have to use those matchers at all, they are totally 100% optional. Just throwing any exception will fail the test (it’ll show status of error), so you can use NUnit asserts, other peoples extensions or really hand code to generate your desired effect.

    2)I know not everyone sees things the way i do (which is a good thing), so I’m working right now on a DSL , and an base class to create your own matchers. RSpec has the same thing so that people can create their specific matchers for each project instead of just having line after line in their specs violating dry.

  • http://www.lostechies.com/members/rssvihla/default.aspx Ryan Svihla

    @Peter also i forgot to mention.
    This stuff is all on github and very easy for you to fork and create your own suggested “view” of this. If enough people prefer your approach or your work I’ll pull it back in and add it to my branch, and I’ll definitely appreciate the help.

    Thanks again for the commentary.

  • Eyston

    Yah, I googled on Boo right after my post. I had just watched Ayende’s Boo and DSL video from NDC and figured Spec tests sound like a good DSL case. Not a whole lot showed up so it seems to be build yourself right now.

    Just googled on IronRuby and RSpec and this came up: http://msdn.microsoft.com/en-us/magazine/dd434651.aspx

    Haven’t read it yet, but I’m surprised I haven’t seen more blog posts about this if it works well.

    I like seeing posts about other people doing BDD. Its something I feel comfortable with but have yet to have that ‘click’ of understanding.

  • http://programmergrrl.blogspot.com Amy Thorne

    I just thought I’d throw in my _very_ slight knowledge about IronRuby and RSpec. A few of us tried getting this working at the last London Open Space Coding Day, http://openspacecode.com/, and at least one of us was successful. Here’s a link to where I blogged about it, though I was mostly focusing on Cucumber, so my blog post isn’t all that helpful, http://programmergrrl.blogspot.com/2009/08/open-space-coding-day-notes-tdd-as-if.html.

    But as interesting as that is, I’m all for more BDD options that use C# and NUnit, since those are what my current team has standardized on, and sometimes it can be tough to shift a whole team onto another language for writing tests or to using a different testing framework.

  • http://www.lostechies.com/members/agilejoe/default.aspx Joe Ocampo

    This is more like Shoulda than RSpec :-)

    Can’t we all just get along?

  • http://www.lostechies.com/members/rssvihla/default.aspx Ryan Svihla

    @joe
    /me shakes fist

    yes and its shaping to be more like shoulda the more I work with it. I will have to strangle both you and Jason later for infecting my brain with such concepts.

  • http://www.highoncoding.com Mohammad Azam

    Hi,

    I have been implementing unit test BDD style using underscores. Although I do not mind that approach but I am always in search for a simpler solution. To be clear BDD is not only about how to name our test methods. Anyway, that is another discussion.

    I recently wrote few unit tests bdd style using IronSpec framework which is part of IronRuby. I was amazed how simple BDD test became when implemented in IronSpec. Here is a link to my article which describe the approach. Scroll down to the bottom to see the updated code.

    http://highoncoding.com/Articles/585_Unit_Testing_CLR_Assembly_Using_IronRuby_with_Spec.aspx