The problem with learning RSpec

So… In the recent five-hundred-and-forty-seventh iteration of the
“What’s the point of mocks?” discussion on this list, David C.
ended a message with:

[ . . . ] Really, I think
that’s what we should all be striving for. Not so much “should I use
mocks or not,” but “when should I choose to use them?”

And here… Here you made me really pause and think.

David: Now that you’re a Pragmatic author – have you read Andy’s
Pragmatic Thinking and Learning? Damn good book. The most valuable
part of it to me was in the first couple of chapters, which laid out
the Dreyfus model of skill acquisition. Having learned about it a few
months ago, I’m starting to see it everywhere now. I don’t intend to
rehash the whole theory, but it basically says that the development of
a skill (any skill) follows a predictable pattern:

  1. Novice (needs clear checklists or recipes; not ready for theory or
    problem-solving)
  2. Advanced Beginner (can solve typical problems and alter the recipe
    within parameters)
  3. Competent (understands the theory behind the recipes and can act
    creatively)
  4. Proficient (acts on principles rather than recipes; using the skill
    is nearly automatic)
  5. Expert (defines and innovates the field; works on intuition rather
    than rules)

From reading a fair amount on TDD/BDD – including the Rspec Book – I
think there’s widespread consensus that learning TDD/BDD is a totally
separate skill from programming itself. One can be an expert
programmer with decades of experience, but still be at zero when it
comes to writing and using tests. (Or even an “anti-learner,” hostile
to the concept itself.)

My thesis in this message is that there is a hurdle built into
learning the skill of TDD/BDD with RSpec: that there’s a steep curve
somewhere in the early part of stage 2 – “Advanced Beginner” – that
makes it more difficult than it ought to be to ascend to competence.
The hurdle is that some easy things are easy, but other easy things
are very complicated. Not just hard to do, but hard to learn. Hard
to understand why stuff works.

The tasks where the curve begins can be identified by following the
high-level trends of conversations on this list. Usually it’s on
Rails. Models are easy enough; heck, models are fun. But then we try
to do controllers, and… Boom. Brick wall. You can run the
generator, but… What is it doing? How do you change it? Let’s say
I’m a novice to Rails, too: what the hell is that routing spec?

That last sentence is the sharpest way I can think to phrase the
problem. “What the hell is that spec?” Rails is easy to start
rolling with for the default use cases, but moderately hard to
understand when you’re ready to do more complex things. Its nuances
are scattered in a lot of places, and some of the connections are
invisible. RSpec on Rails, even in the default cases, exposes more of
those nuances and requires you to understand them. ActiveRecord
stands on its own, so models are fine (and views are mostly just
tedious) but you can’t even begin to understand that generated
controller spec until you understand Rails and all of its nuances
better.

And if you’re trying to learn both at once? And you don’t want to go
deeper into your Rails code until your specs pass? …Learning
deadlock. The failure to understand one keeps you from making
progress with the other. In the ideal case the specs would help to
teach you Rails, but in practice it doesn’t work that way. They specs
are too opaque without Rails knowledge.

When I set out to consciously learn this stuff, I was determined to
really learn it. I didn’t want to type any code I couldn’t
understand. So I ran the RSpec scaffold in a ‘dummy’ app and used it
only as a reference to build my own by hand. The first controller
spec I tried was for a nested resource with parent and child objects.
(Bad choice perhaps.) It took me almost two days to write that first
full spec with all the mocks and stubs, and get it to pass on every
action. I was on contract and even to me that felt hard to justify.
And then I had to deal with authentication and filters, and then I
felt the pain again.

I’m a stubborn ass, so I plodded through. Eventually I even figured
out what I was doing. (I think.) But I believe I have seen people
run into this curve and view it as a brick wall. Many give up,
sometimes concluding that RSpec is beyond them – after all, everyone
says it’s “easy,” so if they can’t write a controller spec quickly or
see the immediate value of this stuff, they must be too dumb for it.

It isn’t just Rails either. That’s the most common entry point, and
controllers seem to be the most common wall. But I hit a wall again
when I needed to write an adapter for a complex SOAP interface,
building some abstractions on top of soap4r. “Where do I start?” was
quite hard for me. I fished around for blog posts and examples to
give me some precedent. Eventually I figured out a reasonably
efficient way to mock out the SOAP responses without building a whole
fake server, and I think I’m better for the exercise. But as soon as
I got beyond “this is all my code, so I understand it,” I hit that
curve again.

