TDD as a Catalyst for Clean Code

An entry about tdd Publication date 12. June 2009 12:46

A few weeks back, I held a lightning talk about Test Driven Development at an internal event for Capgemini. The talk was heavilly influenced by Robert Martin's concept of clean code - I highly recommend that you watch his keynote from Railsconference 2009. Another influence for the lightnign talk was Kent Becks storyteller talk at Railsconf 2008, which is also highly recommended.

Even though my lightning talk was only about 10 mintues long, I had a whooping 24 slides to get through:

The slides won't  tell the story by themselves, so here are the notes I had on my slidecards The cards don't follow the slides, but I had circled keywords on each card to remember when to move forward (some slides were split with several animations etc).

Card 1
Motivation. Two observations about programming.
Ward - the inventor. Wiki, design patterns, XP, Kent Beck.

Card 2
The depth metaphor.
Start coding without all knowledge: Borrowed knowledge.
Need to clean up/improve old code as a result of improved/new knowledge to pay back debt.
If you don't, you loose momentum as old code drags you down.

Card 3
Kathy Sierra. Writer. Head First.
Not only function, but form.
Simpler to maintain, more fun to use, "cool factor".
Less stess, more motivating.

Card 4
Uncle Bob. Objectmentor. Agile manifesto.
Clean Code: 0 WTF's per minute.
Boyscout rule: Check in code cleaner than you checked it out.

Card 5
Fear. "Omg! This code sucks.. I should fix it." -> "Omg! No way I'm touching this - I'll just break it!"
How to remove the fear of refactoring?

Card 6
Change. Great design helps. How to verify changes? Compile? Run? 

Card 7
Empirical evidence.
Kent Beck. Innovator. Ward. XP. Testing
Glenford Myers, Boris Beizer, Bill Hetzel...

Card 8
Unit Testing. 90s. Smalltalk. SUnit.
Unit Testing born. Something missing... Test First?!
Crazy idea, no expectations - but worked!
TDD was born..

Card 9
Three Laws.

Card 10
Result? Productivity! Less debugging. Fear gone! Refactor at will.
TDD => Clean Code.

Be the first to rate this post

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

How To Make Unit Tests a Burden

An entry about tdd Publication date 12. May 2009 16:29

One of the common arguments people have against unit testing, is that it slows them down. And they're right - unit testing will slow you down - if you're doing it wrong.

Brittle Me This

The easiest way to be sure that your tests become a burden, is to write brittle tests. And the easiest way to write brittle tests, is to write tests that make assumptions about the internal implementation of whatever they're testing. For example, by calling private methods from unit tests.

The Fear of Refactoring

One of the huge advantages of having a set of unit tests, is the safety net they provide which allows you to refactor code without the fear of breaking stuff. If however by refactoring your code you break the tests and thus also have to refactor them all the time, not only are you compromising the value of the tests, you're also introducing a lot of extra work for yourself.

The Value of Resilience

Whether you're writing state or behavior based tests, try to keep knowledge about internal implementations of the thing you're testing out of the test, and you'll find that your tests become much more resilient to change, and thus much more valuable.

Currently rated 4.0 by 1 people

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

Fluent Reflection-Based Assertions

An entry about tdd | c# 3.0 Publication date 10. March 2009 11:57

Earlier this year, I shared my set of fluent assertion extension methods for xUnit. Here's a neat update which comes in handy whenever you´re doing assertions on things like anonymous objects – for example the data of a JsonResult from an ASP.NET MVC controller action:

return Json(new { status = "ok"})

Aside: You may balk at this and say we really should have a DTO instead of using anonymous object notation here – and you may be right. But lets disregard that for the rest of this post… :)

Normally, to write a test which verifies that the JsonResult's Data property indeed contains a status property with the value “ok”, we would need to crack it open with reflection:

[Observation]

public void Status_is_ok()

{

    var json = (JsonResult) _result;

 

    PropertyInfo statusProperty = json.Data.GetType().GetProperty("status");

 

    Assert.NotNull(statusProperty);

    statusProperty.GetValue(json.Data, null).ShouldBeEqualTo("ok");

}

