Jan 1 2012

Status Update on SpecsFor.Mvc

Category: SpecsFor | TestingMatt @ 15:04

Well, I missed my goal of having the 1.0 version of SpecsFor.Mvc available by the end of 2011, but it was not for lack of trying.  I’ve been dog-fooding it on a mobile web app (my first), and that’s resulted in a number of changes and improvements.  I’m quite pleased with how things are shaping up, but I’d like some feedback from someone who isn’t me on the changes.

More...

Tags:

Dec 11 2011

SpecsFor.com Launched, SpecsFor 2.2 Released!

Category: SpecsFor | TestingMatt @ 14:25

The last month has been a busy one for SpecsFor.  I’ve added numerous new features to accommodate additional testing styles and to simplify testing challenges.  I’ve also been hard at work on a real site and some docs for SpecsFor.  I’m pleased to announce that SpecsFor.com is now live.  I’ve also shipped a new version of SpecsFor that simplifies the painful task of creating multiple mocks of the same type for injection into IEnumerable parameters.

More...

Tags:

Nov 27 2011

SpecsFor.Mvc – Acceptance Testing Without Magic Strings

Category: SpecsFor | TestingMatt @ 05:56

Today I published the first preview release of the next member of the SpecsFor family: SpecsFor.Mvc!  SpecsFor.Mvc is a stand-alone library designed to simplify and streamline the creation of acceptance tests for ASP.NET MVC applications.  Read on to find out how easy it is to start crafting automated acceptance tests with SpecsFor.Mvc today!

More...

Tags:

Nov 23 2011

SpecsFor 2.0 Released!

Category: SpecsFor | TestingMatt @ 15:52

Things have been quiet lately for my BDD framework, SpecsFor, but I have finally published version 2.0 to both Github and NuGet.  Read on to find out what’s changed.

More...

Tags:

Aug 25 2011

Data Access in Fail Tracker–Unit Testing

Category: SpecsFor | Testing | Fail TrackerMatt @ 14:15

In my last post, I described Fail Tracker’s simple repository model for abstracting LINQ to NHibernate, which is used for all data access in Fail Tracker.  One reason I chose to implement an abstraction around NHibernate’s ISession interface was to facilitate Test Driven Development, a practice that wasn’t really feasible given how LINQ to NHibernate is implemented as an unmockable extension method.  While the abstraction made data access mockable, it would still have been painful if it weren’t for a base SpecsFor context that handled all the heavy lifting. 

More...

Tags:

Jul 15 2011

Test-Driven Development Is Not Slower

Category: TestingMatt @ 11:53

Hello, my name is Matt Honeycutt, and I am addicted to Test Driven Development.  I’ve been “using” for about 5 years now.  It started out with a little innocent unit testing and Test Later Development, but I quickly found that the increased productivity caused by TDD to be too alluring, and I succumbed.  Now I’m using all the time.  I use at work.  I use at home.  I just can’t stop.  People don’t really understand the risks.  There’s this myth that TDD is slower, that it makes you less productive, but that’s so not true.  Read on, and I’ll help you understand why.

More...

Tags:

Feb 5 2011

SpecsFor Released!

Category: TestingMatt @ 15:08

It’s not the official 1.0 release yet, but I have just published the first (and hopefully only) preview version of SpecsFor.   You can download it right now from the CodePlex site. This release meets most of the goals I laid out in my last post on SpecsFor, and if no bugs are found, SpecsFor Version 1.0 will follow shortly.  Read on to find out more!

Main Features

SpecsFor is a Behavior-Driven Development style framework that puts developer productivity ahead of all other goals.  The current release features:

  • AutoMocking – Easily configure and verify behavior.
  • ReSharper Live Templates – Quickly create specs with only a few keystrokes.
  • Clean Separation of Test State – Encapsulate test setup and reuse it across as many specs as you like.
  • Run The Same Specs Multiple Times With Different Contexts – SpecsFor allows you to assert the same things are true given any number of contexts.
  • Mix And Match Contexts – Context can be combined and extended to support complex test setup without code duplication or excess noise in your specs.
  • Declarative Context – Context can be established in many ways, including by simply marking your spec class with a special attribute.
  • Works With Any NUnit Test Runner – No add-ins are needed, SpecsFor is fully compatible with all popular test runners including TestDriven.NET, Resharper, and TeamCity.