…This is a real problem. It’s not entirely the fault of RSpec (in
which I include RSpec-Rails) as a framework. Some of it’s built into
the ideology: some types of systems really are hard to specify or
interact with, and we don’t acknowledge that enough. Or we say “If
it’s painful to specify you’re doing it wrong.” Not always true, and
a dangerous statement for a novice who’s only feeling the sorts of
pain everyone feels when they first begin exercising.

Some of it’s built into Rails and “Rails-like” MVC frameworks This is
off the topic here, but I can’t shake the feeling that if DHH had had
RSpec from the very start and applied some of its philosophies
faithfully, Rails would be different in some fundamental ways.
Instead, some things are coupled in ways that require RSpec-Rails to
jump through some weird hoops. It all works, but it isn’t all
simple. And beginners can’t grok beyond simple.

Some of it’s the fault of the community. The problems I see here are
subtle and certainly not malignant. This list, for instance, is
excellent for its purpose – it has probably the highest
signal-to-noise ratio of any active technical list I follow, and
everyone’s eager to help at every level. I’ve never seen anyone
sniped at for asking beginner questions. That’s great. But the
questions and the answers are both coming from such a broad range of
skill levels, and sometimes that makes for a disconnect that’s tough
for learning.

That’s what I saw in the quote above that triggered this weird polemic
from me. In the Dreyfus model, there’s no question that many people
here would be classed as Expert – almost by definition in David’s or
Aslak’s case. Me, I see myself on the level of “mid-to-high
Competent, struggling toward Proficient.” Whether that’s accurate or
not, I’d be the wrong person to say. Studies show that most
incompetent people are very bad at gauging their incompetence, and I
might be one of them. Studies also show that Experts are generally
not good at teaching Novices, because they no longer think in terms
of rules and recipes. Making an Expert follow a recipe is terribly
frustrating and a waste of everyone’s time. OTOH telling Novice “use
your own judgment” is even more frustrating – and may result in the
loss of that Novice. The Novice doesn’t have his or her own
judgment yet.

When we say things like, “I think that’s what we should be striving
for – not ‘should I use mocks or not,’ but ‘when should I choose to
use them?’” …That problem is, if we buy into that Dreyfus
hierarchy, that is a harmful statement to deliver to an audience
that’s broadly distributed along the skill curve. The question of
“When should I use X?” is an appropriate question for someone at
Competent or Proficient levels. But it would be very challenging for
most Advanced Beginners to suggest an answer, and a Novice wouldn’t be
able to answer it at all. (As for Experts: they probably don’t even
need to think about it. They just know.)

We need more awareness of this. It’s not a bad thing, and I think
there are probably more benefits in having a skill-level-distributed
list like this than to set up some sort of “beginner’s” or “learner’s”
list or anything. (For one thing, most programmers who’d benefit
would have too much ego to join it.) We just need to recognize – and
I include myself, as I spun off the theory tangent in that last
thread – that a Novice question needs a Novice or Advanced Beginner
answer, and that saying “It’s really more complicated than that” isn’t
helpful to certain classes of question.

Community-wise: I also think we need better learning resources. The
RSpec Book is great. Followed faithfully, I have a hunch it can bring
an Advanced Beginner up to Competent with remarkable efficiency. I
think it could work as well for some Novices. But not all. It
depends on their thinking patterns, and whether they need or want to
be grounded in theory before they get going with the recipes. The
Mastermind puzzle is a good starting exercise, but there’s too much
explanation going on before the rest of the practical reference
begins. (Again, for some people. This was my impression. For
others it might be just right.)

The RSpec.info site is…problematic. It’s quirky in its information
structure, and I’ve gotten lost sometimes clicking around to find
something I knew was there. I don’t feel comfortable pointing
people to it as a start-from-zero starting point. The explanations
are clear and up-to-date, but it’s hard to find a handhold. The
Peepcode videos worked better for me, though they were a bit too long
for my ADD-driven brain.

At one point I was going to write a “Getting Started With RSpec” sort
of primer. It was going to be informed by my own growth curve, and
truly start with “Step by step, okay, just do this.” No generators,
write the code by hand, but get actual specs working quickly in actual
projects.

Of course, my “do this” would be somewhat different from David’s –
I’ve been vocal enough about doing a lot of my tests a different way
– so I felt a bit awkward about breaking from orthodoxy when I don’t
feel like an expert myself. But I felt bold. I started it, got a
little distracted and overplanned the demo app (a wiki to host the
primer itself, but I wanted some new sorts of features) and it’s
languishing. This thread makes me wonder if I should put a little
more foreground time into it. Not the stupid wiki, but the document.

