This blog contains reflections and thoughts on my work as a software engineer

torsdag den 17. juli 2008

Antipatterns exception testing

During my first encounters with Test Driven Developement (TDD) I adopted the ExpectedException attribute and used it heavily when coding - that is: I focused a lot on testing for every exception written in the code.

I have come to the conclusion during the last few weeks that my testcases didn't provide very much value if you test heavily for exceptions. There are a few bulletpoints to mention here:


  • Tests written for testing errorconditions on general exceptions (ArgumentNullException etc) are not important. You should write exceptions for ArgumentNull etc. etc but I don't test for them anymore. Focus your testing on things you can assert instead - a test which throws an error will fail the test so even if you don't write an explicit test for the error condition your test will still fail you if the error occurs. Never ever aim for 100% code coverage - if you do you are walking a deathmarch.
  • Business value exceptions are on the other side very important to write tests for. If you have custom exceptions classes which you throw when i.e. a business rule fails to validate you should write a test which succeeds only if the error is thrown. This provides business value: You know that your business logic works because you get your expected exception thrown
  • If you throw exceptions in your code WITHOUT explaining what went wrong I will hunt you down and shoot you in the legs. Not very pedagogic indeed but exceptions are only useful with a meaningful description of what went wrong. You are giving the consumer of the exception no data to help figuring out what went wrong.
Which best practices on this issue do you reccommend to others?

onsdag den 9. juli 2008

Rhino + VS debugger == WFT?

We have used the MVP pattern lately in my recent project to increase testability and decouple the UI from our business logic. To enhance our testing environment we have begun using Rhino Mocks and it is an overall satisfying experience even though I am still having a hard time "getting it right" when writing tests.

I want to share with you one of the "What The F***" experiences I had just a few minutes ago: One of our mocking tests failed. Well - insert a few breakpoints and fire up the debugger. And then it happened: For every time I ran my test I had errors on different lines in my source code... Most of the times I had a NullPointerException but at other times the Rhino framework threw mysterious errormessages at me...

I was a little scared to see a unittest behave like this for twenty minutes and really had no clue what was happening but my collegue was able to solve the puzzle once I asked around for a little help. What had happened was that in my MVP Presenter I had set up an mock of my view and some expectations for different properties to be called during OnLoad. They should be called just once so when you start using your debugger's Quickwath on those properties you "use up" the quota of expected calls. You are actually fulfilling the expectation you just set up when quickwatching a property in a test with expectations set Rhino-style... And when the code afterwards tries to execute the code you intended the expectation to test for your test fails because you only set your property up for being accessed just once.

Lesson learned today: When a test which uses mocking fails you - clear all breakpoints and try again. It actually solved the mystery and I was able to fix the initial cause of the error within a few minutes.

torsdag den 3. juli 2008

Firefox - not just another browser

Disclaimer: Lots of people have written this post before me. Don't come back and tell me that you haven't heard this one before ;o)

*****************************************************************

I am usually very relaxed when it comes to the tools I am using - I use whatever suits my needs and strive not to be very religious about who created them and if I am using the newest version or not.

I have used Internet Explorer for quite a while (always actually). I have tried a few browsers over the years the latest one being Maxthon which was recommended to me by one of my former collegues. It never hit the spot mainly because I didn't give it a real try - I didn't spend enough time to see what extra value it could provide me because it seems to be a quite successful browser variant.

However - I must admit that the new Firefox 3 is amazing mainly because it is so freaking fast. It feels like I just had my computer upgraded to a bigger processor and doubled my RAM. This is the first browser I have begun to use as frequently as Internet Explorer - simply because it is better than it's competitor. The addins are also extremely powerful - they have been around for years but the vast amount of plugins written for Firefox is simply amazing. If you want to do something whatever it is - searching, social networking, image grabbing, resizing, debugging... Somebody is likely to have written a plugin for Firefox which enables you to do whatever you want to quicker and easier than before you discovered the plugin.

Speed + extensibility = I love it. IE isn't a bad browser at all but they should really be careful not to be become a has-been. Jugding by these figures IE still wins the socalled "browser war" but they are about to loose precious market shares unless they saddle up and start producing something of similar star quality.

Regards K.

tirsdag den 24. juni 2008

Fusions for dummies

Does anybody know where to buy the "How to merge IT-infrastructure and culture of an organization - for dummies"? Well... My company is about to take part in a fusion which will give birth to a unified organization responsible for all sorts of athletics, sports and excersise in Denmark. Today we had a meeting where we discussed various issues concerning IT-migration stuff and various non-tech and tech. related issues. This is a quick summary gathered from my personal experiences and beliefs - it does not relate at all to anything other than my personal view on how to do things "the right way":

