Updates to NBehave

What happened to NSpec?

I am not sure if all of you know but the NBehave project consolidated with the NSpec project a while back, since then we have been pretty silent about what we are doing because we wanted to give the community something they could simply drop in and not be to evasive in its implementation. Meaning we didn’t want you to have to learn how to use yet another runner.

What we decided is that NSpec did a lot of cool things but at its heart was an assertion engine. We contemplated if we really wanted to go down the path of creating a whole new assertion engine. This is where Andrew Stopford’s and Jeff Brown’s MbUnit 3.0 Gallio engine come in.

 

“The Gallio platform is an open, extensible, and neutral system that provides a common object model, runtime services and tools (such as test runners) that may be leveraged by any number of test frameworks. In this vision of the world, MbUnit v3 itself is simply another test framework plugin with the same status as any other.”

NBehave will utilize the Gallio extensible test framework and employ as many of the BDD idioms as we can manage to squeeze in.

This will enable us to offer:

  • To use any of the 7 current Gallio test runners, including console, GUI, MSBuild, NAnt, PowerShell, ReSharper and TD.Net plus any new ones that are developed.
  • CCNet integration and most anything else that’s built around Gallio
  • NBehave with Gallio as a bundle.

Pretty cool right? Well as you can imagine this has been ongoing trial an error but the good part is we are working with the Gallio dudes to get something out there.

So does that mean I have to wait to use BDD then? No…

We wanted to give you all something now.

One of the more important constructs of BDD is that we are now specifying how our code should behave under a governed context. Whether that context is story governed or system governed is particular to the situation that is eliciting the invocation. Laymen response it is not just about stories and acceptance testing.

BDD is about creating a reentrant code base that can be understood by development teams working together to create great software. You should be able to perform a cursory glance at you specifications and understand intentions and expected behavior. The difficult part is that this is going to require the same type of self discipline that TDD fostered.

So how do you take advantage of this now?

Well the current repository on Google Code has several features that we think the community can take advantage of now. Thanks go out to David Laribee and JP Boodhoo for the help with the base spec fixture.

Here is a list of some of the features we have completed and are working towards.

  • · NUnitSpecBase – Done
  • · MbUnitSpecBase – Done
  • · NUnit assertion extensions – Done
  • · MbUnit assertion extensions – Done
  • · Automocking Container – Done
  • · Create MSTest assertion extensions (April 1st)
  • · Create xUnit assertion extensions (April 1st)
  • · TestDriven.NET integration (April 1st)
  • · XML output for stories (April 1st)
  • · XSLT for XML story runner output (April 1st)

So how do I use these new features?

  • 1. Download the latest trunk from Google Code or wait till April 1st for the official build
  • 2. Execute the go.bat
  • 3. Now create a new project and reference the following dll’s from the build folder (this is assuming you are using NUnit)
    • a. Castle.Core
    • b. Castle.DynamicProxy
    • c. Castle.DynamicProxy2
    • d. Castle.MicroKernal
    • e. Castle.Windsor
    • f. NBehave.Spec.Framework
    • g. NBehave.Spec.NUnit
    • h. NUnit.Framework
    • i. Rhino.Mocks
    • j. …The kitchen sink!

As you can see there are a lot of dependencies but for the most part they are everything you would need to have the optimal BDD experience.

At this point I am really jealous of Gem! :-)

Here is how you would setup a basic specification fixture.

Pseudo DSL:

these specs are concerning this [Type]
    when this [type] is in this [context]
        then [specify] that it [should behave] this way

The first thing is to setup the using aliases.

using Context = NUnit.Framework.TestFixtureAttribute;
using Specification = NUnit.Framework.TestAttribute;
using Concerning = NUnit.Framework.CategoryAttribute;

Then use the namespace to define the concerning type:

namespace MathFlash.Core.EquationGenerator_Specs

In the case above the specs in this file are going to be concerning EquationGenerator_Specs.

Now let’s define our first context.

