Fork me on GitHub

Wednesday, August 26, 2009

Configure your Visual Studio to run your tests automatically

It all started after I saw Misko Hevery demonstrating this technique of running unit tests whenever he saves code in Eclipse at his Thoughtworks Geek Night talk and reading his blog post on it. I am a big sucker of fast feedback and always felt that faster the feedback, better it is. This technique to run unit tests, I felt is a big step towards it (Also my patience is too short for me to go and run the tests by navigating through menus :). Being a compulsive TDD guy, unfortunately in a .Net project and so forced to use Visual Studio (I have nothing to complain about. Move along :) every day, I felt the need for this badly. And so began my quest...

I was looking for a way to hook into the save event of Visual Studio to do something same as Misko's but couldn't find any till now. The next best thing for me is Post Build Event hook. Conveniently this is available in Visual Studio for every project to be configured in project properties. So on the test project properties "Build Events" section, you can hook into the pre and post build events to run some shell scripts.

Prerequisites - Have nunit-console.exe in path or better have it in your project as a dependency. I have it inside my project root folder inside bin\NUnit. To run tests using nunit-console you need to pass your test assembly path to that. Also check the build order in your solution. Typically it will be Main project -> Unit Tests.
  • Choose the project properties of the project which contains unit tests in your solution.
  • In the Build Event section of project properties, choose Run the post build event list box to be "On successful build" as I want my tests to run only when build completes without error.
  • In the Post-build event command line text area it is possible to write any shell script which will execute once the build is done. So refer to the nunit-console.exe here with your target assembly path (Your test project assembly). Conveniently here you have macro's to refer the parameters you need, so the job gets easier.Check out the screenshot of my configuration in post build event.

  • Now it is time to try out the cool thing :D.
  • Every time I refactor or add code or tests you build the code by ctrl + shift + b, I can find the build run and after successful build unit tests being run as a part of build.
  • The cool thing is if the unit test fails, it is a build failure :). So I make a small refactoring I build it and with in seconds I can see if I have broken something and fix it or do a ctrl + z if needed...
Check out the output from the build and unit tests.

My Red Green Refactor cycle has just got shorter :). I have done this in the simplest way I know and it works for me. Let me know if there is a better way to do this

Also I have done this as a part of my yet to be open sourced project FluentAssertions. No spoilers now but more on this soon...

Tuesday, August 25, 2009

Using Git As A Tool to Help In Refactoring

I am a big fan of Git. Initially started as a urge to use the cool GitHub. But later when I started to realize the potential of Git itself the simplicity and power of this VCS amazes me.

As most of you know Git is a distributed version control system (VCS). For those who haven't used it or heard of it (Please come out of SVN dark ages :) please do a Google search and you will find a flood of links hitting you. What I am write speak here is about my typical usage of Git and how it helps me in day to day refactoring making it easier.

I am firm believer of RGR (Red Green Refactor) cycle. But beyond that I do a lot of micro refactorings like renaming variables, classes, moving behavior, adding tests etc as I thinking more about what I have written and finding better ways to express my code.

Now the problem when I used to use SVN is that I have only two choices. Either I pile up these small refactorings to commit in my local copy which I don't really like. Or commit each one individually and trigger the build for every small change I make. Also if I pile up and commit, at the time of commit how can I express my intentions of the commit I am making. I never like to put a comment in commit which blankly says "Refactoring and adding some tests.".

So how did Git change the picture? Git as most of you know is a two stage repository VCS. One repository may in remote server (incase of Github it does or a SVN repo if you use Git SVN) and other repository in your local machine which is also a complete repo of your source code. You can treat your local repo as a main repo and commit in it as many times as you want. This gives me a great advantage.

Every refactoring I do can be tested and committed to the repository (local one) individually. I can express my intent of the commit of every refactoring. When I feel substantial amount of work is done I can push to the remote repo and continue with my next item of work. Also when I push I can see it as a series of work I have done on a feature not as one bulky piece. Typically I have this code, refactor, test and commit cycle for every five to ten minutes when I use Git. This is one amazing advantage which I have when using Git. Similar feelings will be expressed by people who use Mercurial as well.

Also as an added advantage when build is broken and someone is fixing it I can still commit to my local repo and continue working and push my changes later. But we should be cautious not to pile up too much in our local repo that we distance ourselves with the mainline code base.

Similar thoughts on using Git and Github has been expressed by Mark Needham here.

Let me know if you have similar experience as this.

Mocks and Expressing Test Intent