That looks pretty ugly and unreadable, I think. So I've packed the ugliness away into a new helper method for my fluent assertion library, allowing me to write the above much more readably:

[Observation]

public void Status_is_ok()

{

    var json = (JsonResult) _result;

 

    json.Data.ShouldHaveProperty("status")

                      .Value

                      .ShouldBeOfType<string>()

                      .ShouldBeEqualTo("ok");

}

Notice also that I've now made it possible to chain assertions together, since the Should methods now return the object being asserted on.

You can download the updated assertion extension methods here

Be the first to rate this post

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

Slides From my TDD Talk

An entry about conferences | nnug | tdd Publication date 6. February 2009 08:05

Below are the slides from the Test Driven DevelopmentDesign talk I held at NNUG Stavanger last night. Thanks to everyone who attended, it was a great event!

Like I mentioned during my talk, many of the slides contain interesting links at the bottom to great blog posts/articles that are worth checking out if you want more details. You can also have a look at the tdd, bdd, agile and design patterns tags in my blog archive for further reading.

Currently rated 4.0 by 1 people

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

Fluent, Ubiquitous Assertions with xUnit

An entry about tdd | c# 3.0 Publication date 28. January 2009 13:03

With most testing frameworks, you write assertions like this:

var item = new object();

var list = new List<object> {item};

 

Assert.Equal(1, list.Count);

NUnit introduced a constraint-based assertion model a while back, which lets you write the above assertion in a more fluent manner:

Assert.That(list.Count, Is.EqualTo(1));

While this syntax certainly makes for more naturally readable assertions (“assert that List.Count is equal to 1”), it is quite verbose, awkward and has a less discoverable API (you have to know about all the IConstraints available).

With the extension method feature in C# 3.0, I’ve seen several experienced TDDers begin to use their own custom fluent assertion interfaces, resulting in syntax like this:

list.Count.ShouldBeEqualTo(1);

I’ve been meaning to write a set of extension methods myself to use with xUnit, and I’ve finally found the time to do so:

public static class AssertionHelpers
{
    /// <summary>
    /// Verifies that the string contains a given substring, using the current culture
    /// </summary>
    /// <param name="actualString"></param>
    /// <param name="expectedSubstring">The sub-string expected to be in the string</param>
    public static void ShouldContain(this string actualString, string expectedSubstring)
    {
        Assert.Contains(expectedSubstring, actualString);
    }

    /// <summary>
    /// Verifies that the string contains a given substring, using the given comparison type
    /// </summary>
    /// <param name="actualString"></param>
    /// <param name="expectedSubstring">The sub-string expected to be in the string</param>
    /// <param name="comparisonType">The type of string comparison to perform</param>
    public static void ShouldContain(this string actualString, string expectedSubstring, StringComparison comparisonType)
    {
        Assert.Contains(expectedSubstring, actualString, comparisonType);
    }

    /// <summary>
    /// Verifies that the collection contains a given object
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="collection"></param>
    /// <param name="expected">The object expected to be in the collection</param>
    public static void ShouldContain<T>(this IEnumerable<T> collection, T expected)
    {
        Assert.Contains(expected, collection);
    }

    /// <summary>
    /// Verifies that the collection contains a given object, using the given comparer
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="collection"></param>
    /// <param name="expected">The object expected to be in the collection</param>
    /// <param name="comparer">The comparer to use</param>
    public static void ShouldContain<T>(this IEnumerable<T> collection, T expected, IComparer<T> comparer)
    {
        Assert.Contains(expected, collection, comparer);
    }

    /// <summary>
    /// Verifies that the string does not contain a given substring, using the current culture
    /// </summary>
    /// <param name="actualString"></param>
    /// <param name="expectedSubstring"></param>
    public static void ShouldNotContain(this string actualString, string expectedSubstring)
    {
        Assert.DoesNotContain(expectedSubstring, actualString);
    }

