# I don't get rspec

**URL:** <https://www.ruby-forum.com/t/i-dont-get-rspec/82714>\
**Category:** Ruby\
**Created:** [January 19, 2007, 10:41pm UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714 "2007-01-19T22:41:11Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 23, 2007, 12:03am UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/21 "2007-01-23T00:03:11Z")

</div>

I saw Dave A. talk about this, at Canada on Rails, and initially I  
thought it was a bunch of BS. It seemed like the only difference  
between BDD and TDD was the words; everything else was just the same  
thing with new names. Like the only development involved was a bunch  
of alias statements. But I was totally wrong. What you’re really doing  
is a more intuitive, smoother version of TDD which produces  
documentation as its byproduct. TDD isn’t really about testing – it’s  
about design. BDD makes it easier to use TDD for what it’s really for.

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 23, 2007, 10:39pm UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/22 "2007-01-23T22:39:37Z")

</div>

Giles B. wrote:

> I saw Dave A. talk about this, at Canada on Rails, and initially I  
> thought it was a bunch of BS. It seemed like the only difference  
> between BDD and TDD was the words; everything else was just the same  
> thing with new names.

It’s easy for folk to dismiss RSpec by saying that it’s just semantics  
… but when you are dealing with meaning, semantics is everything.

> TDD isn’t really about testing – it’s  
> about design. BDD makes it easier to use TDD for what it’s really for.

Heh, you nailed it!

–  
– Jim W.

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 23, 2007, 10:50pm UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/23 "2007-01-23T22:50:36Z")

</div>

On 1/23/07, Christian N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> They can contain anything except NUL bytes (the extended symbol  
> syntax). They are turned into class and method names automatically  
> (we need some special formatting for that due to Test::Unit  
> restrictions).
> 
> > Is it possible to nest contexts? Is this a good idea?
> 
> test/spec allows them since 0.2, and I use them to group contexts that  
> go together. Note that nothing is inherited, it’s purely namespacing.  
> RSpec doesn’t have them, and they aren’t interesting in implementing  
> them AFAICT.

That’s correct. We’ve really struggled with this because users want a  
means of sharing context material, but we believe that nesting  
contexts is going to lead to specs that are confusing to look at. We  
believe that clarity supercedes DRY in specs, and so we haven’t  
supported this yet.

That said, you can include modules and get reuse that way:

module SomeHelperMethodsUsefulAcrossContexts  
end

context “some context” do  
include SomeHelperMethodsUsefulAcrossContexts  
end

I’d be surprised if test/spec doesn’t already support this out of the  
box.

Cheers,  
David

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 23, 2007, 10:54pm UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/24 "2007-01-23T22:54:37Z")

</div>

Is there an equivalent to autotest for rspec (autospec?)? I’ve googled  
around, but only came across a Rails plugin, which (perhaps obviously)  
is very Rails-centric.

-P

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 23, 2007, 11:03pm UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/25 "2007-01-23T23:03:43Z")

</div>

Wayne V. wrote:

> I don’t look at this as “add a test to the spec/add a trivial fix to  
> the code” but instead as “add a test to the spec/do the simplest thing  
> that could possibly work to get the tests to pass”, and I find  
> substantial value in this approach.

When I do TDD, I approach it with a Jeckle and Hyde perspective. When I  
write a test, I am writing a specification of how the code should work.

When I start writing code, I become the laziest programmer you can  
imagine, writing only enough code to pass the specification as it is  
written at that moment. If it is not called out in the spec, it doesn’t  
get written.

When I switch back to test writing, I cuss out that lazy programmer  
(i.e. me just a few moments ago) and write additional specs to force the  
code to do exactly what I want.

The tension between Dr. Jeckle (the spec writer), and Mr. Hyde (the  
programmer) causes Dr. Jeckle to write better specs and Mr. Hyde to  
write lean, correct code.