Show Me The Code!

As cool as the feature list is, the code is even cooler.  SpecsFor provides multiple ways for you to build out your specifications.  The primary and most flexible way is through attaching context to classes via attributes, like so:

[Given(typeof(TheCarIsNotRunning), typeof(TheCarIsParked))]
[Given(typeof(TheCarIsNotRunning))]
public class when_the_key_is_turned : SpecsFor<Car>
{
    public when_the_key_is_turned(Type[] context) : base(context){}

    protected override void When()
    {
        SUT.TurnKey();
    }

    [Test]
    public void then_it_starts_the_engine()
    {
        GetMockFor<IEngine>()
            .Verify(e => e.Start());
    }
}

In this example, the specs will be executed twice, once for the combined context of “TheCarIsNotRunning” and “TheCarIsParked”, then again with just “TheCarIsNotRunning” applied. 

If you don’t like attributes, you can opt for a more traditional means of establishing context.

public class when_the_key_is_turned_alternate_style : SpecsFor<Car>
{
    protected override void Given()
    {
        Given<TheCarIsNotRunning>();
        Given<TheCarIsParked>();

        base.Given();
    }

    protected override void When()
    {
        SUT.TurnKey();
    }

    [Test]
    public void then_it_starts_the_engine()
    {
        GetMockFor<IEngine>()
            .Verify(e => e.Start());
    }
}

Unfortunately this method of context specification does not support running the same spec multiple times with different contexts.

Let’s See It In Action!

The feature list is cool, the code is cooler, but seeing it in action is the best way to see what’s going on:

What’s next?

SpecsFor Version 1.0 will be released in the next few days.  It will be available as a downloadable binary as well as a NuGet package.  In the meantime, I’m still very interested in feedback on the project.  You can drop me a line via the comments below, or you can post on the CodePlex site.

Tags:

Jan 26 2011

Announcing SpecsFor: Yet Another BDD Framework For .NET!

Category: TestingMatt @ 15:40

There is no shortage of Test/Behavior-Driven Development frameworks for .NET.  You have SpecFlow, Machine.Specifications (MSpec), and even Cucumber.  While these frameworks have been around for a while, I felt they weren’t right for me for various reasons, so I created SpecsFor.  SpecsFor is a TDD/BDD framework that has been naturally cultivated from use on two projects, including one commercial app.  The first release of SpecsFor is in the works, but first, I need feedback on some changes I’m considering to the core API.

But why??

I have previously shown the SpecsFor test helpers that are used on RageFeed (the never-to-be-released social networking app I’m working on).  My goal with SpecsFor was to completely eliminate testing friction by creating a simple set of conventions and templates to enable rapid spec creation, and I feel that SpecsFor has actually come very close to realizing my zero-friction vision.  A variant of SpecsFor is also used at my day job, and I have recently found myself copy-pasting the core class into other projects that I work on.  This is not conducive to maintaining SpecsFor, and I feel it’s time it grew up and became a proper library. 

What is it?

SpecsFor is primarily a base test fixture that establishes a clean way of performing simple Behavior-Driven Development style tests while providing an auto-mocking container and other utilities to reduce common sources of testing friction.  It greatly simplifies common operations such as initializing the class under test, establishing context, and creating mock objects.  When combined with a library like Should, you can quickly create very readable specifications.

SpecsFor exposes overridable template methods corresponding to the various steps of the BDD process: to establish context (the Given), to perform an action (the When), and to verify outcomes (the Then).  For now, the official version is built on NUnit, StructureMap, and Moq, but it will be available for the IoC library and testing framework of your choice soon (I have already created versions of SpecsFor that operate on MS Test and Ninject).

SpecsFor also includes a small set of Resharper templates. These templates make it easy to create new specs and test cases.

SpecsFor Today

The main version of SpecsFor, as seen in RageFeed, works well with the testcase class per feature pattern. Since it’s not uncommon to want to reuse some test context across multiple fixtures, the Given logic is conventionally contained in abstract base classes.  The test fixtures themselves then inherit from the appropriate context, perform an action, and assert the results.  Here’s an example:

