Test Drive your windows phone application

4 comments

Monday, December 30, 2013

Today I presented the topic of unit testing (surprise, surprise) and Test Driven Development for windows pone applications.

I’d like to thank those who managed to arrive to the meeting despite the weather – it was a pleasure.

My talk was at the second part of the meeting - right after Eyal who showed how to use SignalR with windows phone and had a cool demo in which he controlled a game remotely using his phone (asteroids).

The code for my session is already on GitHub and here are the slides to go with it:

I’ve enjoyed preparing for this talk and I hope I’ll make the time in the future to continue working on the library I’ve created for this session.

But until then:

 

Happy coding…

On object creation and unit tests

7 comments

Sunday, December 22, 2013

There is always a balance between readability and maintainability when writing unit tests.
I hate hearing a fellow developer say – “the task took me X time more because I had to fix 100+ tests because I refactored my production code”. This means I’m always on the look for ways to decrease the tests maintenance overhead.
While adding  (or removing) a parameter to a method can cause the discomfort of fixing a few tests that run that method – doing the same to the constructor is downright painful. The constructor of the class you’re testing is the method that have to run on each test– and if you change it you must edit all of those tests so that they would compile after the change.
Over the years (and projects) I have used several strategies to reduce the pain of change – the following are the ones that worked for me:

Our test subject

I’ve decided to use the old mocking-frameworks-compare project which unfortunately has not been updated for some time now.
The project took several Mocking (read: Isolation) frameworks and compared their API using a simple problem/story.
I have a brain (business logic) that should cause Mouth to Yell if a hot Iron is touched by Hand.
image
Since at the time FakeItEasy was not around to be compared I’ve decided to use to
explain how we can (or rather should) create out test subject.

Option #0 - Do nothing

Been there, done that. From time to time we accept the fact that this is as good as it gets and prepare to pay the cost. I have always preferred readability in my unit tests and I still write tests where I just create the object under test.
Keep it simple means that you get to choose using a simple new to create the object under test.
[TestMethod]
public void TouchHotIron_Yell()
{
    var hand = A.Fake<IHand>();
    var mouth = A.Fake<IMouth>();

    A.CallTo(() => hand.TouchIron(A<Iron>.Ignored)).Throws<BurnException>();

    var brain = new Brain(hand, mouth);
    brain.TouchIron(new Iron { IsHot = true });

    A.CallTo(() => mouth.Yell()).MustHaveHappened();
}
Although simple this is not a robust solution, the object creation is tightly coupled to the test which could cause some discomfort – what happens if we add another parameter to the class constructor – sounds innocent enough, until you find yourself fixing 200 tests that happen to instantiate that object. This makes developer shy from adding parameters to constructors (seen that) or create an overload for each new parameter added just to make sure that the test code continue to compile – and then it’s my job to search the code for those useless constructors and delete them one by one.

Option #1 - Use setup method + fields

Each day a software developer who writes unit tests looks at it tests and thinks to himself – I can reduce the duplication by using the Test Setup method (in MSTest TestInitialize) and so that developer happily copies all of the initialization code to a single setup method where he can only change one method when the need arises.
[TestInitialize]
public void CreateObject()
{
    _hand = A.Fake<IHand>();
    _mouth = A.Fake<IMouth>();

    _brain = new Brain(_hand, _mouth);
}

[TestMethod]
public void TouchHotIron_Yell()
{
    A.CallTo(() => _hand.TouchIron(A<Iron>.Ignored)).Throws<BurnException>();

    _brain.TouchIron(new Iron { IsHot = true });

    A.CallTo(() => _mouth.Yell()).MustHaveHappened();    
}
I have written about why I don’t like about using Setup methods namely they split the test logic and could can become bloated as your write more tests and your class required different initialization for each test.
If you use SetUp/TestInitialize to split the creation and testing of your objects make sure that everyone understand that this method should only be used for that purpose alone. I saw how these methods can become complex and difficult as more and more logic moves there until they are impossible to understand – you’ve been warned!

Option #2 - Factory methods

This used to be my favorite method since I still have all of test inside a single method. Instead of moving the plumbing of the initialization into the SetUp method – why not move it to a method and call it from each test that requires it.
[TestMethod]
public void TouchHotIron_Yell()
{
    var hand = A.Fake<IHand>();
    var mouth = A.Fake<IMouth>();

    A.CallTo(() => hand.TouchIron(A<Iron>.Ignored)).Throws<BurnException>();

    var brain = CreateBrain(hand, mouth);
    brain.TouchIron(new Iron { IsHot = true });

    A.CallTo(() => mouth.Yell()).MustHaveHappened();
}

private Brain CreateBrain(IHand hand, IMouth mouth)
{
    return new Brain(hand, mouth);
}
This way when I read the test I can see everything that the test does and if I care about how the object was initialized I can dive right in.
Please make sure that you don’t do too much inside this factory method – same rules apply as in production code (Single Responsibility being one of them).
I’ve been part of one project where we’ve created a class to initialize and configure most of our business objects and it helped us make sure that we create them according to the requirements.

