[rspec-users] How to spec a (Trollop-based) binary’s internal state?

Ashley Moran ashley.moran at patchspace.co.uk
Sun Nov 9 16:07:37 EST 2008


On Nov 07, 2008, at 5:24 pm, Shot (Piotr Szotkowski) wrote:

> Right, that’s why I suggested I could Kernel#eval the binary’s  
> contents
> in the current process instead. This would require tricking Trollop,  
> but
> I assume I could trick it by hand-crafting ARGV.

You might find Rick Bradley's talk[1] on regression testing flog  
useful here.  He starts by speccing the binary at a Ruby level.  Note,  
however, that later in the talk he admits he made a mistake in not  
writing end-to-end tests soon enough.  I think he should have run the  
binary as a black box and just pushed binary code into lib sooner.

> Ah, Cucumber. :) I’ve yet to write my first story; I somehow assumed
> these are more oriented toward non-programmers and/or for driving
> implementation on a rather higher level, and have to be ‘implemented’
> on the RSpec level somehow anyway. I take that these assumptions are
> flawed. :)

Yes and no.  I wouldn't say they are oriented towards the end user -  
Cucumber files are code and must be formatted strictly.  But they are  
readable enough that they can be understood by the end user.  You  
don't actually need to use RSpec in Cucumber steps - just raising an  
exception when you see something you don't like is enough - but the  
matchers make the steps readable.

I recommending stopping the line until you have your current  
functionality described in Cucumber feature definitions, it will save  
you a lot of pain in the long run.


> Hm, I guess I simply need to read up on Cucumber and stories;
> I still can’t see how this kind of specification would differ
> (in the end) from Kernel#`-based RSpec – i.e., why implementing
> the code behind these stories would side-step the underlying issue.
> (But the last time I read on stories was pre-Cucumber.)

Cucumber with Kernel#` and RSpec with Kernel#` would achieve the same  
thing, the difference being the structure of the files.  Cucumber is  
optimised to deal with higher-lever concepts, where natural language  
is a more important part of the spec.  RSpec is more suited to lower- 
level specs where the aim is to cover every edge case or object  
interaction.  This would be too cumbersome with Cucumber.


> Is there an example of story/Cucumber-based specification
> of a binary’s behaviour available somewhere out there?

There is now :)

Well, it's a really crappy, trivial example I just made it about 10  
mins.  No use of STDERR, no file input/output, no network  
connections.  Flagrant abuse of FIT tables.  Oh, and wanton sharing of  
data between steps.  But apart from that it's model code.

Don't take any of this as best practice!  It's just to show the  
concept (seeing how "sort" is presumably written in C):

# sort.feature

   Feature: sort
     So that I can search faster
     As a person that likes searching
     I want to sort data

     Scenario: data ordered already
       Given the following data:
         | STDIN  |
         | apple  |
         | banana |
         | cherry |
         | mango  |
         | pear   |
       When I sort the data
       Then the output should be:
         | STDOUT |
         | apple  |
         | banana |
         | cherry |
         | mango  |
         | pear   |

     Scenario: data out of order
       Given the following data:
         | STDIN  |
         | pear   |
         | mango  |
         | apple  |
         | cherry |
         | banana |
       When I sort the data
       Then the output should be:
         | STDOUT |
         | apple  |
         | banana |
         | cherry |
         | mango  |
         | pear   |


# steps/sort.rb

   require 'spec'

   Given %r/^the following data:$/ do |table|
     @stdin = table.hashes.map { |r| r["STDIN"] }.join("\n")
   end

   When %r/^I sort the data$/ do
     @result = `sort <<END\n#@stdin\nEND\n`.split("\n")
   end

   Then %r/^the output should be:$/ do |table|
     @expected = table.hashes.map { |r| r["STDOUT"] }
     @result.should == @expected
   end

Hope this helps.

Ashley

[1] http://rubyhoedown2008.confreaks.com/11-rick-bradley-flog-test-new.html


-- 
http://www.patchspace.co.uk/
http://aviewfromafar.net/



More information about the rspec-users mailing list