Pages

Monday, April 22, 2013

TDD is not all about writing tests first

TDD's mantra:


In words:

  • Add a failing test
  • Write code to pass the test
  • Refactor

If you want to get a firm grip on this awesome methodology, read this book by Kent Beck.

However, TDD is not just about writing your tests first or to increase your code's test coverage. These are just the add-ons that you get for free when you use TDD. The mantra behind using TDD is to improve your design, to think from a consumer point of view who is going to use your components or APIs. These consumers can be anyone, it could be you, your team mates, other teams or general public.

Then, you may ask how can writing tests first allows you to better design your interfaces? Good question. Lets think about it in this way. Why we write software? One possible answer is to create some applications that does few useful things that wouldn't have been possible or too tedious to do manually. Its creates something with some intent that someone can use it. So two things that pop out: intent and use. I think that TDD allows you to get these two things right, the intent and use, while creating software. Again you may ask, still how writing a test helps you to get these two things right? Good question again.

When you are writing a test even without the code itself, the most important thing that comes to your mind is how am I going to use this component in my system or application. This makes you think about the interfaces, the parameters, the exceptions you want this method to throw. And there you design your API.

And then the other most important thing you think about what is the intent or the purpose of the code that you are about to write. What you want this piece of code to do? That is what makes you to write your assert statements.

Yes, it could be very difficult to digest this test-first approach initially if you haven't been practicing such methodology but once you do you will see the results and it value. You will be amazed to see how easy it becomes to design your components if they are easy to test.

I have been using TDD for more than a year now and I can definitely see the difference in the way I think and develop software. Its weird but TDD makes you to not to hate writing unit tests since they are the not burdensome-after-thoughts anymore.

Then, there are so many other good things that come for free when you write your tests first. It makes you confident about refactoring existing code. I am currently working on a system at Amazon that serves million of customers and allow them to play with their apps with almost zero downtime. How can you imagine refactoring such a service where a simple mistake can either lead to doing something unintended that breaks millions' of users Appstore experience or can breaks a functionality (or Appstore client) in its entirety? We want our tests to fail first in such cases. 

Then there is code coverage. You won't believe the results of running a code coverage tool on a codebase that is written using TDD approach. It does not give you a single opportunity to make the coverage better by looking at the results and then 'hack' the tests to increase the coverage since you already get an amazing high code coverage for free!

Give it a try, its worth it.

Tuesday, April 2, 2013

Few useful Git commands

I have been using Git at work for last couple of years now and I must say it has helped me a lot to be more productive and pushing out more and more features instead of either waiting for code reviews or waiting for the expensive branches (as in Perforce) to get created.

I won't go into details on how Git has helped me and why I love this tool but rather will post some very useful commands that helps to get around some very tricky situations. I found these commands from various posts while looking for solutions to these problems I encountered while at work. So yes, these are not 'my' solutions but they do work.


How to get a list of un-pushed commits in git?
Assuming your remote repository is named origin and you’re dealing with the master branch:
  
  $ git log master ^origin/master

This shows what commits are in master but not in origin/master (which is the remote branch).

This same syntax can be used to see the difference between two local branches, but will show cherry-picked commits as differences which can be confusing:
   
 $ git log master ^production

Delete last commit
To soft delete the commit before head. Alternatively you can refer to the SHA-1 of the hash you want to reset to. --soft option will delete the commit but it will leave all your changed files "Changes to be committed", as git status would put it.

$ git reset --soft HEAD~1

If you want to get rid of any changes to tracked files in the working tree since the commit before head use --hard instead.

Now if you already pushed and someone pulled which is usually my case, you can't use git reset. You can however do a git revert,
  
$ git revert HEAD

This will create a new commit that reverses everything introduced by the accidental commit.

Make an existing git branch track a remote branch?
Given a branch foo and a remote upstream, as of Git 1.7.0:

$ git branch --set-upstream foo upstream/foo

That will cause Git to make local branch foo track remote branch foo from upstream.

How to undo "git commit --amend"?
Move the current head so that it's pointing at the old commit. Leave the index intact for redoing the commit

$ git reset --soft HEAD@{1}

commit the current tree using the commit details of the previous HEAD commit. 

