Monday, March 05, 2012

cover_me for standalone Ruby


I am working on this small home project of my own exploring various aspects of Ruby language while building something useful for myself. I will tell more about what it is once (if :) it's ready.

Part of the techniques and things that I am trying is TDD. Like I heard the other day on the Ruby Rogues podcast, the right response to "testing is hard" is not "let's don't test", it's "let's get better at it". I also wanted to see if I really can put my mind in a position to think "backwards" when designing an API. When you start with a test you basically first define how you use it and only then go build it. In theory it should lead to a cleaner easier to use API as well as help with the whole YAGNI thing. Instead of doing all those extra behaviors the users might never need you would focus on the critical things that make it useful.

I like my TDD experience so far. I find that it disciplines me to focus on things that matter. Without writing the test first I am more likely to think wild and do some yak shaving, you know. It's likely much less apparent that you're building a not needed feature or doing a premature optimization than it is that you're writing a meaningless test. Starting with the test makes me think of what I need and then I am obligated to build that thing that I need or my tests suite fails. The whole red-green-refactor cycle. It's fun. You should try it.

Having done it for a little while I thought I would measure my test coverage. Enough was said about how it doesn't necessarily mean a lot to have your code "covered", how striving for coverage alone you get your code exercised but not necessarily tested, how there are different levels of coverage, etc. Still I wanted to measure.

Ruby 1.9 comes with a built-in experimental coverage feature that does runtime instrumentation and collects the metrics. There are simple gems out there that leverage it to get the data out and build coverage reports and cover_me is one of them. You basically require 'cover_me' in your test suite and off you go. Almost.

If you do just that you will have the coverage.data file but no reports. Here's their github issue #20 that talks just about that. Running CoverMe.complete! from irb or pry is one of the recommended solution, as well as doing rake cover_me:complete. I did like neither as I wanted it all "out of the box" and working even when I simply do ruby test/test_all.rb. And here comes the beauty of Ruby being dynamic and interpreted language. Any external library you have in your gems can be opened up and looked into. A few minutes (or hours, or days :) of looking through the code and you know what it does and what it needs to do what you want. I first posted a dirty way of doing it and then came up with a much cleaner solution that doesn't require tapping into the cover_me sources. Maybe someone will find it useful. I guess the best way would be to wrap it all into a rake task and just run my test suite along with the coverage steps as one rake command. Next time.

p.s. I know that I shouldn't be using Windows to do Ruby development.

No comments: