RCov measurements
I’m busy setting up a Rails development project at a client site, and we’ve chosen to use rSpec for specification/testing, and rCov to report coverage. They work quite well together, but there’s one caveat – classes that aren’t loaded don’t appear in the coverage report at all, so for a single class there’s effectively no difference between 0% coverage (no tests at all) and 100% coverage. Of course this is an oversimplification, since Ruby loads files, not classes, but it’s a good enough approximation on most projects, and there’s clearly some sort of problem regardless of the details.
Our solution has been to force rSpec to load everything in app/models and app/controllers before the specs are run. We do this in the rspec_helper, and since this is loaded multiple times (on different paths) it’s also useful to restrict this code so it only runs once.
First, here’s the code that loads the models and controllers:
class ForceLoader
def self.run
["models", "controllers"].each do | app_component |
directory = File.join(RAILS_ROOT, "app/") + app_component
Dir[directory + "/**/*.rb"].each { |file| require_dependency file }
end
end
end
There are two things to note about this code:
- we use require_dependency for consistency with other Rails loading, rather than require or load;
- we need to ensure that the path of the file passed to require_dependency is the same as the path used by default by Rails. Ruby loading is path passed, and if you refer to the same file with two different path representations you may load it twice.
Next, let’s look at the code that we put in rspec_helper.
begin ForceLoader rescue require File.dirname(__FILE__) + '/force_loader' ForceLoader.run end
If we can’t reference ForceLoader we load it and run it. Once the class is loaded the rescue code won’t be invoked, so this ensures once only execution.
Hopefully this approach will give you more accurate coverage reports with minimal overhead – it’s certainly uncovered at least one problem on our project so far. It can also be extended to cover other parts of your app in a fairly straightforward way.






What are you thoughts on the benefits and disadvantages between .Net and Ruby?
I read one poster who said he found he could do in Ruby in a day what took him a week in .Net. Would you agree?
I don’t work in .NET, so I can’t do a comparison.
For simple CRUD development, say for personal use, the difference between Rails and something Java based is incredible since you can do most of it automagically.
When I know how to do something in Rails it’s (so far) always been faster than doing it in Java, but I still know less Rails than I do Java.
I have seen the demos of Ruby, in it building tests and a blog.
The trouble I have always found with fast code generators is that:
they are great when applied to a particular task – however customer’s may sometimes want a feature which can’t be done by the auto-code, and then you are in trouble.
Using them correctly requires understanding the framework intimately. I can remember working on some .Net projects where built in features where used in very strange/confusing/inefficient ways because people didn’t understand the framework. (Analogy: like using a hammer to under screws.)
the third problem would be that autocode generators force people to think about problems in terms of the autocode generator. As development is about finding good/cheap/simple solutions – I don’t know if this is a good thing.
Have you found the same in Ruby? Your thoughts?
Code generators fail when they are used as workarounds for missing abstractions in the underlying tools. This is frequently correlated with the volume of code produced. The problem is exacerbated if developers are expected to maintain the generated code. The Ruby generators that I’ve used (and it’s been a while since I’ve done much with generators) produce small quantities of code, and I’ll contend that most of this code is intended to be replaced rather than maintained. This intent is conveyed with the name ’scaffold’ – something to support you in the short term, and to be torn down when over time.
Also, I did cryptically say “automagically” rather than “generated”. I’m using Active Scaffold for administrative aspects of my application (things the public never see), and it doesn’t generate anything. You can choose to use Active Scaffold as a scaffold, or you can learn more about the active scaffold framework code and make small changes yourself.
People certainly use frameworks without understanding them. It would surprise me if that wasn’t the case, since that would make frameworks an exception – people use all sorts of things without understanding them. Languages, IDEs, operating systems, power tools, automobiles and televisions just to name a few. People who invest time in deeper understanding often find ways to use things better – whether that investment is worth it is context dependent.
Tools, code generators or not, have strengths and weaknesses that need to be considered, and generally act as constraints on solutions. There’s nothing inherently good or bad in this. It’s a challenge, and one of the reasons experience will continue to be an important part of software development (and most other human activity).
Ah – I see where I’m getting confused.
I haven’t seen Ruby, but I saw the demo of “Ruby on Rails”. That was the code generator which created the blog/tests which I was thinking in terms of – though I could still be off-the-mark on this one.
I will look into this scaffolding though – it sounds pretty cool.
Dave,
I was talking mainly about Ruby on Rails, though I’m sure there are different ways to approach Rails.
Oh.
I don’t know enough about Ruby to talk/ask good questions about it.
I was very impressed by:
Languages, IDEs, operating systems, power tools, automobiles and televisions just to name a few. People who invest time in deeper understanding often find ways to use things better – whether that investment is worth it is context dependent.
Thought that was quite profound.