[Context, Concerning("EquationGenerator")]
public class When_initializing_the_EquationGenerator_with_one_and_five : NUnitSpecBase

As you can see we have defined a class decorated with a Context attribute and a Concerning attribute. We have also inherited from the NUnitSpecBase. The name of the class is defining the context that will govern the expected behavior that we will assert on later.

Next we will define our first specification.

[Specification]
public void Should_generate_equations_where_the_left_hand_side_is_greater_than_or_equal_to_the_lower_bound()

So you have defined a context and specified expected behavior. What is so important about the NUnitSpecBase. Well for one it abstracts the use of the automocking container (I will have a post on that in the next couple of days). It also has several new method conventions that have their roots in rSpec.

protected override void Before_each_spec()

This method will be called before_each_spec similar to the SetUpAttribute.

protected override void After_each_spec()

This method will be called after_each_spec similar to the TearDownAttribute.

Last but not least are the NUnit extension methods. You have two options. You can use the standard CamelCase notation or you can use to more readable underscore notation. For example:

equation.LeftHandSide.ShouldBeGreaterThanOrEqualTo(_lowerBound);

or

equation.LeftHandSide.should_be_greater_than_or_equal_to(_lowerBound);

Why did we give you both? Because we just couldn’t decide on which one to use just yet. I am sure in the end we will decide on one but for now you will have both options. If anything it gets you ready for rSpec once IronRuby is baked!

This is only the beginning. We have a lot more planned for future releases and Gallio will open the door for even more exciting possibilities.

For reference here are all the specs.

using System.Collections.Generic;
using MathFlash.Core.Domain;
using NBehave.Spec.NUnit;
using Context = NUnit.Framework.TestFixtureAttribute;
using Specification = NUnit.Framework.TestAttribute;

namespace MathFlash.Core.EquationGenerator_Specs
{
    [Context]
    public class When_initializing_the_EquationGenerator_with_one_and_five : NUnitSpecBase
    {
        private EquationGenerator _generator;
        private int _lowerBound = 1;
        private int _upperBound = 5;

        protected override void Before_each_spec()
        {
            _generator = new EquationGenerator(_lowerBound, _upperBound);
        }

        [Specification]
        public void Should_generate_equations_where_the_left_hand_side_is_greater_than_or_equal_to_the_lower_bound()
        {
            foreach (var equation in _generator.GenerateEquations())
            {
                equation.LeftHandSide.should_be_greater_than_or_equal_to(_lowerBound);
            }
        }

        [Specification]
        public void Should_generate_equations_where_the_left_hand_side_is_less_than_or_equal_to_the_upper_bound()
        {
            foreach (var equation in _generator.GenerateEquations())
            {
                equation.LeftHandSide.should_be_less_than_or_equal_to(_upperBound);
            }
        }

        [Specification]
        public void Should_generate_equations_where_the_right_hand_side_is_greater_than_or_equal_to_the_lower_bound()
        {
            foreach (var equation in _generator.GenerateEquations())
            {
                equation.RightHandSide.should_be_greater_than_or_equal_to(_lowerBound);
            }
        }

        [Specification]
        public void Should_generate_equations_where_the_right_hand_side_is_less_than_or_equal_to_the_upper_bound()
        {
            foreach (var equation in _generator.GenerateEquations())
            {
                equation.RightHandSide.should_be_less_than_or_equal_to(_upperBound);
            }
        }

        [Specification]
        public void Should_generate_twenty_five_equations()
        {
            var equations = _generator.GenerateEquations();

            equations.Count.should_equal(25);
        }
    }
}

Related Articles:

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

About Joe Ocampo