I’m rambling now, and I’ve spent way too much of my workday on this
message, so I’ll just summarize:

  • Some easy things are complicated in RSpec;
  • Incomplete understanding of RSpec and a framework being spec’ed can
    create learning deadlock;
  • Novices need different answers than competent practitioners;
  • The community as a whole should be aware and respectful of the
    growth curve difficulty.

If anyone had the patience to read this far, any thoughts? Am I
identifying real issues, or am I just full of hot air?


Have Fun,
Steve E. ([email protected])
ESCAPE POD - The Science Fiction Podcast Magazine
http://www.escapepod.org

If anyone had the patience to read this far, any thoughts? Am I
identifying real issues, or am I just full of hot air?

Hi Stephen,
I did in fact read your entire message, but I’m running out of time so
I’m afraid I can’t reply with the thoughtful response that it deserves.
Here is my brief gut reaction… I totally agree about your observation
WRT the Dreyfus model. I’ve thought about how how it relates to TDD/BDD
in the past and have made similar conclusions. I think you are spot on
about an expert not being able to really answer a novice’s question very
well… because they are suffering from the “curse of knowledge” and it
is hard to remember what it was like without all that knowledge.
In general though I don’t know if I really see all of this as a problem
specific to RSpec. The problem is that many people coming to RSpec are
not just RSpec novices but are in fact TDD novices (and Rails, and Ruby
novices too boot at times as well!). TDD, like you said, is a skill
apart from programming and is really separate from learning the
mechanics of RSpec. A well practiced TDDer without much Ruby experience
is in a much better position to use RSpec effectively than an
experienced Ruby dev with no TDD experience. So if the real problem is
that people don’t know TDD/BDD I think outside of the RSpec community
there are a lot of resources to draw on. There are great TDD books in
addition to lists dedicated to TDD, presentations on TDD, etc…
Perhaps one step would be to link to these resources? I also agree with
Rick in that it just takes experience to learn this stuff since the
answers to questions are so context specific. Anyways, I gotta run, but
I those were some of the thoughts I had.

Thanks,
Ben

On Thu, Jun 11, 2009 at 2:48 PM, Stephen E.[email protected] wrote:

David: Now that you’re a Pragmatic author – have you read Andy’s
within parameters)
3. Competent (understands the theory behind the recipes and can act creatively)
4. Proficient (acts on principles rather than recipes; using the skill
is nearly automatic)
5. Expert (defines and innovates the field; works on intuition rather
than rules)

And look at the chart in the section “Is a Ruby Code-base Hard to
Understand?” in the article which Martin F. just published today

It shows a curve of the usage of metaprogramming in Ruby as the
experience of the programmer progresses, along with annotations about
what the thoughts about the technique during the leaning progression.

The progression goes:

Attitude Usage
Scary and bad low
Scary and good at the high end of the sensible range
Obvious and good high in the “over usage” range
Obvious and bad at the high end of the sensible range

The real key to mastery is gaining experience by making mistakes and
learning not only techniques, but the trade-offs in when and when not
to use them.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Ben and Rick,

Thanks very much to both of you for the encouraging responses. Your
reply, Ben, came just in time as I was starting to wonder if I had
made a complete and irrevocable ass of myself.

On Fri, Jun 12, 2009 at 10:36 AM, Ben M.[email protected] wrote:

In general though I don’t know if I
really see all of this as a problem specific to RSpec. The problem is that
many people coming to RSpec are not just RSpec novices but are in fact TDD
novices (and Rails, and Ruby novices too boot at times as well!).

FWIW, I agree totally. In fact I re-read my message last night, and I
want to retract one of my statements for sure: the statement that
RSpec makes “some easy things easy, but other easy things very
complicated.”

On deeper thought, I don’t believe this is true. RSpec doesn’t make
anything harder than it already is. There’s nothing wrong with
RSpec in this sense. I think a more incisive statement would be that
with RSpec, some complicated things feel like they should be easier.
If only because other things feel so easy. And newbies tend to
confront those problem areas at a point in the growth curve where the
complexity can be misinterpreted as them Just Not Getting It. Some
are driven off as a result.

You’re right about practice. You’re right that bringing together too
many learning curves at once creates interference patterns that
shouldn’t be blamed on RSpec. And Rick’s reference to Martin F.'s
spiked learning curve – “this is scary, this is nifty, WHOOPS I
overdid it, this is okay in its place” – is an excellent point.

