Automagical RSpec: Sake Spec for your Scripts 3

Posted by Justin Reagor Thu, 17 Apr 2008 01:18:00 GMT

I’ve been trying to attempt at spec’ing every single tiny lil script and bit of code I write a long the way. This means I needed a quick, cross directory/app/project script that would run specs from the current directory.

I love Rake, and I love Sake even more.. and Sake was born to do this sort of system-wide task… so lets get to the code!

Throw this in your ~/.sake and smoke it:

desc 'runs specs in the current project, with its own SpecHelper setup'
task 'spec' do
  require 'rake'
  require 'spec/rake/spectask'

  module SpecBase
    def self.included(klass)
      Object.class_eval do
        require 'rubygems'
        require 'spec'
        Spec::Runner.configure { |config| config.mock_with(:mocha) }
      end
    end
  end

  Spec::Rake::SpecTask.new("spec") do |t|
    t.spec_opts  = ["--format", "specdoc", "--colour"]
    t.spec_files = Dir["spec/**/*_spec.rb", "./*_spec.rb"].sort
    include SpecBase
  end
end

As the description string states, this task encapsulates spec_helper.rb and runs any _spec.rb files in the current directory. This makes it very quick for writing specs for small scripts.

Of course, I try to maintain a convention of naming my spec’s just like in Spec::Rails. So if I’m writing a eat_bacon.rb script, I use eat_bacon_spec.rb as the spec file.

Also note: I’m loading Mocha up there, so make sure to take that out if you don’t need it.

Enjoy, with Sake!

Automagical RSpec: Shared Example Loading from Separate Files

Posted by Justin Reagor Wed, 16 Apr 2008 01:05:00 GMT

I especially love Ruby because I can quickly customize it to my tastes and likes. With out regard for anyone else’s feeling but my own. With that said, I do try and use this power for good. For the better of my office mates.

Earlier today I was doing some of this…

describe Admin::ModelsController do
  shared_examples_for 'all admin pages' do
    code code code here...
  end

  describe 'when logged in' do
    more specific controller specs here...
  end
end

...and I thought to myself that I would really just love to do this…

describe Admin::ModelsController do
  it_should_behave_like 'all admin pages'

  describe 'when logged in' do
    more specific controller specs here...
  end
end

Loading it from some separated out module underneath the specific MVC spec/ sub directories.

I’ll explain more in a second… but using some code I was working on before, thanks to storing it in Yojimbo, I quickly wrote this into my spec_helper.rb…

Dir[File.dirname(__FILE__)+'/**/shared/*'].each { |group| 
  require group
  include Object.const_get(group.match(/.*[\/]{1}([\w]*)[.rb]./).captures.first.camelize)
}

As you can tell from the code, it will go through all sub-directories of the current one (RAILS_ROOT/spec in this case) and rummage for “shared/” directories. It will then try and load modules, within these files, named after the file’s file name.

Without having to require and include each single file/module throughout your spec files (or the parent spec_helper).

Examples:

spec/controllers/shared/all_admin_pages.rb
module AllAdminPages
  shared_examples_for 'all admin pages' do
    code code code here...
  end
end

Of course this is a smallish hack that I think really cleans out my specs. I generally got the idea from app/views/shared or app/views/layouts/shared directories in Rails. Keeping small shared view partials in separate, nicely organized sub-directories.

Let the flaming commence! j/k ;)

Philly on Rails RSpec Presentation

Posted by Colin A. Bartlett Thu, 13 Sep 2007 11:48:00 GMT

Last night, I presented about RSpec to the Philly on Rails user group. It was a fun time. Seemed to go well; I hope people found it informative.

It was such a great idea to agree to present on it because a couple months ago I had barely used it. Agreeing to speak in front of a few people about it forced me to learn it. And, so far, I love RSpec!

Here are my slides.

I wanted to create XHTML ones but didn’t have time to learn how and just used Keynote. So they’re just big JPEGs. And they’re really not that useful unless you were there last night. I tended to use a lot of illustrations that won’t mean much unless someone is chatting along side them.

I will try and post up a few more posts about RSpec in the coming days to supplement the slides.

Start Specin' the News 3

Posted by Justin Reagor Sun, 27 May 2007 16:57:00 GMT

Since Colin came back from RailsConf raving about BDD, I’ve found myself priming up for what previously seemed inevitable. Behavioral testing as part of a new development process. Through a better testing structure I hope to..

  1. better the quality of my code
  2. refined organization of development time
  3. focus on the task at hand
  4. providing well covered documentation

With that said… and being the HUGE social loser I am… I’ve spent the last two days writing Specs and tests using RSpec 1.0. I have to say its almost too easy writing the actual tests, whereas the process of writing some tests, writing the code and making the code pass the test has been a definite shift in the way I develop. But not an unwelcomed one! ;)

Since RSpec seems to have a real lack of helpful documentation, I find myself wondering around their API, blog posts and best guesses. I have had great success so far, until I started writing some protected/private methods.

I had initially forseen a world of testing every single line and expression of code. Until I found this tidbit of info on the rspec mailing list…

1. Should you test protected and private methods in your specs?

No. You’re specifying the behavior of an object as seen by the outside world. Of course protected and private methods aren’t available to the world, so why would you need to test them? When you’re doing state-based testing, just call a method and then verify that it returns the expected value or leaves your object in an expected state.

This was backed up by almost every post after it. Seems that as a developer testing his code, I should stick with testing the main parts of the system that, overall, accomplish my task. Verifying that they are doing what I need them to do.

Private and protected methods typically back up other parts of the system that are public. For documentation purposes, I will probably write some tests that validate the functionality of a private/protected method IF they are made public. Just keeping them commented out to satisfy my entire spec.

Quoted RSpec mailing list post and another great post after that