Tuesday, June 5, 2012

TDD/BDD : Writing Specifications


Specifications

What are Specifications? Simply put, they are tests. But when we tend to think more in terms of the business scenario, its easier to write tests.


Specifications Should

  • Reflect the user story/ business case at hand.
  • Should be readable
  • Should reflect context well.

Patterns


  • Given, When, Then (GWT)
  • Align, Act, Assert (AAA)

Understanding Given, When, Then


  • In the Given, we setup what's required. "Given these conditions"
  • In the When, we specify the action. "When we perform this action"
  • In the Then, we tell our expectations. "This is our expectation"

So, if we read from top to bottom : "Given these conditions, When we perform this action, This is our expectation"


Writing a Test Scenario using the GWT & AAA patterns


public class Calculator
{
    public int Add(int value1, int value2)
    {
        return value1 + value2;
    }

}

We can test the Add method using the two patterns.

The GWT Pattern

    public class WithGWT
    {
        private int _value1;
        private int _value2;
        private int _result;


        [SetUp]
        public void Setup()
        {
            Given();
            When();
        }

        private void When()
        {
            _result = Calculator.Add(_value1, _value2);
        }

        private void Given()
        {
            _value1 = 2;
            _value2 = 3;
        }

        [Test]
        public void It_should_return_five()
        {
            Assert.AreEqual(_result,5);
        }
    }

The AAA Pattern:

    public class WithAAA
    {
        private int _value1;
        private int _value2;
        private int _result;


        [SetUp]
        public void Setup()
        {
            Given();
            When();
        }

        private void When()
        {
            _result = Calculator.Add(_value1, _value2);
        }

        private void Given()
        {
            _value1 = 2;
            _value2 = 3;
        }

        [Test]
        public void It_should_return_five()
        {
            Assert.AreEqual(_result, 5);
        }
    }

Specifications Library

Since we would have specifications in all our projects, We can setup a library to have such a pattern.
Also we can hide Asserts inside custom extension methods which makes it more readable.

Sample Implementation

    [TestFixture]
    public abstract class Specification
    {
        [SetUp]
        public void Setup()
        {
            Given();
            When();
        }

        [TearDown]
        public virtual void Cleanup()
        {
           
        }

        public abstract void Given();
        public abstract void When();
    }



public static class SpecificationExtensions
  {

    public static object ShouldEqual(this object actual, object expected)
    {
      Assert.AreEqual(expected, actual);
      return expected;
    }

`}


Assert is a NUnit class. The Assert class contains a collection of static methods that implement the most common Asserts in NUnit.
We can extend all the Assert class methods as such. And, we can adopt the library in all our projects.

So, our GWT test class would now like

    class WithGwtUsingSpecificationLibrary : Specification
    {
        private int _value1;
        private int _value2;
        private int _result;

        protected override void Given()
        {
            _value1 = 3;
            _value2 = 5;
        }

        protected override void When()
        {
            _result = Calculator.Add(_value1, _value2);
        }

        [Test]
        public void It_should_return_eight()
        {
            _result.ShouldEqual(8);
        }

    }

You can download the sample TDD project from my Box.com account.


https://www.box.com/s/9a16341ae9e4bc1ef86f

No comments:

Post a Comment