Still I am stuck in the mock world. Tests have been a central part of coding life and mocks play a crucial role in them. My opinion is, test which doesn't express itself explicitly has lost its value. It may run as a part of suite but its value to the programmer as a way to understand the behavior is lost which is important.

So coming back to main topic, how mocks help in expressing your intention in test? In short mocks show a way to express constraints on how a collaborator should be used. Constraints are part of intention which in turn represent specification. Confusing as usual? Lets see an example specification and find how mock helps us to express this in our test.

Example Spec or Constraint: If I am building a Greeting application to greet in multiple languages and I use a third party translator which I need to pay for every call I make. My default language is English. So when I want greeting in English then I should not call the translator so that I don't need to pay unnecessarily.

Following is the test code I wrote for this.

public void DonotUseTranslatorWhenLanguageIsEnglish()
var translatorMock = new Mock();
translatorMock.Setup(mocktranslator => mocktranslator.Translate("English", "English", "Hello"));
var translator = translatorMock.Object;
var greeting = new Greeting(translator);
greeting.SayHello("English", "Sai");
translatorMock.Verify(tr => tr.Translate("English", "English", "Hello"), Times.Never());

The intention of this test is to see if the language is English I don't use the translator. Here I will use a mock translator because there is a constraint on its usage and I am interested in expressing this in the test. So I use a mock translator on which I set constraints of usage and then after exercising the behavior I validate if the constraint I set has been satisfied.

You may get similar constraints in your application like retry thrice for connecting with credit card processor in case of failure. Or send mail in case of critical failure in application. Such situations are really good usages of mock.

A note of caution with using mocks - Mocks are way to look into an object's working i.e. how it uses its collaborator. Unless you are really interested in this information don't use them. If your interested lies only in the behavior of the object you are trying to test, use a stub instead for a collaborator.

Monday, August 17, 2009

Mocks and Verifying Expectations

Mocks are uber cool. They are really convenient to replace dependent components as well useful in TDDing out the behavior of an object and its collaborators. But what I have seen people doing is using mock and ceremoniously verify the expectations (in case of RhinoMocks it is using VerifyAllExpectations) and I question this. Here are my views on this practice.

Example -
public void GreetInFrench()
var translator = MockRepository.GenerateMock();
translator.Expect(tr => tr.Translate("English", "French", "Hello")).Return("Bonjour").Repeat.Once();
var greeting = new Greeting(translator);
greeting.SayHello("French", "Sai");

Above test has been written using RhinoMocks framework. But the important point to note is, is it really necessary to verify if the expectation we set on translation mock is satisfied or not at the end of the test?

For me mock expectation is a form of assertion and in a test I don't like to assert on something which is not related to the behavior of the object I am trying to evolve. So when I pass a collaborator to an object through constructor or some method do I really care how the collaborator gets used or do I care the behavior of the object is as expected? Well obviously I care about the behavior and not much about the collaborator. So the assertion happens on what the object returns on exercising that behavior and not whether collaborators have been used or not.

But when would I explicitly assert using a mock? When I really care about how the collaborator gets used or there is no way for me to observe the effects of the object behavior I am testing. Situation like these bring out the need for mock.
For example

1) If there is a condition which says retry thrice to contact mail server in case of failure I set an explicit expectation to verify that the method on mock is called thrice on the failure test. Or I have a spec which says every call to translator service costs 2$. Then again I explicitly verify that the service is called once through a mock translator service.

2) Or when I am at the boundary of my system working on something which sends messages to the outside world (like sending mails or printing something on screen such methods typically return void) then I have no way to observe the effects. Again in such case I use a explicit verification to see if the method has been called on mock

So for me a better way to write the initial test is

public void GreetInFrench()
var translator = MockRepository.GenerateStub();
translator.Stub(tr => tr.Translate("English", "French", "Hello")).Return("Bonjour");
var greeting = new Greeting(translator);
Assert.That(greeting.SayHello("French", "Paulo"), Is.EqualTo("Bonjour Paulo"));

Here we use a stub for translator as I have nothing to verify against it and it is up to the greeting object to use it. I am happy as long as my expectations with greetings object is met.

Every test we write is a form of specification and mocks at times helps us to makes some of the conditions in these specifications explicit. Making unnecessary expectations will confuse the reader of the test as it mangles the meaning of what we behavior are trying to evolve.

Well... These are my views on using mocks. If you feel the stuff is really confusing let me know I will try to explain in a different way. Or if you have an alternate view lets discuss :)