–  
– Jim W.

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 12:08am UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/26 "2007-01-24T00:08:49Z")

</div>

On 1/23/07, Jim W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> imagine, writing only enough code to pass the specification as it is  
> written at that moment. If it is not called out in the spec, it doesn’t  
> get written.
> 
> When I switch back to test writing, I cuss out that lazy programmer  
> (i.e. me just a few moments ago) and write additional specs to force the  
> code to do exactly what I want.
> 
> The tension between Dr. Jeckle (the spec writer), and Mr. Hyde (the  
> programmer) causes Dr. Jeckle to write better specs and Mr. Hyde to  
> write lean, correct code.

With me it’s more like Abbott and Costello!

Seriously, thanks for describing this so well.

Cheers,  
David

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 1:11am UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/27 "2007-01-24T01:11:57Z")

</div>

On 1/19/07, James Edward G. II [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On Jan 19, 2007, at 6:55 PM, Sam S. wrote:
> 
> > The problem is a lot of people don’t do TDD right, and the  
> > semantics of  
> > it raise the barrier to entry.
> 
> Yes. This has always bothered me about the zentest tool. I love  
> many of the tools in that package, but the zentest tool seems to  
> encourage bad testing habits. The video linked to earlier in the  
> thread explains why.

What’s wrong with zentest, specifically?

Thanks,  
Joe

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 1:27am UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/28 "2007-01-24T01:27:01Z")

</div>

On Jan 23, 2007, at 6:10 PM, Joe Van D. wrote:

> > thread explains why.
> 
> What’s wrong with zentest, specifically?

You will probably understand better by watching the movie, but  
zentest encourages you to make a test case for each class and a test  
method for each method. BDD teaches that these decisions are pretty  
arbitrary.

The true goal of testing is to test the “behaviors” of your object.  
If that means interacting with five methods or just one possible call  
sequence of a method that has several, that’s what you should really  
be testing. What do if you need to work with two classes at one to  
test something?

This class and method organization is also encourages you to use so-  
so names for your tests at best. If you have a Calendar class and a  
TestCalendar, that’s pretty much saying the same thing twice (a  
violation of DRY) and it doesn’t tell you much. BDD encourages you  
to actually express what you are testing with your naming. This  
really helps you focus on the goal of the process and is much less  
arbitrary.

There you have it, in my own words. Just to be clear, the above is  
my opinion through and through. I do not speak for the zentest or  
BDD teams.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 2:06am UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/29 "2007-01-24T02:06:05Z")

</div>

On Jan 23, 2007, at 16:26, James Edward G. II wrote:

> On Jan 23, 2007, at 6:10 PM, Joe Van D. wrote:
> 
> > What’s wrong with zentest, specifically?
> 
> You will probably understand better by watching the movie, but  
> zentest encourages you to make a test case for each class and a  
> test method for each method.

Which will match up 1:1 if you factor your code well.

> BDD teaches that these decisions are pretty arbitrary.

I don’t use BDD because I already have my tests broken up by units of  
behavior. I call them methods.

BDD presents a method of thinking about test design to help you focus  
on better object design and object modeling. Unit testing doesn’t  
have this method of thinking built-in, you have to discover it.  
(Although it makes itself evident if you pay attention to how  
difficult it is to test something.)

> The true goal of testing is to test the “behaviors” of your  
> object. If that means interacting with five methods or just one  
> possible call sequence of a method that has several, that’s what  
> you should really be testing.

I think there are two true goals of testing. One is to enumerate  
your edge cases so each one behaves as you expect. Another is to get  
feedback about how well you’ve designed your program. Both are  
equally important.

If you want to write specifications to enumerate your edge cases,  
great. However, if you’ve factored poorly neither BDD nor TDD will  
give you small, concise tests nor a small, concise implementation.

> What do if you need to work with two classes at one to test something?

Then your classes are probably coupled too tightly.