    /// <summary>
    /// Verifies that the string does not contain a given substring, using the given comparison type
    /// </summary>
    /// <param name="actualString"></param>
    /// <param name="expectedSubstring"></param>
    /// <param name="comparisonType"></param>
    public static void ShouldNotContain(this string actualString, string expectedSubstring, StringComparison comparisonType)
    {
        Assert.DoesNotContain(expectedSubstring, actualString, comparisonType);
    }

    /// <summary>
    /// Verifies that the collection does not contain a given object
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="collection"></param>
    /// <param name="expected"></param>
    public static void ShouldNotContain<T>(this IEnumerable<T> collection, T expected)
    {
        Assert.DoesNotContain(expected, collection);
    }

    /// <summary>
    /// Verifies that the collection does not contain a given object, using the given comparer
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="collection"></param>
    /// <param name="expected"></param>
    /// <param name="comparer"></param>
    public static void ShouldNotContain<T>(this IEnumerable<T> collection, T expected, IComparer<T> comparer)
    {
        Assert.DoesNotContain(expected, collection, comparer);
    }

    /// <summary>
    /// Verifies that the collection is empty
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="collection"></param>
    public static void ShouldBeEmpty<T>(this IEnumerable<T> collection)
    {
        Assert.Empty(collection);
    }

    /// <summary>
    /// Verifies that the objects is equal to the given object, using a default comparer
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="actual"></param>
    /// <param name="expected"></param>
    public static void ShouldBeEqualTo<T>(this T actual, T expected)
    {
        Assert.Equal(actual, expected);
    }

    /// <summary>
    /// Verifies that the object is equal to the given object, using a custom comparer
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="actual"></param>
    /// <param name="expected"></param>
    /// <param name="comparer"></param>
    public static void ShouldBeEqualTo<T>(this T actual, T expected, IComparer<T> comparer)
    {
        Assert.Equal(actual, expected, comparer);
    }

    /// <summary>
    /// Verifies that the condition is false
    /// </summary>
    /// <param name="condition"></param>
    public static void ShouldBeFalse(this bool condition)
    {
        Assert.False(condition);
    }

    /// <summary>
    /// Verifies that the object is in within a given range
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="actual"></param>
    /// <param name="low">The inclusive low value</param>
    /// <param name="high">The inclusive high value</param>
    public static void ShouldBeInRange<T>(this T actual, T low, T high)
    {
        Assert.InRange(actual, low, high);
    }

    /// <summary>
    /// Verifies that the object is within a given range, using a custom comparer
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="actual"></param>
    /// <param name="low">The inclusive low value</param>
    /// <param name="high">The inclusive high value</param>
    /// <param name="comparer">The custom comparer to use</param>
    public static void ShouldBeInRange<T>(this T actual, T low, T high, IComparer<T> comparer)
    {
        Assert.InRange(actual, low, high, comparer);
    }

    /// <summary>
    /// Verifies that the object is assignable from the given type
    /// </summary>
    /// <param name="object"></param>
    /// <param name="expectedType">The type the object should be</param>
    public static void ShouldBeAssignableFromType(this object @object, Type expectedType)
    {
        Assert.IsAssignableFrom(expectedType, @object);
    }

    /// <summary>
    /// Verifies that the object is not of the given type
    /// </summary>
    /// <param name="object"></param>
    /// <param name="expectedType">The type the object should not be</param>
    public static void ShouldNotBeOfType(this object @object, Type expectedType)
    {
        Assert.IsNotType(expectedType, @object);
    }

    /// <summary>
    /// Verifies that the object is of the given type
    /// </summary>
    /// <param name="object"></param>
    /// <param name="expectedType">The type the object should be</param>
    public static void ShouldBeOfType(this object @object, Type expectedType)
    {
        Assert.IsType(expectedType, @object);
    }

    /// <summary>
    /// Verifies that the collection is not empty
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="collection"></param>
    public static void ShouldNotBeEmpty<T>(this IEnumerable<T> collection)
    {
        Assert.NotEmpty(collection);
    }