Option #3 - Auto-Faking container

I’ve started using Auto-Mocking containers after Typemock has added this functionality to Isolator via Isolate.Fake.Dependencies call.
In order to really decouple the creation of the test subject we need to bring in the big guns.
This is a solution similar to the way that object creation is decoupled from usage inside production code – namely Inversion of Control (IoC) container. Using an Auto-Mocking Container we can delegate the object creation logic to a specified class that is responsible to provide all of the constructor’s parameters and pass in Fake objects whenever such an argument was not specified – it’s that simple.
There’s a great blog post about it by Mark Seemann on the subject – go read it now!
In fact the container I’m using with FakeItEasy was written using Mark’s AutoFixture project.
And so by using Auto-Mocking we can make our test look like this:
private IFixture _container;

[TestInitialize]
public void InitializeContainer()
{
    _container = new Fixture()
        .Customize(new AutoFakeItEasyCustomization());
}

[TestMethod]
public void TouchHotIron_Yell1()
{
    var hand = _container.Freeze<Fake<IHand>>().FakedObject;
    var mouth = _container.Freeze<Fake<IMouth>>().FakedObject;

    A.CallTo(() => hand.TouchIron(A<Iron>.Ignored)).Throws<BurnException>();

    var brain = _container.Create<Brain>();
    brain.TouchIron(new Iron { IsHot = true });

    A.CallTo(() => mouth.Yell()).MustHaveHappened();
}
Simple? It is once you get used to it.
  1. Use NuGet to add AutoFixture.AutoFakeItEasy,
  2. Create a container using the magic words: .Customize(new AutoFakeItEasyCustomization()). This would make sure that fake objects would be passed to instances created using AutoFixture.
  3. Use the Freeze command to make sure that the container would return them when creating the object – I only do this inside the test so that I can use different configurations for different tests.
  4. And that’s it
I my object would require other parameters that I don’t care about they would be provided automatically (and recursively) by the Auto-Mocking container.
I really like using Auto-Mocking in my tests but I prefer to pass the parameters I’m using to the Create method and so I wrote a simple extensions methods that I can use to do exactly that:
public static class AutoFixtureExtensions
{
    public static T FreezeFake<T>(this IFixture fixture)
    {
        return fixture.Freeze<Fake<T>>().FakedObject;
    }

    public static T Create<T, TArg1, TArg2>(this IFixture fixture, TArg1 arg1, TArg2 arg2)
    {
        fixture.Inject(arg1);
        fixture.Inject(arg2);

        return fixture.Create<T>();
    }
}
I also wrote a few more extension methods for different number of arguments as well as FreezeFake for those at the team that find this API more to their liking:
[TestMethod]
public void TouchHotIron_Yell2()
{
    var hand = _container.FreezeFake<IHand>();
    var mouth = _container.FreezeFake<IMouth>();

    A.CallTo(() => hand.TouchIron(A<Iron>.Ignored)).Throws<BurnException>();

    var brain = _container.Create<Brain>();
    brain.TouchIron(new Iron { IsHot = true });

    A.CallTo(() => mouth.Yell()).MustHaveHappened();
}

[TestMethod]
public void TouchHotIron_Yell3()
{
    var hand = A.Fake<IHand>();
    var mouth = A.Fake<IMouth>();

    A.CallTo(() => hand.TouchIron(A<Iron>.Ignored)).Throws<BurnException>();

    var brain = _container.Create<Brain, IHand, IMouth>(hand, mouth);
    brain.TouchIron(new Iron { IsHot = true });

    A.CallTo(() => mouth.Yell()).MustHaveHappened();
}

Conclusion

In order to write robust unit tests you have to make sure that your tests would fail only when  a bug is introduced and you definitely want to avoid compilation errors caused by the tests.
It can be very frustrating to have to fix a truckload of tests due to a trivial change – and there are practices and tools to help us avoid exactly that.
Auto-mocking container is one of these tools and since I’ve started using it my productivity has improved tremendously – so why don’t you give it a try today.

Happy coding…

Agile Practitioners 2014 conference

No comments

Tuesday, December 17, 2013

I have been talking and posting about Agile for a few years now – ever since I discovered SCRUM and unit tests.1784dc7

In the past I had the pleasure to speak in the Agile Practitioners conference. It was fun, great local and international speakers and good crowd.

This year I’ve decided to return to the scene of the crime – this time I’ll do a quick lightning talk about “what’s wrong with TDD”.

 

So if you’re around (Israel) and want to hear great speakers and meet other agile practitioners from the industry – sign up, just tell them I’ve sent you. Or better yet – use this coupon to receive a nice discount.

 

 

See you there

Battle of the mocking framework @NDCLondon

No comments

Thursday, December 05, 2013

This week I’ve had a chance to come to London (again) and present one of my favorite topics in NDC London.

I had a good session which I enjoyed . I had a crowd and was asked very good questions by the members of the audience.

The code I’ve used can be found on GitHub and this is the presentation for your consideration:

 

Happy coding…

Related Posts Plugin for WordPress, Blogger...