Behavior Driven JavaScript Development with JSSpec

An entry about bdd | javascript | tdd Publication date 26. January 2009 12:00

Before Christmas, I begun investigating JavaScript unit testing frameworks in an effort to increase the test coverage for my web projects. I’ve had a busy month since then, moving and changing jobs, but now I’m back on track and ready to try out another framework. So today, I’ll be looking at JSSpec, which is a Behavior Driven Development framework.

Code by Example

In JSSpec, specifications are referred to as containing one or more “examples” (tests) which “describe” (fixtures) the behavior. This wording of the specifications helps enforce the idea that a test should not only verify the behavior of a given piece of code, but also “serve as documentation and at the same time reveal the intent of the code”.

Rewriting the InlineEditor Test Suite with JSSpec

When investigating YUITest, I wrote a simple InlineEditor component complete with a set of tests as an example. Those tests looked like this one:

var testCase0 = new YAHOO.tool.TestCase(
{
    name: "When entering editing mode",
    setUp: function()
    {
        var span = $("<span id='span'>test</span>"); // create the span to edit
        span.appendTo($('#container')); // append it to the test container
        this.editor = new InlineEditor(span);
        YAHOO.util.UserAction.click(span[0]); // click to begin editing
    },
    test_span_is_turned_into_input: function()
    {
        var input = $('#span'); // find the element in the document
        // element should now be replaced with an input element
        YAHOO.util.Assert.isInstanceOf(HTMLInputElement, input[0]);
    },
    test_input_has_same_text_as_span: function()
    {
        var input = $('#span');
        YAHOO.util.Assert.areEqual('test', input.val());
    },
    tearDown: function()
    {
        $('#container').empty(); // clear the container 
        delete this.editor;
    }
});

Migrating the tests to JSSpec wasn't difficult – in part thanks to the fact that I had already written my tests using YUITest with a bdd-style approach. The test above, for example, now looks like this:

describe('When entering editing mode',
{
    before_each: function()
    {
        container = $("<div/>");
        container.appendTo($("body"));
        original_text = 'test';


var span = $("<span id='span'></span>"); // create the span to edit span.text(original_text); span.appendTo(container); // append it to the test container var editor = new InlineEditor(span); editor.beginEdit(); }, after_each: function() { container.remove(); }, 'span should turn into editor': function() { var inputs = $('input').filter('#span'); // find the element in the document value_of(inputs).should_have(1, "length"); }, 'editor should have text of span': function() { var input = $('#span'); value_of(input.val()).should_be(original_text); } });

So what has changed? Where we had setUp and tearDown methods in YUITest, we now have before_each and after_each methods in JSSpec. The test methods are declared with string names in JSSpec, which means I can now use spaces and write more natural names for them (plus no need to prefix their names with ‘test’). The assertion syntax is a bit different too – JSSpec uses a fluent API that again reads a bit more easily.

All in all, I think I prefer the syntax of JSSpec. It also has a very nice test runner UI:

 image

The API is fairly easy to grasp too, and though the documentation is fairly concise (especially compared to YUITest) it covers everything you need to know. All in all, JSSpec is one of those frameworks that you pick up and hit the ground running with, which is awesome.

A Minimalistic Framework

Feature-wise however, YUITest wins hands down. Where JSSpec is strictly offering a testing framework with the minimal set of features you need, YUITest has a much larger bag of tricks. For instance, JSSpec has no helpers for testing asynchronous code (Ajax stuff) or interacting with UI elements (faking mouse/keyboard events etc) – you’ll have to either roll your own or rely on something like jQuery for that stuff. Assertions are a bit sparse too – I really miss things like YUITests data type assertion (isArray/isString/… and the more generic isTypeOf/isInstanceOf).

Continous Integration

Unlike YUITest, JSSpec has no built-in extension API for reporting test results. However, the test runner produces a clean html output which won’t be too hard to parse if you were to for instance fire it up from a custom build task in TFS:

image

Download Example Code

You can download the complete InlineEditor example with a suite of JSSpec tests here.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Extending xUnit with a Custom ObservationAttribute for BDD Style Testing

An entry about bdd Publication date 19. September 2008 20:32

A couple of weeks ago, I wrote about how I’ve been experimenting a bit with the way I structure my tests in light of moving towards Behavior Driven Development. One of the things I did, was to create a base class for all my tests, and use it to separate the context of the test from the actual testing, so that it could be reused.

In order to make this work with xUnit, my base class was forced to make virtual calls within its constructor – which you really don’t want to do. Alas, xUnit doesn’t have any setup and teardown functionality apart from using the constructor and implementing IDisposable, so there’s wasn’t really any other way for me to get this working. Or was there…?

Extending xUnit

Of course there was! Like any good framework, xUnit can be extended. For one thing, we can create our own test method attribute to manage how any test decorated with it should be executed:

/// <summary>
/// Identifies a method as an observation which asserts the specification
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class ObservationAttribute : FactAttribute
{
    protected override IEnumerable<ITestCommand> EnumerateTestCommands(MethodInfo method)
    {
        foreach(ITestCommand command in base.EnumerateTestCommands(method))
        {
            yield return new ObservationCommand(command, method);
        }
    }
}

In xUnit, each test run is programmatically represented by an instance of something that implements the ITestMethod ITestCommand interface, and through the EnumerateTestCommands method the Fact attribute is allowed to return any number of such instances – which essentially means that any xUnit test method may be executed multiple times per test (something that the Theory stuff in the xUnit Extensions take advantage of – more on that some other time).

My custom Observation attribute simply passes the original test command(s) on, after wrapping it in an ObservationCommand. By using the decorator pattern, we can easily implement this so that it calls the InitializeContext and Observe methods on our Specification fixtures before letting the actual command execute the test:

public class ObservationCommand : ITestCommand
{
    private readonly ITestCommand _innerCommand;
 
    public ObservationCommand(ITestCommand innerCommand)
    {
        _innerCommand = innerCommand;
    }
 
    public MethodResult Execute(object testClass)
    {
        // for specifications, we initialize the context and 
        // perform the observation before executing the test method
        if(testClass is Specification)
        {
            Specification specification = (Specification)testClass;
 
            specification.InitializeContext();
            specification.Observe();
        }
 
        return _innerCommand.Execute(testClass);
    }
 
    public string Name
    {
        get { return _innerCommand.Name; }
    }
 
    public bool ShouldCreateInstance
    {
        get { return _innerCommand.ShouldCreateInstance; }
    }
}

With this in place, our Specification class now looks like this:

/// <summary>
/// The base specification class
/// </summary>
public abstract class Specification
{
    /// <summary>
    /// Initializes the context for the specification
    /// </summary>
    protected internal abstract void InitializeContext();
 
    /// <summary>
    /// Performs the action to observe the outcome of to validate the specification.
    /// </summary>
    protected internal abstract void Observe();
}

Let’s Recap: An Example..

Okay, so I showed an example last time – but lets do another one with the new naming and everything. I create an (abstract) context like this:

public abstract class Behaves_like_repository_with_no_pages : Specification
{
    protected InMemoryDataContext _context = new InMemoryDataContext();
    protected InMemoryRepository<IPage> _repository;
  
    protected override void InitializeContext()
    {
        _repository = _context.GetRepository<IPage>() as InMemoryRepository<IPage>;
    }
}

With this, I can then write specifications that requires such a context in order to be tested:

public class When_creating_a_new_page : Behaves_like_repository_with_no_pages
{
    private IPage _page;
 
    protected override void Observe()
    {
        ICreatePages factory = new PageFactory(_repository);
        _page = factory.Create("Title");
    }
 
    [Observation]
    public void A_new_page_instance_is_created()
    {
        Assert.NotNull(_page);
    }
 
    [Observation]
    public void The_instanace_is_inserted_into_the_repository()
    {
        Assert.Equal(1, _repository.Find().Where(p => p == _page).Count());
    }
 
    /** snip **/
}

I’m getting more and more comfortable with this way of structuring my tests - but be warned that it is a very fine line to walk here before taking the DRY principle too far by pushing too much stuff down into the base class, which will make it very difficult to come back to a test later, or for someone else to read it as an example of how something works.

My view at the moment is that only the setup of the context belongs in the base class; the code that creates the environment in which we want to run the test. In the above example for instance, our context is the existence of a page repository. This is a prerequisite for creating a new page, and not really of interest for the test itself – it is just something that must be there in order for us to be able to test creating a page. Normally, most of the stuff that sets up the context will be code that mocks any dependencies the SUT has.

By separating this from the test class, I think the readability of the test becomes much improved. If you look at it, you can instantly recognise that in order to create a new page, you need to obtain an instance of the ICreatePages interface and call its Create method. Then, by looking at the observations, you can identify what the end result (side effects) will be – that a new page instance is returned, and that it is inserted into the repository.

Where Do We Go From Here?

What I’m doing here, is just enabling a BDD-like way of writing tests within an existing unit testing framework. There are quite a few people out there who are building tailored test frameworks for BDD however – some notable ones for .NET are NBehave and MSpec, plus the very interesting Specter, which takes advantage of Boo’s meta-programmability to make the syntax read more like proper specifications.

For my part, I’m just waiting for better integration with the IDE and tools for these frameworks, before taking the plunge and ditching my current “hybrid” approach. One thing is for sure – I’m really digging the mindset of BDD (which obviously goes far beyond just writing tests, but that’s a post for another day).

Currently rated 3.0 by 2 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Hypothesis Base Class and Naming Conventions for BDD/AAA Style Unit Testing

An entry about tdd | bdd Publication date 22. August 2008 11:57

Earlier, I wrote about how I think unit tests should employ the concept of falsifiability. To do this effectively, I’ve been experimenting a bit with how I structure my tests. Following on from the concepts I talked about previously, each test fixture should be defined as a hypothesis we try to falsify with a set of assertions – not being able to break the hypothesis means we can assume that it is true (and that our code works!).

This ties neatly with the concepts of BDD, which uses a context/specification style for writing tests, as well as the now popular AAA (Arrange-Act-Assert) structure. Much of the inspiration for what I’m doing here comes from reading Jean-Paul Boodhoo’s and Jimmy Bogards blogs.

Here’s an example of a test class I’ve written in this way:

namespace Specs_for_ImageController
{
    public class When_rendering_image  : RenderImageHypothesis
    {
        private DynamicImageResult _result;
        private const string _id = "id";
 
        protected override void Observe()
        {
            _result = _controller.Render(_id, null, null) as DynamicImageResult;
        }
 
        [Fact]
        public void It_is_retrieved_from_gallery()
        {
            // verify that the gallery's GetItem method was called
            _galleryMock.Verify(g => g.GetItem(_id));
        }
 
        [Fact]
        public void A_DynamicImageResult_is_returned()
        {
            Assert.NotNull(_result);
        }
 
        [Fact]
        public void DynamicImageResult_has_image()
        {
            Assert.Same(_image, _result.Image);
        }
    }
}

What I’ve done here, is separate the context (Arrange) of the hypothesis from the observation (Act) and the attempts to falsify it (Assert). Additionally, I’m using the namespace, class and method to build a very fluent naming scheme.

The test class inherits from the RenderImageHypothesis class, which contains the context of the hypothesis:

public abstract class RenderImageHypothesis : Hypothesis
{
    protected ImageController _controller;
    protected Mock<IGallery> _galleryMock;
    protected Image _image;
    protected Mock<IGalleryItem> _galleryItem;
    protected Mock<IImageScaler> _imageScalerMock;
    protected Bitmap _scaledImage;
 
    protected override void InitializeContext()
    {
        _galleryItem = new Mock<IGalleryItem>();
        _galleryMock = new Mock<IGallery>();
        _imageScalerMock = new Mock<IImageScaler>();
 
        _image = new Bitmap(1, 1);
 
        // mock the gallery item so that it returns the image
        _galleryItem.Expect(g => g.GetImage()).Returns(_image);
 
        // mock the gallery so that it returns the gallery item
        _galleryMock.Expect(g => g.GetItem(It.IsAny<string>())).Returns(_galleryItem.Object);
 
        // mock the image scaler so that it returns the 'scaled' image
        _scaledImage = new Bitmap(1,1);
 
        _imageScalerMock
            .Expect(s => s.Scale(It.IsAny<Image>(), It.IsAny<int?>(), It.IsAny<int?>()))
            .Returns(_scaledImage);
 
        _controller = new ImageController(_galleryMock.Object, _imageScalerMock.Object);
    }
}

This then enables me to reuse it for other observations on the same context:

public class When_rendering_image_with_width_and_height_defined : RenderImageHypothesis
{
    private readonly int? _width = 15;
    private readonly int? _height = 15;
    private DynamicImageResult _result;
 
    protected override void Observe()
    {
        _result = _controller.Render("", _width, _height) as DynamicImageResult;
    }
 
    [Fact]
    public void It_is_scaled_to_width_and_height()
    {
        // verify that the image scaler was called with the appropriate args
        _imageScalerMock.Verify(s => s.Scale(_image, _width, _height));
    }
 
    [Fact]
    public void Scaled_image_returned()
    {
        Assert.Same(_scaledImage, _result.Image);
    }
}

My Hypothesis base class looks like this:

/// <summary>
/// Represents a test fixture hypothesis
/// </summary>
public abstract class Hypothesis
{
    protected Hypothesis()
    {
        InitializeContext();
        Observe();
    }
 
    /// <summary>
    /// Should initialize the context of the test fixture
    /// </summary>
    protected abstract void InitializeContext();
 
    /// <summary>
    /// Should perform the observation that will be asserted
    /// </summary>
    protected abstract void Observe();
}

Running the tests, we get a very nice BDD-style list of test results:

image

I’m still experimenting with this, and I’ve yet to convince myself 100% that its a better way to structure the tests – especially with respect to separating out the context in a base class for reuse, which could potentially lead to hard to tests that are hard to understand at a glance. If you have any thoughts, please comment!

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Powered by BlogEngine.NET 1.4.5.0

Welcome!

My name is Fredrik Kalseth, and this is my blog - thanks for visiting! I am fortunate enough to work with what I love for a living, and this blog is essentially the biproduct of that.

I work as a senior consultant for Capgemini, and am also an active participant in the Norwegian .NET community, as an avid attendee but also as a speaker (most recently at NNUG and MSDN Live).

As a developer, I have a wide circle of interest. My primary passion is for agile, test-driven development, with focus on best practices and clean code. That said, I also love to work on the frontend, especially with web development.

On Twitter? My handle is fkalseth. On LinkedIn? I`m there too.

Disclaimer

This is a personal blog; any opinions expressed here are my own and do not necessarily reflect those of my employer. All content herein is my own original creation, and as such is protected by copyright law. Unless otherwise stated, all source code posted on this blog is freely usable under the Microsoft Permissive License.

What Readers Talk About

Comment RSS