(Note that HEAD@{1} is pointing somewhere different from the previous command. It's now pointing at the erroneously amended commit.)

$ git commit -C HEAD@{1}

Monday, April 1, 2013

Log5j vs Log4j

Log5j is a modern facade over the most heavily used logging framework Log4j that not only provides a better interface for logging but also performs better. Even though Log5j has a lot of advantages, most of the projects (even at Amazon) uses Log4j. You will find logs like this all over the code base
    
   log.info("this is the string with value " + value + " and it does stink with factor" + stinkfactor);

All those concatenations, yuck!

I found the interface of Log5j pretty awesome, specially when it allows to you log like
    
   log.info("this is the string with value %s and it does not stink",value);

But out of curiosity, I wanted to know how good its performance is. I did a simple test and found some interesting results.

Experiment Setup
Unit tests with log4j configured with a FileAppender (similar to what every production environment uses). The log level was set to INFO (hence DEBUG was disabled). In each test, logs with different types of logging statements (with/without parameters) were emitted in a loop with a 2 million count. Randomly generated numbers were used as parameters in each loop just to avoid some optimizations that could be done by compiler if you have constant strings.

Use case Performance
(test finished in msec)
Notes
Log 4j Log 5j
Debug log with parameters
no isDebugEnabled()
using String.format() to format log statement
6184 183 String.format() was used only for log4j to simulate what log5j does internally
Log5j does not need String.format()
Debug log with parameters
no isDebugEnabled()
not using String.format()
1350 265 For log4j, logging statement like "log text" + param1 + " and other param" + random() was used.
Debug log without parameters
no isDebugEnabled()
52 142
Debug log with parameters
with isDebugEnabled() check for log4j
128 183 isDebugEnabled() not required for log5j
Info log with parameters
using String.format()
50192 45667 String.format() was used for log4j to simulate what log5j does internally
Log5j does not need String.format()
Info log with parameters
not using String.format()
34202 52207 -
Info log without parameters 31684 30958

Conclusion
  • Do not use String.format() with log4j, specially when that log level can be off in production (E.g. DEBUG is off in production). Its very expensive. 
  • Log5j performs almost the same as Log4j even without any isLOGLEVELEnabled() (E.g. isDebugEnabled()) checks. Hence, it results in clean code without redundant log enabled checks. 
  • Log5j provides a cleaner interface to log statements than Log4j (with a mess of appending variables within log text) with a small bearable overhead


Thursday, March 28, 2013

Best Software Writing

There are hundreds of blogs in the blogosphere that talks about software design, processes and methodologies, on how to write awesome code and be a better software engineer. But there are a few that not only excel in putting forward their ideas in all these areas but they give a lot more to ponder over.

Most of the people and their blogs that I am listing here, have their own unique way of pouring over ideas that makes you think hard. Some of them compliment each other, some contradicts and some are completely isolated that covers pretty much every point of view about software processes and ideas in general.

1. Martin Fowler Best known for the books like Refactoring and Patterns of Enterprise Application Architecture, he is the person to follow if you want to understand the magic behind developing software using good patterns.

2. Kent Beck He does not need any introduction but in case you don't know, he is the creator of xUnit family of testing tools and best known for his contribution to Extreme Programming and Test Driven Development.

3. Paul Graham The co-founder of the famous startup incubator Y Combinator who communicates through his essays, gives an amazing view of various aspects, from his early blogs on hacking and programming to his current passion about startups and entrepreneurship.

4. Jeff Atwood Another excellent writer who blogs almost anything and everything related to software and other topics. He is the co-founder of Stack Overflow, the knowledge bank that every software developer has to visit more than a thousand times in his life.

5. Andy Hunt If you are a fan of Pragmatic Programmer series, then you mush follow the founder's blog. His classic The Pragmatic Programmer book is the must read.

6. Joel Spolsky Most of the time this guy makes a lot of sense to me, but sometimes I think why do I even follow his blog. I guess I like to be surprised when I am reading his blogs, I don't know.

7. Steve Yegge Pure fun. Period.

I have few more that I follow but they are in my Google Reader Feedly, I will see if I can share that. Please do let me know in comments if you have any other interesting people to follow.

Sunday, February 24, 2013

Apps to improve productivity on Mac OS X



I have been using Mac OS X for almost 3 years now and over the time, I have found few apps that adds a lot to your Mac experience, specially if you are a software developer. The main intention behind using most of these apps is to use keyboard most of the times (and minimize use of the mouse). Even if you are not a developer, some of these apps still add a lot of value and improves your productivity while using a Mac. The best part - most of these apps are free! You can buy to have some extended features, but for me the free stuff is enough most of the times.

So, here are my favorite apps that should be useful even if you don't develop on mac:

1. Alfred (Free): This is one of my most favorite app that I must have used thousands of times till date. It not only allows to search - applications, files, folders - but also a number of other cool features like calculations, spelling etc. A must have for anyone using Mac.

2. Spectacle (Free): Its a great windows manager for Mac that allows you to use keyboard shortcuts to adjust window sizes and positions. The best part, it is free and open source!

3. 2Do ($29.99): If you are looking for getting things done, then 2Do is the best you can get among thousands of productivity apps that claims to follow GTD. Though it has a price tag ($29.99), its worth the money. I have been practicing GTD for last few months now using this app on my iPhone and Mac and so far very happy with the results. I will soon post my setup with this app on this blog.

4. Caffeine (Free): If you hate it when your mac goes to sleep or start the screen savers when you don't want it to, then Caffeine is the great tiny app to solve that problem. 

5. TextWrangler/BBEdit (Free/$49.99): If you are looking for a better text editor than that ships with Mac OS X, then go for either TextWrangler (free) or BBEdit (paid). TextWrangler, as the company calls it 'little brother' to BBEdit, is the stripped down version of BBEdit. I use TextWrangler as I don't need a lot of features that come with BBEdit.

6. Evernote (Free): Well, I don't think this app needs any introduction. Though I like the Notes app that shipped with Mountain Lion but still it can't match Evernote. It provides you so many features that you can't ignore. Again, its free!

These apps are more useful for those that prefer to develop software:

7. Intellij ($199.99/Free): A great IDE that allows you to write code in tens of different languages. I used to use Eclipse, but that felt like a heavy weight with lot of plugins/features that I don't need. Though their is a price tag on this IDE for their Ultimate version but its those very few apps for which I am willing to pay the money. Having said that, they do have a free Open source version but naturally with less features than the Ultimate version.
But in case you don't need those additional features, then you should try out the free version. See the comparison between two editions.

8. iTerm2 (Free): If you are a command line person like me and don't like the Terminal app that ships with OS X, then iTerm2 is the right app for you. Its a lot faster and customizable than Terminal app.

9. HomeBrew (Free): As the project page mentions, it is 'the missing package manager for OS X'. If you crave for all the wonderful *nix apps, then this is the right app for you. Its amazingly easy to install and use.

10. Mutt (Free): If you are overwhelmed with the email apps like Outlook, and prefer to read your emails as text and be more productive while handling your email then you should go for Mutt. There are a lot of references on web to setup and run Mutt on Mac, this is one of my favorites. But be aware that this isn't prettiest of all and might take you few days to setup and get used to it, but once you do its a great tool.