> This class and method organization is also encourages you to use so-  
> so names for your tests at best. If you have a Calendar class and  
> a TestCalendar, that’s pretty much saying the same thing twice (a  
> violation of DRY) and it doesn’t tell you much. BDD encourages you  
> to actually express what you are testing with your naming. This  
> really helps you focus on the goal of the process and is much less  
> arbitrary.

Mapping tests to classes 1:1 is a sign of proper design. Your  
implementation’s names should reflect the behavior implemented  
within. If you have to give different names to your tests and your  
implementation you’ve probably named your implementation poorly.  
Instead you should refactor your implementation so that it can be  
named well.

Read the tutorial on the rspec site:

[http://rspec.rubyforge.org/tutorials/index.html](http://rspec.rubyforge.org/tutorials/index.html)

The specifications match up with the implementation very well, so the  
Stack is probably well-designed. If they didn’t, that’s a good sign  
of code smell.

(You get the same code smell out of unit testing, it just smells a  
little different.)

–  
Eric H. - removed\_email\_address@domain.invalid - [http://blog.segment7.net](http://blog.segment7.net)

I LIT YOUR GEM ON FIRE!

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 2:37am UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/30 "2007-01-24T02:37:09Z")

</div>

On 1/23/07, Eric H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On Jan 23, 2007, at 16:26, James Edward G. II wrote:
> 
> > On Jan 23, 2007, at 6:10 PM, Joe Van D. wrote:
> > 
> > > What’s wrong with zentest, specifically?
> > 
> > You will probably understand better by watching the movie, but  
> > zentest encourages you to make a test case for each class and a  
> > test method for each method.
> 
> Which will match up 1:1 if you factor your code well.

The point is that you shouldn’t try to shoehorn your tests into this  
1:1 approach. You brought up the tutorial as an example of specs that  
match up nicely with the code, but even that ends up with a few  
contexts. If you just have a StackTest class, you won’t get the same  
logical separation. How many programmers are going to write an  
EmpyStackTest class, a OneItemStackTest class, a FullStackTest class,  
etc?

As your behavior becomes more complex - by interacting with other  
objects - you need to be able to drill a bit deeper with your  
specifications. I often have one complete context for an individual  
method. Not many programmers will create a new test class just to  
spec a method. And that doesn’t mean that this method is too tightly  
coupled to other objects, it just means that you need more  
finely-grained specifications.

> BDD presents a method of thinking about test design to help you focus  
> on better object design and object modeling. Unit testing doesn’t  
> have this method of thinking built-in, you have to discover it.

The bottom line is that if you’re using either Test::Unit or RSpec the  
most effectively, you’re probably doing things nearly the same way  
that you would with the other framework. The difference is that RSpec  
guides you to the proper way. Unit testing doesn’t have the proper  
thinking built-in, as you said. The BDD guys give us a testing tool  
with some of the lessons they’ve learned over the years built-in.  
It’s just a different path to the same place.

Pat

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 5:16am UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/31 "2007-01-24T05:16:23Z")

</div>

Eric H. wrote:

> end  
> assert\_equal 1, @s.top  
> end
> 
> end

Each one of these test methods invokes multiple methods on Stack. You’re  
not testing a method, you’re testing the interaction between several  
methods – i.o.w. a call sequence. Looking at the contents of each, it’s  
not clear that one method really is prominent – i.e. is test\_push  
testing #push, #empty?, or #top ?

Question – what would you name:

def test\_???  
@s.push 1  
@s.pop  
assert @s.empty?  
end

or would you merge it in with test\_empty\_eh ?

Devin

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 3:23am UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/32 "2007-01-24T03:23:13Z")

</div>

On Jan 23, 2007, at 17:36, Pat M. wrote:

> The point is that you shouldn’t try to shoehorn your tests into this  
> 1:1 approach.

Shoehorning is design smell, so I refactor. The 1:1 falls out  
because of good design. Its not something I aim for, its something I  
refactor to.