My personal philosophy is simple: "Have a good strategy that sets the environment for success through the enablement of the whole. Be agile but with a mind towards pragmatism. Delegate to the best qualified individuals, but don’t be afraid to involve yourself in all parts of a job. Treat everyone with respect, humility, and with a genuine pursuit towards excellence." Respected business and technical leader with expertise in directing organization towards effective results driven outcomes. Proven ability to perform and communicate from both technical and business perspectives. Strong technical and business acumen developed through experience, education and training. Provides the ability to utilize technology, harness business intelligence and execute strategically by optimizing systems, tools and process. Passionate about building people, companies and software by containing cost, maximizing operational throughput and capitalize on revenue. Looks to leverage the strengths of individuals and grow the organization to their maximum potential by harnessing the power of their collective whole and deliver results. Co-Founder of LosTechies.com
This entry was posted in BDD (Behavior Driven Development). Bookmark the permalink. Follow any comments here with the RSS feed for this post.

18 Responses to Updates to NBehave

  1. What do you think of an alternative approach to Concerns – nested classes with [Concern] attribute:

    [Concern]
    public class MvcContextSpecificationConcern
    {
    [Context]
    public class When_MvcContextSpecification_MvcMockedHttpContext_to_mock_context : MvcContextSpecification
    {

    I use it personally for a couple of months and it works ok… Concern in that case is a part of attributes aliases on top (I am not sure if I’ve shown you that part over email?) – it feels much more natural and clearer for me personally?

    using Concern = NUnit.Framework.TestFixtureAttribute;
    using Context = NUnit.Framework.TestFixtureAttribute;
    using Observation = NUnit.Framework.TestAttribute;
    using Specification = NUnit.Framework.TestAttribute;

    Also, I would use Specification only when specifying the behavior (interaction) of a given code piece. If I were specifying the end result (state – because sometimes it’s not possible to specify interactions, or when you really want to also confirm the result of an operation). In other cases I would use Observation attribute instead of Specification, as we are actually observing the result.

    [Observation]
    public void The_mocked_instance_of_HttpContext_should_be_available()
    {
    _context.ShouldNotBeNull();
    }

    What do you think?


    Vladan

  2. Colin Jack says:

    @Vladan
    I like your idea of seperating observations from specifications.

    I am not convinced on the natural superiority of interaction testing so although I’m trying very mock based BDD (focussing on its effect on design) I’ve also being doing a lot of state based specifications. I’ve found these are actually very useful so I plan to continue with it.

    Having said that since the two types of specifications serve different purporses I think decorating them differently would be a good idea.

    @AgileJoe
    Good stuff, looks like things are progressing. Are you guys planning to do some more blogging about BDD, because I’ve found all your posts up to now very useful.

  3. To be honest, it’s not my idea… I’ve seen it somewhere from Scott Bellware (not sure if it was a blog post or something because his blog is no longer available)… but I’ve used it ever since, and for the similar reasons as you I’ve liked it allot (helps me be more expressive in my intents)


    Vladan

  4. Colin Jack says:

    @Vladan
    Out of interest how do you end up doing BDD tests, as in when you start specifying a high level piece of work would you kick off with an interaction test or a state based one that will act as an acceptance test or both?

    I’m interested to know how others are working.

  5. Personally I am in a similar boat as you… I’ve started only a couple of months ago and only on a pet project (thin glue framework to connect asp.net mvc + nhibernate + bdd with the practices I’ve thougth of as good over the past few years) so I’ve only done parts spec-first, and other spec-later (mostly because if I’ve third party code… like extending mvc controller I couldn’t flush my intent as interaction)

    That said… when I can I start with high level specs and add details to them (or as fellow specs) as I feel is appropriate (e.g. my currently active part of this is NHibernate integration based on Ayende’s Rhino Commons for NH for which I am following the idea set forth by Ayende, only writting them spec-first to flush out a tad-bit different design… I figure I will be much richer in experience with BDD after this part because it integrates over a couple of things and ideas).

    For me a good sample on BDD is Xeva framework from David Larabee:
    http://code.google.com/p/xeva/

  6. Colin Jack says:

    @Vladan
    Ta, I’ll give it a look.

    @AgileJoe
    I’m using TFS for testing and it doesn’t pick up the tests unless they are specifically marked with TestMethodAttribute (in 2005 at least).

  7. Jimmy Bogard says:

    @Colin

    This is a known issue with TFS 2005. TFS 2008 may have fixed this.

    In the meantime, using aliases might help.

  8. Colin Jack says:

    @bogardj
    I don’t have 2008 but as you say it may have been fixed, looks like I’ll need to get it to look at the NBehave source code though.

    The aliases didn’t seem to fix it but I’ll try giving it another shot.

  9. Jeremy Gray says:

    This is a small point, but nonetheless: Between underscores and CamelCase, I hope you settle on CamelCase so that code using NBehave need not violate .net framework design guidelines on member naming (which underscores violate.)

    It is all well and good to learn and borrow from other frameworks, other languages, other platforms, etc. but one still needs to keep in mind the rules, guidelines, and conventions of the target framework/language/platform/etc.

  10. Joe Ocampo says:

    @vladen

    >What do you think of an alternative approach to Concerns – nested classes with [Concern] attribute:

    I had a feeling you were going to ask this question. The ONLY reason why I have elected not to format it this was is because some of the runners have an issue with nest TestFixtures. As we move towards Gallio this is something I will really be pursuing. If not for anything else then to make it more akin to rSpec. Example:

    require ‘user’

    describe User do

    before(:each) do
    @user = User.new
    end

    context “(adding assigned role)” do
    before(:each) do
    @user.assign_role(“Manager”)
    end

    specify “should be in any roles assigned to it” do
    @user.should be_in_role(“Manager”)
    end

    specify “should not be in any role not assigned to it” do
    @user.should_not be_in_role(“unassigned role”)
    end
    end

    context “(adding assigned group)” do

    end
    end

  11. @Joe

    Sounds great! Thnx!
    It’s a struggle worth fighting, I am glad your not giving up on it (even for Resharper working better as JP mentioned :) ).

    What do you think about [Observation]?


    Vladan

  12. Joe Ocampo says:

    @ Jeremy Gray

    I just started a discussion thread on the AltDotNet yahoo group about this very subject.

  13. Joe Ocampo says:

    @Vladan

    I think it is a matter of semantics.

    Write it out in a sentence format:

    These specifications are observing this type

    vs

    These specifications are concerning this type

    the ladder is more appropriate to me as it conveys importance and something of iterest more so then simply observing.

    Although this could simply be an English thing.

    I have asked the Gallio crew if we can substitute alias in for attributes. Jeff mentioned this shouldn’t be a problem. So we could both be right in the end.

  14. @Joe,

    I agree about the semantics.

    However (not that I am trying to convince you :) ) it’s the feeling that I like about making a distinction between a spec. and an observation.

    And I would rather put it:

    These specifications are concerning this type
    vs.
    These observations are concerning this type

    because they are both part of the (sometimes) same concern, only differ by their intent… with the first we specify how SUT should behave, with the second we observe what that (or other) behavior should do (or result to) – which is equaly important in some scenarios.

    Anyway… I am very happy Gallio will support it. It trully will be a great engine to work with (now if only TDD.NET would comply as well :) )


    Vladan

  15. So April 1st still on for the official build?

    Let me know if poss!
    david (at) electrichornet (dot) com

  16. Carlos says:

    A couple question I would really appreciate someone can answer me:

    1) Where can I found NBehave documentation?
    2) What are the requirements (HD, OS, .NET version, VS version etc.) in order to instal NBehave?

  17. Joe
    Hi i hope you dont mind but we have written a tiny abstraction layer on nbehave to allow us to seperate the functional implementations form the descriptive a little like cucumber .

    Any way it can be found here
    http://neilmartinagile.wordpress.com/2009/04/14/a-variation-on-nbehave-story/
    regards
    Neil Martin
    &
    Ronnie Barker

  18. dnjommedf says:

    C4kiBI cvjyhxpffohl, [url=http://aodxulbakvir.com/]aodxulbakvir[/url], [link=http://bauqpxakurpa.com/]bauqpxakurpa[/link], http://vzuhrttahygo.com/