But I don’t think it’s totally out-of-bounds to frame it as an “RSpec
problem,” even if it isn’t RSpec’s fault. The thing is… Well…
There are opportunities here. If RSpec – along with its tools and
resources and culture – was a little better at some of this stuff,
how much easier would it be to learn everything else?

How many of us learned BDD at the same time we learned programming?
…Show of hands? Anyone? The only developers who could make that
claim would have to be pretty fresh out of the pond. If that does
apply to anyone reading this, please speak up – I’d like to hear your
thoughts on how you’re doing.

How many of us used TDD or BDD out of the gate when we learned Rails
or Ruby? This is plausible, but I get the sense it’s uncommon. Most
of us don’t even think to work on good testing practices until we
believe we’re getting the rest of the stuff down. I know I didn’t.

Formal education in programming doesn’t help. Not by any evidence to
my eyes. I’ve recently started seeing someone who’s majoring in CS at
a well-known university, and he said the first class he took on
software design was in C. Frickin’ C. Then they did C++, and
then Java, but there was nothing significant about testing. I told
him about Cucumber and it made his heart go pitter-patter.

The teaching resources for Rails and Ruby don’t help. Just about
every book makes a nod toward testing – there’s always a chapter,
they always say “do this constantly” – but the chapter’s inevitably
somewhere near the back, after everything else has been introduced.
Rails culture is passionate about testing, but most of us don’t start
to tap into that culture until we’re at ‘Competent’ or above.

What if the world were different? What if teaching were different?
What if the predominant lessons people used to get started with Rails
did not start with “Type ‘rails’, make a scaffold, watch it fly!”
but instead started with, “What’s the most important single piece of
information in your app? Okay, great. Write a spec like this. Now
open up this file in /app/models… […] Your spec passed, you’re
cooking! Now let’s spec a view so we can see that information… Now
let’s spec a controller to bring them together…”

(Even better would be to start with Cucumber, which would take up very
little extra overhead in that type of tutorial.)

You get the gist. What if learning Rails was all about learning
BDD? Would it make the Rails stuff easier to understand and develop
competence faster? I hypothesize that it would.

Some things need to be easier in BDD before we can get there. To me
that means things need to be easier in RSpec. I believe my tutorial
above would be easy enough to do today on the model side, but it’s
just too cumbersome to write a view or controller spec. You lose that
“holy crap look how fast this is coming!” vibe which is so
invigorating when you’re doing something new. We could make that
tutorial happen when writing a controller spec takes about as long as
writing the controller code. There are some mitigators for this –
the Shoulda macros may be great for this now that they work with RSpec
– but even so I think it’s probably a little bit of wading into the
swamp.

I would like to see that world. I’d like to help make it. That
college guy I’m dating has asked me about learning Rails – but I’m
planning to talk his ass off about Cucumber and RSpec before I agree
to help him with code. I’m hoping he’ll be my experiment to test my
hypothesis, and I’ll get a better sense of just how easy or hard it is
to learn agile Web development if BDD happens at the ground floor.

Given time, I think the patterns facilitated by RSpec could
completely revolutionize the way software happens everywhere, if
the next generation of developers come to learn it first and not as an
“add-on.” And that’s why I’m picking on RSpec. I can’t think of any
other technology in a better position to make this happen, with only
some moderate shifts of emphasis in both the tools and the culture.

Does anyone else think that’d be pretty cool?


Have Fun,
Steve E. ([email protected])
ESCAPE POD - The Science Fiction Podcast Magazine
http://www.escapepod.org

test

Stephen E. wrote:

really see all of this as a problem specific to RSpec. The problem is that
anything harder than it already is. There’s nothing wrong with
spiked learning curve – "this is scary, this is nifty, WHOOPS I
claim would have to be pretty fresh out of the pond. If that does
apply to anyone reading this, please speak up – I’d like to hear your
thoughts on how you’re doing.

How many of us used TDD or BDD out of the gate when we learned Rails
or Ruby? This is plausible, but I get the sense it’s uncommon. Most
of us don’t even think to work on good testing practices until we
believe we’re getting the rest of the stuff down. I know I didn’t.

When learning a new technology I generally don’t bother with testing let
alone TDD (unless I think TDD could help the learning process). It is
like spiking and most of the stuff you are creating is throw-away code
that won’t need to be maintained. There are times, like this, where
testing isn’t needed IMO. But that isn’t really your question is it…
You’re wondering what effect teaching good testing practices up front
would bring… I’ve wondered this my self at times (in fact I’m helping
prepare an intro rails course now and wresting with this very issue) and
it seems like teaching good testing to people who don’t even know OO can
be like jumping in to the deep end of the pool.