> You brought up the tutorial as an example of specs that  
> match up nicely with the code, but even that ends up with a few  
> contexts. If you just have a StackTest class, you won’t get the same  
> logical separation. How many programmers are going to write an  
> EmpyStackTest class, a OneItemStackTest class, a FullStackTest class,  
> etc?

BDD and TDD are not 1:1 in this manner, so you’ve overdesigned your  
unit tests.

Instead, do the simplest thing that works:

require ‘rubygems’  
require ‘test/unit’  
require ‘test/zentest\_assertions’

class TestStack \< Test::Unit::TestCase

def setup  
@s = Stack.new  
end

def test\_empty\_eh  
assert @s.empty?  
@s.push 1  
deny @s.empty?  
end

def test\_push  
@s.push 1  
deny @s.empty?  
assert\_equal 1, @s.top  
end

def test\_top  
assert\_nil @s.top  
@s.push 1  
assert\_equal 1, @s.top  
end

end

> As your behavior becomes more complex - by interacting with other  
> objects - you need to be able to drill a bit deeper with your  
> specifications. I often have one complete context for an individual  
> method. Not many programmers will create a new test class just to  
> spec a method. And that doesn’t mean that this method is too tightly  
> coupled to other objects, it just means that you need more  
> finely-grained specifications.

This is where I create new methods or new classes on the  
implementation side. As the number of edgecases increase I pull out  
bits that are resistant to testing by refactoring. Creating multiple  
test classes to test one implementation class is design smell.

–  
Eric H. - removed\_email\_address@domain.invalid - [http://blog.segment7.net](http://blog.segment7.net)

I LIT YOUR GEM ON FIRE!

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 6:06am UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/33 "2007-01-24T06:06:27Z")

</div>

On 1/23/07, Eric H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On Jan 23, 2007, at 16:26, James Edward G. II wrote:
> 
> > On Jan 23, 2007, at 6:10 PM, Joe Van D. wrote:
> > 
> > > What’s wrong with zentest, specifically?
> > 
> > You will probably understand better by watching the movie, but  
> > zentest encourages you to make a test case for each class and a  
> > test method for each method.
> 
> Which will match up 1:1 if you factor your code well.

Eric,

I realize that you might have been put on the defensive here, but the  
suggestion that 1:1 is the only natural conclusion of well factored  
code denies a world of experience.

In my own experience, the ratio of test cases to classes usually  
starts off close to 1:1, but as a project evolves it naturally moves  
away from that. If you see that a class is growing, for example, it is  
common to start refactoring out methods into new classes as those  
classes make themselves apparent.

Some people will add new tests for the new class as a matter of  
course. If you do that, then you are testing the same code in two  
different tests. Multiply that over a large system and you’re  
increasing the time it takes your test suites to run exponentially.  
Slower test suites get run less often, providing less timely feedback.

Also, 1:1 mapping means that every time you want to refactor you are  
burdened with refactoring your tests. 1:1 as a policy has a tendency  
to push people towards doing less refactoring and leaving code in a  
state that less well factored than they might envision.

Others are satisfied that the new class is already tested through the  
classes that are using it. The risk they run is that tests get further  
and further away from the code they are testing, and problems become  
progressively difficult to isolate.

Which is right? Neither 100% of the time. The skill is in finding the  
right balance in each different situation and understanding how to  
make good decisions about when new tests resulting from refactoring is  
a good idea and when it’s not.

> > BDD teaches that these decisions are pretty arbitrary.
> 
> I don’t use BDD because I already have my tests broken up by units of  
> behavior. I call them methods.
> 
> BDD presents a method of thinking about test design to help you focus  
> on better object design and object modeling. Unit testing doesn’t  
> have this method of thinking built-in, you have to discover it.

I’m not sure I understand the distinction you’re trying to make here.  
TDD/BDD is all about discovery.

> feedback about how well you’ve designed your program. Both are  
> equally important.