public class when_the_key_is_turned : given.the_car_is_not_running
{
    protected override void When()
    {
        SUT.TurnKey();
    }

    [Test]
    public void then_it_starts_the_engine()
    {
        GetMockFor<IEngine>()
            .Verify(e => e.Start());
    }
}

public static class given
{
    public abstract class the_car_is_not_running : SpecsFor<Car>
    {
        protected override void Given()
        {
            base.Given();

            GetMockFor<IEngine>()
                .Setup(e => e.Start())
                .Callback(() => Console.WriteLine("VRRRROOOOOOOM"));
        }
    }
}

While this works relatively well for most simple cases, it’s not without flaws.  It clearly violates the principle of “favor composition over inheritance.”  It often leads to fixtures that identical except for their base classes.  It is also difficult to combine contexts.  Indeed the only option for reusing and combining contexts is to use inheritance, like so:

public abstract class the_car_is_not_running : SpecsFor<Car>
{
    protected override void Given()
    {
        base.Given();

        GetMockFor<IEngine>()
            .Setup(e => e.Start())
            .Callback(() => Console.WriteLine("VRRRROOOOOOOM"));
    }
}

public abstract class the_car_is_parked : SpecsFor<Car>
{
    protected override void Given()
    {
        base.Given();

        GetMockFor<ITransmission>()
            .SetupProperty(t => t.Gear, "Park");
    }
}

public abstract class the_car_is_parked_and_not_running : the_car_is_not_running
{
    //DUPLICATED CODE!  YUCK!
    protected override void Given()
    {
        base.Given();

        GetMockFor<ITransmission>()
            .SetupProperty(t => t.Gear, "Park");
    }
}

Even this breaks down in cases where you need context from more than one chain of inheritance.  Unfortunately, complex inheritance relationships can be just as detrimental to maintaining test suites as to maintaining production code.

Towards A Better API

The first official release of SpecsFor will feature an improved model for specifying test cases.  I have several goals for the revised API in mind:

  • Context is a distinct entity and is established without using inheritance.
  • Context can be easily mixed and matched.
  • Attaching context to a test fixture should require minimal code noise (code that isn’t testing something).
  • A single fixture can be re-used with multiple contexts. 

The first three goals are “must haves” in my opinion.  The last is just a “nice to have,” but I hope that I can find an approach that will facilitate better reuse.  Right now, I have designed several candidate APIs that meet these goals with varying degrees of success.  All assume that context setup (the Given phase of BDD) is handled by a class separate from the test fixture itself.  Here are the contexts used in the example fixtures shown below:

public class TheCarIsRunning : IContext<Car>
{
    public void Initialize(ITestState<Car> state)
    {
        state.GetMockFor<IEngine>()
            .Setup(e => e.Start())
            .Throws(new InvalidOperationException());
    }
}

public class TheCarIsParked : IContext<Car>
{
    public void Initialize(ITestState<Car> state)
    {
        //TODO: Setup a mock transmission for the car. 
    }
}

Feedback Needed

Before I make a decision on which API to proceed forward with for the first public release of SpecsFor, I’d like to get some feedback from the .NET community.  Which of the candidate APIs do people prefer?  Are there other options I haven’t considered?  Pros or cons to one of the approaches that I overlooked?  Please take a few minutes, evaluate these samples, and let me know what you think.

Option 1 – Manually specify context

The first option is the easiest to implement as it’s not very far from how SpecsFor works today.  Instead of using base classes to establish the context, you would just specify which context class (or classes) to apply prior to test execution.

public class when_the_key_is_turned : SpecsFor<Car>
{
    private InvalidOperationException _exception;

    protected override void Given()
    {
        Given<TheCarIsRunning>();
        //Context could be combined by making multiple calls to Given<TContext>(). 
    }

    protected override void When()
    {
        _exception = Assert.Throws<InvalidOperationException>(() => SUT.TurnKey());
    }

    [Test]
    public void then_it_should_throw_exception()
    {
        _exception.ShouldNotBeNull();
    }
}

Pros: Simple to implement.  Very flexible.

Cons: Doesn’t read very well.  Adds some code bloat to the spec class. 

