RSpec and Recurring::Schedule
After a long week agonizing over a scheduling library, and then specing it out rather quickly, I've got some work I'm pretty happy with.
As a contrast to Test::Unit, I like the way RSpec spreads my attention around the codebase while I concentrate on implementing specific behaviours. In Test::Unit, I tend to write tests around the private methods of the object under test.
So far I haven't involved RSpec in tests of object interactions, so I haven't had a chance to use the mocking features. I use Mocha for Rails sometimes, so I'm excited to see how it feels under spec.
The nicest thing about the writing process was thinking of my library (just one class, Recurring::Schedule, for now) through the lens of it's public API. A few months ago, I made an attempt at this library, using Test::Unit, and results, while they functioned as prototype for weeks while we worked elsewhere, were nigh unrefactorable. Writing from scratch with RSpec gave me a faster library, in less time, with less code, while worrying less about code duplication.
My previous TDD attempt had all these fancy metaprogramming methods and whatnot, which I completely dropped in the rewrite. I think that's thanks to the way RSpec spreads your efforts around the codebase as you iterate over specs and code. With Test::Unit, I usually think really hard about what a method has to do, and then write it test first, and it comes out looking beautiful, with tightly woven ruby knots.
With RSpec, I don't have to think, at least not hard, and all at once. I build up behaviour, a little at a time, filling in the methods when I need to.
by Pat Maddox, 2006/12/08 10:44:04 +0000
I really like using RSpec as well...it takes a bit of getting used to, particularly when using mocks for testing object interactions. In one library, it led to my specs being brittle and and the code unrefactorable. Whenever I changed the code, I'd have to change the specs to go along with it. Which makes sense, because I'm testing the interaction, but still it's a pain...and to preempt anyone who says that if I change the specs/test then it's not refactoring, well that's wrong, because I'm not changing the observable behavior of the system.
So I'm still trying to find that sweet spot I guess...certainly developing with RSpec leads me to a better initial design - but of course most of our time is spent in maintenance. I don't really like state-based testing anymore because it feels like it breaks encapsulation, and I tend to arrive at a worse design. But then again it's much easier to refactor, because you're only dealing with the results of method calls. We're doing OOP though, so shouldn't it be "tell, don't ask"? As I mentioned, when I do interaction-based testing I have to modify the specs along with the code, which sucks.
Sorry for getting so wordy. I realize I haven't actually said much, so I'll just link to Martin Fowler :) "Mock aren't stubs":http://www.martinfowler.com/articles/mocksArentStubs.html provides a good discussion on state-based vs interaction-based testing.
You said you haven't used RSpec for specs involving object interactions. Since I'm sure your code has plenty of interactions, I'd be interested in seeing some of your current specs, as well as knowing how you are currently testing interactions.
by Chris Anderson, 2006/12/08 23:06:11 +0000
Pat, Thanks for the comment. As far as object interactions go, I really haven't used RSpec for testing them much yet. The scheduling library I wrote has one principal method include? which takes a Time as an argument. So my contexts just initialize different schedules, and specify that they behave as they should (ie that they include the proper times, and don't include wrong times.) I don't think I'll ever end up changing these expectations, even in a major refactor - they are just obvious, to humans, and the challenge is getting the machine to implement them.
But I am planning on releasing the lib on Rubyforge, so I'll blog about that when I do.
by Ed Howland, 2006/12/17 01:43:01 +0000
Hi Chris,
I am interested in RSpec for the same reasons as you. I also use Mocha and Stubba in my TDD. But the latest versions of each gem conflict with each other. They have name conflicts as RSpec is trying to replicate what Mocha mocks and stubs can do. I have tried with no success to re-integrate to no luck so far.
They have mentioned that there may be a mock framework plugin to RSpec so you can use Mocha or FlexMock etc. But this is a while off. Pity too, because these are two of the best-of-breed in this area.
Ed
by Chris, 2006/12/17 21:12:21 +0000
Ed,
The "RSpec users mailing list":http://rubyforge.org/mailman/listinfo/rspec-users is very responsive, and you can easily have an impact on development, as the project leads are eager to hear about real-world usage.
Chris