Agree.

> If you want to write specifications to enumerate your edge cases,  
> great. However, if you’ve factored poorly neither BDD nor TDD will  
> give you small, concise tests nor a small, concise implementation.

Agree, though I do believe that writing the tests first helps to push  
you in the right direction.

> > What do if you need to work with two classes at one to test something?
> 
> Then your classes are probably coupled too tightly.

Let’s say you have a Money class that handles things like rounding,  
math, conversions, etc. This is all very well tested. Now you are  
building an Account class that interacts with an instance of Money.  
Would you mock that out in every Account test?

> > This class and method organization is also encourages you to use so-  
> > so names for your tests at best. If you have a Calendar class and  
> > a TestCalendar, that’s pretty much saying the same thing twice (a  
> > violation of DRY) and it doesn’t tell you much. BDD encourages you  
> > to actually express what you are testing with your naming. This  
> > really helps you focus on the goal of the process and is much less  
> > arbitrary.
> 
> Mapping tests to classes 1:1 is a sign of proper design.

Again, I disagree. 1:1 mapping is a sign that you are good at  
following policy, nothing more. If I write a giant class that has 50  
methods with a single test case with 50 corresponding test methods  
I’ve met 1:1, but I still probably have a shitty design.

If I have some other, looser ratio of tests/classes and every time I  
need to add features to my app it takes 10 times what I expect it to,  
I probably have a shitty design.

On the flip side, if I have a design that is easy for me or any of my  
colleagues to extend as business requirements change, then I have a  
good design. For that to happen there is probably good test coverage,  
but I really don’t think that 1:1 mapping has much to do with it.

But that’s just me.

Cheers,  
David

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 11:22am UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/34 "2007-01-24T11:22:15Z")

</div>

“David C.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> That said, you can include modules and get reuse that way:
> 
> module SomeHelperMethodsUsefulAcrossContexts  
> end
> 
> context “some context” do  
> include SomeHelperMethodsUsefulAcrossContexts  
> end
> 
> I’d be surprised if test/spec doesn’t already support this out of the box.

It works exactly the same in test/spec.

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 10:03am UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/35 "2007-01-24T10:03:54Z")

</div>

On Jan 23, 2007, at 21:05, David C. wrote:

> I realize that you might have been put on the defensive here,

I don’t really care if people use zentest or autotest or unit\_diff or  
Test::Rails or not, but I will say that you’re missing out if you’re  
not testing.

> but the suggestion that 1:1 is the only natural conclusion of well  
> factored  
> code denies a world of experience.

I’m going to cut and ignore some of your points to respond to this,  
which seems to be the core of your message. I think the parts I’ve  
ignored are tangent to the central issue.

(If you want to see how I handle testing specific cases you can go  
through tests in my various projects. You’ll see I don’t really do  
1:1 testing, and some are barely tested at all!)

> > have this method of thinking built-in, you have to discover it.
> 
> I’m not sure I understand the distinction you’re trying to make here.  
> TDD/BDD is all about discovery.

I added back some context. I believe James’ assertion was that  
ZenTest’s approach was different from BDD’s approach. They are the  
same, but test/unit has less philosophy standing behind it, and less  
guidance about how things should be done.

Generally, implementing a BDD specification would end up as a method  
for me. This happens because I use feedback from both the tests and  
the implementations to improve my code.

> Again, I disagree. 1:1 mapping is a sign that you are good at  
> following policy, nothing more. If I write a giant class that has 50  
> methods with a single test case with 50 corresponding test methods  
> I’ve met 1:1, but I still probably have a shitty design.

Following policy is not listening to your code, which I touched on in  
the context below (and hopefully enough above). I listen to my code,  
and 50 methods tells me its screaming in pain.