Do figure out a way to quickly deliver some shiny new functionality It sounds like an anti-pattern but it will make you and your current organization shine. It will also help positioning you and your team as a neccesary and vital part of a future IT-departement. Sometimes (most of the time, actually) people in charge doesn't have a clue about what's right and wrong in the world of software development - they however are in charge and do prefer shiny new stuff rather than a Powerpoint filled with techstuff which are very sexy if (and only if) you are a software developer.

Nothing good comes to he who waits. Be aggressive and argue your case to ensure that it is your concept and strategy which will lay the foundation of a new IT-infrastructure

Plan an internal plumbing-strategy to refactor old technical debts to a more smooth and agile solution. Focus on the most basic principles and stick to them. Get used to release often - in the wakening of a new organization waterfall strategies are doomed to fail miserably so you will have to be able to deliver quickly as Product Owners find themselves in the process of getting to know your new organization.

- People before you have lost wars because they won the wrong battles. Don't spend time upgrading your backend support system even if it sucks and lacks basic features - you can be pretty sure that a new one from another company will be planned for in a new organization. It sucks, right? And you argue your cause, so you have the arguments ready to convince the new IT-boss that the system should be discontinued in a new organization. Your frustrations will end on a specified date - don't waste precious time on upgrades if they will not survive the birth of a new organization

Be agile! (can you see the yellow glow above my head?). Don't expect anybody to be able to answer questions about the future so get used to living in a world of chaos. Be pleasantly surprised if you get guaranties and precise directions but don't be overly disappointed if people fail to answer to your frustrations. They don't fail because they want to displease you - they simply does not have authority or plain out doesn't know any better than you do.

Regards Kristian

onsdag den 18. juni 2008

The infamous Save() method

We (a collegue and myself) had a little infight a few days ago during a pairprogramming session - I advocated for having all Save() methods being void and parameterless whereas he didn't see any problems in having them returning objects and/or taking input parameters at will.

I couldn't at that time argue my case except that I saw this as a violation of the SoC (Separation of Concerns) principle - and why force the consumer to handle a return value if the consumer doesn't need to have one? The discussion grew a little ugly at some point but yesterday just before leaving the office we talked it over again.

It turned out that my collegue's experienced with TDD for various reasons has not been overly positive - having to figure TDD out for yourself without having some sort of experienced mentor inhouse will lead to frustration in 95% of all cases once you try to use TDD in a real-world scenario. We argued about having a signature of Save() methods in general and I understood my own reservations when we discussed what would happen once the signature of the Save() method changed because we i.e. wanted to introduce a new parameter in a call to Save() - example:

public void Save(string a, string b, int c)
{ ... }

was to be extended with:

public void Save(string a, string b, int c, List d)
{ ... }

What happened in his mind was that the compiler would burp on all places where the Save(a, b, c) was used so you had to change the code of your tests in all places.

What happened in my mind was that you had to change all working tests using the infamous Save() method because you changed a single signature of a method. This is bad because

1: The time spent maintaining your tests should be kept at a minimum
2: You could be mislead to work around changes in your model to avoid having to alter your tests to reflect that change - and THAT should ring the alarmbell.


Conclusion:
1: Having simple method signatures should be a goal in itself to avoid breaking the code of your tests when you want to introduce new functionality and parameters which needs to be carried around in your application.

2: Do use objects to carry around parameters for you. Less code is needed and the readability of your code is much higher. Having i.e. an object carrying 10 primitives around your model is much more extensible than having to extend every class with a property for param #11.

3:
You should not be afraid of having "dead" objects in your model and view which can only contain data. They are keeping the numbers of properties and overloaded methods in your application to a minimum :o)

Related articles:

TDD antipatterns (I don't agree to every one of these but it is a good checklist)

This guy suggests best-practises for API design:
How to design good API's

torsdag den 12. juni 2008

Inversion of Control article

I finally found an article which explains the IoC concept and value of using an IoC framework. I think I grasped the concept quite a while ago but what the value of this IoC thingy was remained unexplained to me...

http://www.ytechie.com/2008/06/i-finally-get-the-point-of-inversion-of-control.html

onsdag den 11. juni 2008

The Pareto Principle

Did you know that the 80/20 rule is also known as the Pareto Principle? I sure didn't ;o)

Check it out on Wikipedia

/ Kristian