Formal education in programming doesn’t help. Not by any evidence to
my eyes. I’ve recently started seeing someone who’s majoring in CS at
a well-known university, and he said the first class he took on
software design was in C. Frickin’ C. Then they did C++, and
then Java, but there was nothing significant about testing. I told
him about Cucumber and it made his heart go pitter-patter.

I hear this complaint quite often and FWIW it is an untrue stereotype
IME. While I was at the university I was taught testing, design
patterns, refactoring, Agile methodologies, pair programming, use cases,
CI, etc… In fact the first time I heard about TDD was in my first
Java class where the professor would TDD all of his work in the lectures
(live coding!). We did team projects where we had a CI server setup and
we were required to have tests and do pair programming at least part of
the time. We also had class projects where different teams would create
different components and we had to work out our communication protocols,
touch points, and integrate it all. Anyways, I justed wanted to throw
that out and say that formal education isn’t totally failing like some
people claim it is. Only my “Software Engineering” courses taught and
encouraged these practices, but I was still taught them.

but instead started with, “What’s the most important single piece of
information in your app? Okay, great. Write a spec like this. Now
open up this file in /app/models… […] Your spec passed, you’re
cooking! Now let’s spec a view so we can see that information… Now
let’s spec a controller to bring them together…”

(Even better would be to start with Cucumber, which would take up very
little extra overhead in that type of tutorial.)

So… From what I have seen people with little experience testing are
able to pick up the notion of integration/acceptance testing a lot
faster than object level testing. So, I do think having a tutorial
drive all the features out with Cucumber or just webrat+some testing
framework isn’t far fetched at all. Object level examples are a
different story though IME…

tutorial happen when writing a controller spec takes about as long as
to learn agile Web development if BDD happens at the ground floor.

Given time, I think the patterns facilitated by RSpec could
completely revolutionize the way software happens everywhere, if
the next generation of developers come to learn it first and not as an
“add-on.” And that’s why I’m picking on RSpec. I can’t think of any
other technology in a better position to make this happen, with only
some moderate shifts of emphasis in both the tools and the culture.

Does anyone else think that’d be pretty cool?

Yeah, I think having such resources available would be very cool. The
most common complaint I hear in IRC rooms is that there is no good
sample rails app that makes good use of RSpec and Cucumber. I think
there are some examples out there, but an app built as a tutorial would
be much more helpful with the proper git tags and such. I mentioned
before that I was helping prepare a rails course. This is with my local
Ruby group and we have started on a tutorial app:

It thought it would be cool to use this project and BDD all the way
through and teach it like that. However, I have other commitments so
other people in the group will probably do most of the work without
BDD… It is something I would like to revisit someday and provide such
an app. Have you started on a tutorial app like this yet?

-Ben

Thank you so much Stephen.

I am ruby and rails beginner (created a simple site so far) that
decided to
dive into rspec and I feel the pains you described.

I decided to start new rails app and do it with rspec (and to only
test my models).
is there a github project with rspec code that test the models?
it will be great to look at the examples before jumping to theory.

Also, I just bought ‘the rspec book’. Can I only read the rspec parts
and skip the cucumber parts
or it doesn’t fit into the books structure and I must read it from
start to finish?

Thanks again for the detailed post. it really helps me understand
what I am getting into.

Thank you so much Stephen.

I am ruby and rails beginner (created a simple site so far) that
decided to
dive into rspec and I feel the pains you described.

I decided to start new rails app and do it with rspec (and to only
test my models).

Is there a github project with rspec code that test the models?
it will be great to look at the examples before jumping to theory.
also, I just bought the book and it looks amazing.
Is it possible to only read the rspec parts and ignore the cucumber
parts?

Thanks again for the detailed post. it really helps me understand
what I am getting into.

Thank you so much Stephen.

I am ruby and rails beginner (created a simple site so far) that
decided to
dive into rspec and I feel the pains you described.

I decided to start new rails app and do it with rspec (and to only
test my models).

Is there a github project with rspec code that test the models?
it will be great to look at the examples before jumping to theory.
also, I just bought the book and it looks amazing.
Is it possible to only read the rspec parts and ignore the cucumber
parts?

Thanks again for the detailed post. it really helps me understand
what I am getting into.