Option 2 – Attributes specify context

Instead of writing imperative code to establish the context for a spec, Option 2 would enable you to declare context by leveraging attributes.   Multiple Given attributes could be applied to a spec, which would trigger the spec to be re-run multiple times, once for each attribute (and therefore once for each context or combination there of).  Multiple contexts could be specified in a single Given attribute if you wanted to compose multiple contexts together.

[Given(typeof(TheCarIsRunning))]
[Given(typeof(TheCarIsParked), typeof(TheCarIsRunning))]
public class when_the_key_is_turned3 : SpecsFor<Car>
{
    private InvalidOperationException _exception;

    protected override void When()
    {
        _exception = Assert.Throws<InvalidOperationException>(() => SUT.TurnKey());
    }

    [Test]
    public void then_it_should_throw_exception()
    {
        _exception.ShouldNotBeNull();
    }
}

Pros: Reads well.  No clutter code inside the spec; concise way of specifying context.  Enables a single spec to be run multiple times with different contexts.

Cons: Run-time type validation for context types.  Probably not feasible without an NUnit add-in.

Option 3 – Marker Interfaces Specify Context

Simple marker interfaces would be used to specify context in Option 3 (note that ‘Given’ is actually an interface; the ‘I’ prefix was intentionally omitted to improve the readability of the code).  Contexts could be combined by implementing multiple ‘Given’ interfaces.

public class when_the_key_is_turned
    : SpecsFor<Car>, Given<TheCarIsRunning>, Given<TheCarIsParked>
{
    private InvalidOperationException _exception;

    protected override void When()
    {
        _exception = Assert.Throws<InvalidOperationException>(() => SUT.TurnKey());
    }

    [Test]
    public void then_it_should_throw_exception()
    {
        _exception.ShouldNotBeNull();
    }
}

Pros: Reads fairly well.  No clutter code inside the spec; concise way of specifying context.  

Cons: Run-time type validation for context types.  No way to run a single spec multiple times with different contexts.

Option 4 – Attributes Leveraging Existing NUnit Functionality

NUnit already has a way of running a test fixture multiple times with different parameters.  This capability could be leveraged in order to support specifying context using attributes without an NUnit add-in, but it would require that the spec class expose a constructor as in the following example:

[Given(typeof(TheCarIsRunning))]
[Given(typeof(TheCarIsParked), typeof(TheCarIsRunning))]
public class when_the_key_is_turned4 : SpecsFor<Car>
{
    private InvalidOperationException _exception;

    public when_the_key_is_turned4(params Type[] context)
        : base (context)
    {
    }

    protected override void When()
    {
        _exception = Assert.Throws<InvalidOperationException>(() => SUT.TurnKey());
    }

    [Test]
    public void then_it_should_throw_exception()
    {
        _exception.ShouldNotBeNull();
    }
}

Pros: Reads well.  Concise way of specifying context.   Enables a single spec to be run multiple times with different contexts. Fairly simple to implement.

Cons: Spec classes must remember to implement a public constructor that passes the contexts to the base class.  Run-time checking of context types. 

Final Remarks

SpecsFor is meant to be a Behavior Driven Development framework that puts developer comfort and productivity first.  It is built around the tools you are already accustomed to.  Unlike some other BDD frameworks that focus on bridging customer requirements and unit tests through wonky (that’s a technical term) binding of English to executable tests, SpecsFor is designed to make testing easier and more productive for the developer.  I would like to have the first public version out within a week, but I also want to be sure that the road SpecsFor settles on is the right road.  I don’t want to make breaking changes in future releases because of short-sighted decisions today.  To avoid that pitfall, I’d really appreciate your feedback.  Please take a moment and leave a comment below.  Let me know which options you like, which you hate, and feel free to share your own ideas about what the ideal BDD framework for .NET developers should look like.  Thanks!

Tags:

Sep 11 2010

The Right Way to Do Automocking with Ninject

Category: Moq | TestingMatt @ 13:07