> If I have some other, looser ratio of tests/classes and every time I  
> need to add features to my app it takes 10 times what I expect it to,  
> I probably have a shitty design.
> 
> On the flip side, if I have a design that is easy for me or any of my  
> colleagues to extend as business requirements change, then I have a  
> good design. For that to happen there is probably good test coverage,  
> but I really don’t think that 1:1 mapping has much to do with it.
> 
> But that’s just me.

Following rules sucks, and honestly I really don’t do 1:1 the way you  
present it (I probably misrepresented myself due to inexact  
expression). It just falls out that way for me because of my style  
and the way I listen to my code and my tests.

I don’t want to say, “YOU MUST TEST 1:1!” since that misses out on  
half of the information you get from testing. I want to say  
something like, “write your tests, listen to your code, listen to  
your tests, then refactor and make it simpler. Then do it again and  
again and again. Once you’re in the habit you’ll just have to the  
first four.”, but even that doesn’t get what I want to convey across.

Oh, and any time your code does something unexpected, write a test.

I still feel that what you test (or specify) should translate very  
closely to what you implement, unit to unit (or behavior to  
behavior). For me this smells good, feels good, flows well, and is a  
pleasure to work with. It took me a long time (at least three years)  
to figure out what I was supposed to be doing, and I’ve still got  
years to go to get it right. Most of it was from doing unpleasant  
things and getting stuck in crappy code. (Basically, the easier it  
is, the more I think I’m doing something right.)

We have these marvelous tools (be it test/unit or BDD-style) and it  
takes a while to realize we’re probably using only half of what it  
can tell us (the tests all pass, done!) and ignoring the half that  
can make code beautiful. Not because of ignorance, but because the  
information is conveyed in a way that’s unusual at first.

It took effort for me to look at code and say “it would be so much  
cleaner if…”, “it would be so much simpler if…”, “I can remove  
this whole class by…”.

Now I can look at something and say “oh, eww, I could just do this  
and this falls off, then that falls off then …”.

I don’t know how to teach people to see it, but its there, if you  
look and listen.

> > The specifications match up with the implementation very well, so the  
> > Stack is probably well-designed  
> > If they didn’t, that’s a good sign  
> > of code smell.
> > 
> > (You get the same code smell out of unit testing, it just smells a  
> > little different.)

–  
Eric H. - removed\_email\_address@domain.invalid - [http://blog.segment7.net](http://blog.segment7.net)

I LIT YOUR GEM ON FIRE!

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 2:04pm UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/36 "2007-01-24T14:04:41Z")

</div>

On 1/24/07, Eric H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > Which will match up 1:1 if you factor your code well.
> 
> > > 
> > 
> > TDD/BDD is all about discovery.
> > 
> > > > This class and method organization is also encourages you to use  
> > > > Again, I disagree. 1:1 mapping is a sign that you are good at  
> > > > I probably have a shitty design.  
> > > > expression). It just falls out that way for me because of my style  
> > > > and the way I listen to my code and my tests.
> 
> I don’t want to say, “YOU MUST TEST 1:1!” since that misses out on  
> half of the information you get from testing. I want to say  
> something like, "write your tests, listen to your code, listen to  
> your tests, then refactor and make it simpler. Then do it again and  
> again and again.

Hear, hear!

> Once you’re in the habit you’ll just have to the  
> first four.", but even that doesn’t get what I want to convey across.
> 
> Oh, and any time your code does something unexpected, write a test.

+1

> I still feel that what you test (or specify) should translate very  
> closely to what you implement, unit to unit (or behavior to  
> behavior). For me this smells good, feels good, flows well, and is a  
> pleasure to work with. It took me a long time (at least three years)  
> to figure out what I was supposed to be doing, and I’ve still got  
> years to go to get it right. Most of it was from doing unpleasant  
> things and getting stuck in crappy code. (Basically, the easier it  
> is, the more I think I’m doing something right.)

I think that’s generally true, with the addition that the “easy”  
measurement becomes more meaningful over time. If a month later it’s  
easy for me to revisit a place in the code to add or change something,  
then I must have been doing something right a month ago.

