[rspec-users] Spec'ing via features

Ben Mabey ben at benmabey.com
Tue Nov 25 01:52:27 EST 2008


Andrew Premdas wrote:
> I came across this idea of dropping unit tests for acceptance tests in
> the java world. It didn't like it there and I don't like it here, but
> maybe thats because I'm an old fuddy duddy or something :). I do think
> that every public method of an object should be specifically unit
> tested, and yes that means that if you refactor your object you should
> refactor your unit tests. This isn't really that much of a burden if
> you design your objects to have simple and minimal public api's in the
> first place.
>   

+1
> What is that makes you think you can refactor code run acceptance
> tests and be save without unit tests? Writing tests "that guarantee
> the correct functioning of the system" isn't something you can just
> do. Best you can hope for with acceptance tests is that part of the
> system functions correctly most of the time in some circumstances.
>
> Perhaps its the BDD ideal that your only writing the code you need to
> make your acceptance tests pass, that make you think your acceptance
> tests cover all your code. However just because you've written minimal
> code to make an acceptance test pass doesn't mean that you can't use
> this code in a multitude of different ways
>
> Do you really think that BDD created code is just some black box that
> you can tinker around with restructure and still be sure it works just
> because your black box tests still work?
>
> I just don't believe you can get the coverage you need for an
> application using acceptance testing / features alone. If you do
> actually write enough features to do this you'll end up doing much
> more work than writing unit tests combined with features.
>   
+1 again.
> All best
>
> Andrew
>   

Here is how I look at the two sets of tests...

Features at the application level (acceptance tests) instill more 
confidence in me about the correctness of the system's behavior. 
Object level code examples (unit tests) instill more confidence in me 
about the design of the system. 

With acceptance tests passing we have no guarantee about the state of 
the design.  Remember, TDD/BDD naturally produces easy to test objects 
and by skipping object level examples you run the risk of creating 
dependent laden, highly coupled objects that are hard to test.  (Just 
think, you can make all of your features, for a web app, pass by writing 
the app in PHP4 with no objects at all :p .)

I also think that acceptance tests are too slow to be used in all 
refactorings and they are not fine grained enough so you'll end up doing 
more debugging than you would otherwise with good object level 
coverage.  I generally try to keep each individual unit test faster than 
a tenth of a second, as suggested in 'Working Effectively With Legacy 
Code'.  What results is an extremely fast suite that can be used to 
quickly do refactorings.  I have experienced the pain of using just 
Cucumber features first hand-- finding bugs on this level is just not as 
fast object level examples.  If you skip object level examples you are 
incurring a technical debt that you will feel down the road, IMO.

Someone at the start of this thread had wondered what people had learned 
when they went through this process of balancing FIT tests with unit 
tests.  While I know some people on this list could provide some first 
hand experience, I think this post by Bob Martin should provide some 
good insight:

http://blog.objectmentor.com/articles/2007/10/17/tdd-with-acceptance-tests-and-unit-tests

- Ben Mabey

> 2008/11/25 Raimond Garcia <lists at ruby-forum.com>:
>   
>>> Wow, if that's it in a nutshell... :)
>>>
>>> Pat
>>>       
>> Thanks Pat, great summary.
>>
>> I have to admit that I'm as crazy as Yehuda,
>> and believe that all we need are just acceptance tests,
>> at different layers of abstraction, for clients and developers.
>>
>> I also see the benefits of speccing out single object's behaviors, with
>> the aim of a good design.
>> However, the drawbacks of doing this out-weight the benefits, in my
>> opinion.
>>
>> Testing how every method of an object is going to behave,
>> implies that after refactoring, that spec will no longer be useful,
>> eventhough the business and application logic stay the same.
>>
>> I believe that being able to come up with a good design,
>> is not only dependent on writing tests before your implementation,
>> but also on knowing how to write a good implementation.
>>
>> This can be gained through experience,
>> reading books, blogs, pair-programming,
>> using tools to tell you about the complexity of your code,
>> and a constant process of refactoring as we complete requirements,
>> and then fully understand what the best design could be.
>>
>> Therefore in my opinion, by writing tests that guarantee
>> the correct functioning of the system, we have a robust suite of tests.
>> Let the refactoring come storming in and change the whole
>> implementation,
>> but the tests should not be affected at all,
>> as I'm not testing my implementation nor design,
>> only the correct functioning of the system,
>> and relying on other tools on top of tests to maintain my code
>> nice, clean and understandable by anyone that comes along.
>>
>> Kind Regards,
>>
>> Rai
>> --
>> Posted via http://www.ruby-forum.com/.
>> _______________________________________________
>> rspec-users mailing list
>> rspec-users at rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
>>
>>     
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>   



More information about the rspec-users mailing list