While StructureMap is definitely my IoC container of choice, it’s not the only game in town.  At my new job, our existing project uses Ninject.   One of my first tasks at this new job was integrating my SpecsFor “framework” into the existing projects.  The original version of SpecsFor worked with StructureMap and leveraged its auto-mocking container.  While Ninject has an auto-mocking extension, ninject.moq, it is sorely lacking when compared to StructureMap’s offering.  In this post, I’ll show you how to modify it into a useful automocking container, and I’ll also show you how easily SpecsFor can be adapted to Ninject using this working container.

Fixing Ninject.Moq

Ninject’s auto-mocking extension project can be found on github.  Yes, you have to build it from source if you want to use it.  However, don’t bother: the existing approach to auto-mocking is flawed and doesn’t work.  Here’s a very simple test case to illustrate the problem:

[Test]
public void Kernel_returns_same_mock_instance_for_all_requests_for_that_type()
{
    var kernel = new MockingKernel();

    //This assert fails.
    Assert.AreSame(kernel.Get<IDummyService>(), kernel.Get<IDummyService>());
}

That’s right, the container returns a new mock every time, which makes it difficult to setup expectations to be injected into a class.  It also can’t create the class-under-test directly without jumping through some additional hoops.  You have to bind the class to itself, like so:

[Test]
public void Kernel_can_create_class_under_test()
{
    var kernel = new MockingKernel();
    //Why should I have to do this??
    kernel.Bind<DummyClass>().ToSelf();

    Assert.IsNotNull(kernel.Get<DummyClass>());
}

Fortunately, these problems are easy to fix, and in fact Derick Bailey has already fixed them in his port of ninject.moq to Rhino Mocks.  You can check out his code on github.

First, we need to eliminate the self-binding requirement for the class under test.  We can do that by adding a little extra logic to the MockingKernel’s HandleMissingBindingMethod:

protected override bool HandleMissingBinding(Type service)
{
    bool selfBindable = TypeIsSelfBindable(service);

    if (selfBindable)
    {
        Bind(service).ToSelf().InSingletonScope();
    }
    ...
}

If a type is self-bindable, we’re binding it to itself with singleton scope.  This means we’ll get the same instance of the class under test from our mocking kernel every time we request it until we call the kernel’s Reset method.

So, that eliminates the need for self-binding our class under test, but we still have the issue of the container returning brand new mocks every time we request one.  That’s because the container is using instance scope instead of singleton scope for the mocks.  Again, we can fix this by modifying the HanldeMissingBinding method, which should now look like this in its entirety:

protected override bool HandleMissingBinding(Type service)
{
    bool selfBindable = TypeIsSelfBindable(service);

    if (selfBindable)
    {
        Bind(service).ToSelf().InSingletonScope();
    }
    else
    {
        var binding = new Binding(service)
                          {
                              ProviderCallback = MockProvider.GetCreationCallback(),
                              ScopeCallback = ctx => Singleton,
                              IsImplicit = true
                          };

        AddBinding(binding);
    }


    return true;
}

With this change in place, both our test classes now pass!  You can check out this code on my ninject.moq fork on github.  I’ve submitted a pull-request, so hopefully the fixes will eventually be merged back into the main ninject.moq extension.

Using Ninject.Moq with SpecsFor<T>

With a working auto-mocking container in hand, all that remained was modifying SpecsFor to work with ninject.moq instead of StructureMap’s auto-mocking container.  I just swapped to the MockingKernel and explicitly created the class under test (StructureMap’s auto-mocking container creates the class under test for you automatically):

public abstract class SpecsFor<T> where T : class
{
    protected MockingKernel Mocker;

    protected T SUT { get; set; }

    /// <summary>
    /// Gets the mock for the specified type from the underlying container. 
    /// </summary>
    /// <typeparam name="TType"></typeparam>
    /// <returns></returns>
    protected Mock<TType> GetMockFor<TType>() where TType : class
    {
        return Mock.Get(Mocker.Get<TType>());
    }

    [TestInitialize]
    public virtual void SetupEachSpec()
    {
        InitializeClassUnderTest();

        Given();

        When();
    }

    protected virtual void InitializeClassUnderTest()
    {
        Mocker = new MockingKernel();

        ConfigureKernel(Mocker);

        SUT = Mocker.Get<T>();
    }

    protected virtual void ConfigureKernel(IKernel kernal)
    {
    }