    /// <summary>
    /// Verifies that the object is not equal to a given object, using a default comparer
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="actual"></param>
    /// <param name="expected"></param>
    public static void ShouldNotBeEqualTo<T>(this T actual, T expected)
    {
        Assert.NotEqual(expected, actual);
    }

    /// <summary>
    /// Verifies that the object is not equal to a given object, using a custom comparer
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="actual"></param>
    /// <param name="expected"></param>
    /// <param name="comparer"></param>
    public static void ShouldNotBeEqualTo<T>(this T actual, T expected, IComparer<T> comparer)
    {
        Assert.NotEqual(expected, actual, comparer);
    }

    /// <summary>
    /// Verifies that the object is not in the given range
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="actual"></param>
    /// <param name="low">The inclusive low value</param>
    /// <param name="high">The inclusive high value</param>
    public static void ShouldNotBeInRange<T>(this T actual, T low, T high)
    {
        Assert.NotInRange(actual, low, high);
    }

    /// <summary>
    /// Verifies that the object is not in the given range, using a custom comparer
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="actual"></param>
    /// <param name="low">The inclusive low value</param>
    /// <param name="high">The inclusive high value</param>
    /// <param name="comparer">The custom comparer</param>
    public static void ShouldNotBeInRange<T>(this T actual, T low, T high, IComparer<T> comparer)
    {
        Assert.NotInRange(actual, low, high, comparer);
    }

    /// <summary>
    /// Verifies that the object is not null
    /// </summary>
    /// <param name="object"></param>
    public static void ShouldNotBeNull(object @object)
    {
        Assert.NotNull(@object);
    }

    /// <summary>
    /// Verifies that the object is not the same as the given object
    /// </summary>
    /// <param name="actual"></param>
    /// <param name="expected"></param>
    public static void ShouldNotBeSameAs(this object actual, object expected)
    {
        Assert.NotSame(expected, actual);
    }

    /// <summary>
    /// Verifies that the object is null
    /// </summary>
    /// <param name="object"></param>
    public static void ShouldBeNull(this object @object)
    {
        Assert.Null(@object);
    }

    /// <summary>
    /// Verifies that the object is the same as the given object
    /// </summary>
    /// <param name="actual"></param>
    /// <param name="expected"></param>
    public static void ShouldBeSameAs(this object actual, object expected)
    {
        Assert.Same(expected, actual);
    }

    /// <summary>
    /// Verifies that the condition is true
    /// </summary>
    /// <param name="condition"></param>
    public static void ShouldBeTrue(this bool condition)
    {
        Assert.True(condition);
    }

    /// <summary>
    /// Verifies that the delegate throws the given exception
    /// </summary>
    /// <typeparam name="EXCEPTION"></typeparam>
    /// <param name="action"></param>
    public static void ShouldThrow<EXCEPTION>(this Action action) 
        where EXCEPTION : Exception
    {
        Assert.Throws<EXCEPTION>(new Assert.ThrowsDelegate(action));
    }

    /// <summary>
    /// Verifies that the delegate does not throw any exceptions
    /// </summary>
    /// <param name="action"></param>
    public static void ShouldNotThrow(this Action action)
    {
        Assert.DoesNotThrow(new Assert.ThrowsDelegate(action));
    }
}

/// <summary>
/// Static gateway for building actions fluently
/// </summary>
public static class The
{
    public static Action Action(Action action)
    {
        return action;
    }
}
}

So far, I’ve created extension methods which wrap all of xUnits Assert methods, but I can certainly imagine other more (domain) specific Should* methods which would be helpful to have as well. Not everybody agrees, though.

Ubiquitous Assertion Syntax

The step from here towards an ubiquitous assertion syntax, as described by Jay Fields, is to create a set of complementary extension methods for behavior based assertions (mock expectations). This would have to involve some lambda trickery, perhaps similar to the ShouldThrow trick I picked up from JP’s blog. More on that later, perhaps.

Currently rated 5.0 by 4 people

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

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

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