Not to belittle the flow issue. Flow, how it feels as you’re doing it,  
is very, very important as well. I’ve just learned over time that, for  
me, not everything that feels right today proves itself out in a month  
or later. That said, most things that “feel wrong” today end up being  
for a long time.

> Now I can look at something and say “oh, eww, I could just do this  
> and this falls off, then that falls off then …”.
> 
> I don’t know how to teach people to see it, but its there, if you  
> look and listen.

Eric,

Thanks for taking the time for such a thoughtful and thorough reply. I  
was definitely reacting to two statements you had made:

“Which will match up 1:1 if you factor your code well.”  
“Mapping tests to classes 1:1 is a sign of proper design.”

Together, these seemed to advocate a position that 1:1 is good,  
anything else is bad. I can see clearly from your response that I  
misread your intent, and that we are primarily in agreement.

The overriding message (which I hope I’m reading correctly this time)  
with which I agree wholeheartedly is that tools are exactly that:  
tools. They can make some things easier. They can make things more  
fun. They can shed light on the things you’re interested in lighting.

But they can’t make you produce good code. Only time and experience  
and diligent attention to the code itself can get you there.

Cheers,  
David

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 3:58pm UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/37 "2007-01-24T15:58:03Z")

</div>

“David C.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> > > end
> > > 
> > > I’d be surprised if test/spec doesn’t already support this out of the box.
> > 
> > It works exactly the same in test/spec.
> 
> Glad to hear it. Do you have any feeling about which approach to reuse  
> you personally prefer? Nested contexts or included modules?

As said, nesting is purely for organizational and namespacing purposes.  
I use modules.

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 2:07pm UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/38 "2007-01-24T14:07:42Z")

</div>

On 1/24/07, Christian N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > I’d be surprised if test/spec doesn’t already support this out of the box.
> 
> It works exactly the same in test/spec.

Glad to hear it. Do you have any feeling about which approach to reuse  
you personally prefer? Nested contexts or included modules?

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 3:59pm UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/39 "2007-01-24T15:59:04Z")

</div>

On Wed, 24 Jan 2007 22:05:17 +0900  
“David C.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > end
> > > 
> > > I’d be surprised if test/spec doesn’t already support this out of the box.
> > 
> > It works exactly the same in test/spec.
> 
> Glad to hear it. Do you have any feeling about which approach to reuse  
> you personally prefer? Nested contexts or included modules?

I know I’m not the person that this was targeted at, but I would  
absolutely  
love to see nested contexts included in rspec… I was just wishing I  
could  
do that yesterday.

---

<div class="post-metadata">

**Author:** ![nicknameoptional](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/48db29/32.png) [@nicknameoptional](https://www.ruby-forum.com/u/nicknameoptional)\
**Post date:** [January 24, 2007, 4:22pm UTC](https://www.ruby-forum.com/t/i-dont-get-rspec/82714/40 "2007-01-24T16:22:19Z")

</div>

On 1/24/07, Christian N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > > context “some context” do  
> > > > As said, nesting is purely for organizational and namespacing purposes.  
> > > > I use modules.

Interesting. I thought it was for context state sharing like this:

context “a User” do  
setup do  
user = User.new  
end

context “with a valid email address” do  
setup do  
user.email = “removed\_email\_address@domain.invalid”  
end  
…  
end

context “with an invalid email address” do  
setup do  
user.email = “removed\_email\_address@domain.invalid”  
end  
…  
end  
end

This leads us quickly down a path in which you have to look up a chain  
of several setup methods to understand failures.

If it’s just a matter of namespacing for reporting/organization that’s  
kind of interesting.

David

[Previous page](https://www.ruby-forum.com/t/i-dont-get-rspec/82714.md?page=1)

[Next page](https://www.ruby-forum.com/t/i-dont-get-rspec/82714.md?page=3)