    [TestCleanup]
    public virtual void TearDown()
    {
        Mocker.Reset();
        AfterEachSpec();
    }

    protected virtual void Given()
    {

    }

    protected virtual void AfterEachSpec()
    {

    }

    protected abstract void When();
}

Just to prove that it works, here’s the specs for SpecsFor (sadly using MS Test instead of NUnit.  Did you know there are people who actually use MS Test?  I didn’t either!) :)

public class SpecsForSpecs
{
    #region Dummy Classes

    public interface IDummyService
    {
        string GetSomeValue();
    }

    public class DummyClass
    {
        public IDummyService Service { get; set; }

        public DummyClass(IDummyService service)
        {
            Service = service;
        }
    }

    #endregion

    [TestClass]
    public class When_using_specs_for : given.the_default_state
    {
        protected override void When()
        {
            //Nothing to do
        }

        [TestMethod]
        public void Then_it_correctly_sets_up_the_class_under_test()
        {
            SUT.ShouldNotBeNull();
            SUT.Service.ShouldNotBeNull();
        }

        [TestMethod]
        public void Then_it_should_create_a_mock_service_for_the_dependency()
        {
            Mock.Get(SUT.Service).ShouldNotBeNull();
        }

        [TestMethod]
        public void Then_GetMock_should_always_return_the_same_mock()
        {
            GetMockFor<IDummyService>().ShouldBeSameAs(GetMockFor<IDummyService>());
        }
    }

    [TestClass]
    public class When_setting_up_expectations_on_a_mock : given.the_default_state
    {
        protected override void When()
        {
            GetMockFor<IDummyService>()
                .Setup(s => s.GetSomeValue()).Returns("I am a mocked result.");
        }
        
        [TestMethod]
        public void Then_the_expectations_are_called_when_the_mock_is_used()
        {
            SUT.Service.GetSomeValue().ShouldEqual("I am a mocked result.");
        }
    }

    public static class given
    {
        public abstract class the_default_state : SpecsFor<DummyClass>
        {
            
        }
    }
}

And there you have it!  A working Ninject auto-mocking container, and a version of SpecsFor that takes advantage of it.

On a related topic, I’m considering spinning SpecsFor into a lightweight library that can be easily reused.  Is there any interest in that?

Tags:

Jul 28 2010

Test-Driven Development – From Painful to (Near) Zero Friction

Category: .NET | TestingMatt @ 14:26

I don’t like development friction.  I especially don’t like testing friction.   Over the last several years, my approach to test-driven development and the style of test cases I create has changed drastically in an effort to eliminate testing frication.  To illustrate, I’ve created my first ever screencasts.  In these screencasts, I use TDD to implement a class in RageFeed.  Starting with very coarse, high-friction unit tests, I’ll show you how you can gradually reduce the friction by creating better tests.  Finally, I’ll show you how easy it is to create clean, readable, specification-style tests in RageFeed today.

Note: I apologize for the limitations of ScreenToaster’s player.  I’m in the process of mirroring the videos elsewhere, and I’ll update the post with links as soon as I get around to doing that.

In these screencasts, you’ll see me use a variety of tools.  They are:

Test-Driven Development - Part 1 (View)

In part 1, I introduce the class I’m going to be implementing, and I use TDD to flesh out the class.  I intentionally create my tests as I would have several years ago (meaning they suck).  From there, I gradually evolve them into a better suite of tests, but there’s still room for improvement.

Test-Drivent Development - Part 2 (View)

In part 2, I leverage some ReSharper templates and some base classes I’ve created in RageFeed to create replace my tests with behavior-driven development style specifications.  The result is (near) zero friction testing.

Downloads

I’ve packaged up the base SpecsFor<T> class as well as my ReSharper templates.  Feel free to use them for whatever you like! 

Download SpecsFor and ReSharper Templates: download

Questions? Comments?

I’m certainly not claiming that what we have in RageFeed is The One Way to do testing in .NET.  It works well for me, but I’d love to hear what others think.  Also, this is my first ever screencast, so please drop me a line and let me know what you liked, what you didn’t like, and what you’d like to see in future screencasts (assuming I actually do more).

Tags: