Presenting at RailsConf 2008 4
I’m going to be presenting at RailsConf 2008 on RSpec’s Story Runner. I’ll be talking about how I approach writing for the Story Runner and address several related issues including:
- plain text stories vs pure Ruby (when is which appropriate?)
- extending the RailsStory with custom helpers
- testing forms using webrat within the Story Runner
- finding a balance of domain and UI scenarios
- duplication between stories/scenarios and model/view/controller/helper examples
That’s probably already more than I can cover fairly in a 45 minute presentation, but feel free to make other suggestions if you have them.
See you in Portland!
RSpec: new --pattern option 1
I’m not in the habit of blogging every change we make to RSpec, but this one may change the way your suite behaves if you have not been following convention.
As of RSpec’s trunk revision 3246 there is a new command line option that lets you control the filename pattern to match. This allows you to restrict files that are loaded when running the spec command in the same way that you can with rake. It also means that helper files that you may depend on are no longer loaded implicitly.
The default is:
"**/*_spec.rb".
To get rspec to behave as it did before this change, use this:
--pattern "**/*.rb"
If you prefer naming your spec files “foo_example.rb”, you can do this:
--pattern "**/*_example.rb"
You can also supply multiple patterns (comma separated):
--pattern "**/*_example.rb, **/*_spec.rb"
This is a very handy way to avoid loading resource files (helpers, matchers, etc) except when you require them explicitly from other files.
This is currently only in trunk, but will be part of the next release.
RSpec-1.1.2 and ZenTest-3.8.0 11
The RSpec-1.1.2 release includes changes to keep RSpec compatible with autotest in ZenTest-3.8.0. This new ZenTest release boasts an improved cascading configuration model that works well for subclasses (like those that ship with RSpec) and allows users to override the mappings of specs (or tests) to code as well as the list of files that get ignored by autotest.
To support this, Autotest now loads the following files in the following order:
Autotest
AutotestSubClass
~/.autotest
./.autotest
This allows RSpec (or any other library) to override defaults set in Autotest, and then provides users both generic (~/.autotest) and project specific (./.autotest) control over the mappings and exceptions.
How can you take advantage of this?
When autotest begins to run, it calls its :initialize hook. This hook is exposed by the add_hook method. You can use this to access the mappings and exceptions using the following methods on Autotest:
clear_mappings()
add_mapping(regexp, proc)
remove_mapping(regexp)
clear_exceptions()
add_exception(string)
remove_exception(string)
add_mapping
The add_mapping method adds a key/value pair to a hash that maps regexps to procs. Whenever autotest senses that a file is touched, it looks for the regexp that matches the file name and the runs all the files returned by the associated proc.
Imagine you’re working on a shopping cart app. You have some currency conversion behaviour in a Product model that you’d like to extract to an acts_as_currency plugin, and you want autotest to observe the process. You might add a mapping like this to .autotest:
Autotest.add_hook :initialize do |at|
at.add_mapping(%r%^plugins/acts_as_currency/lib/.*\.rb$%) {
at.files_matching %r%^spec/models/product_spec\.rb$% +
at.files_matching %r%^plugins/acts_as_currency/spec/.*_spec\.rb$%
}
end
In this case, a change to any of the files in the plugin’s lib directory would cause all the plugins specs to run, as well as the spec for the Product model.
add_exception
The add_exception method adds paths to a list of paths that Autotest ignores.
I like to run autotest in verbose mode (autotest -v) because it tells me when I change a file that it doesn’t know what to do with. The drawback is that it wants to tell me every time I commit because files in the .svn/.hg/.git directories change. So I’ve got these all listed as exceptions in my ~/.autotest file, along with assorted others:
Autotest.add_hook :initialize do |at|
%w{.svn .hg .git}.each {|exception|at.add_exception(exception)}
end
Note that autotest compiles this list to a Regexp with no anchors, so .hgignore and .gitignore would also get ignored in this case.
Cascading config and granular control
One of the coolest changes in ZenTest-3.8.0 is that autotest loads both ~/.autotest and ./.autotest. So now you can have the hooks you like on every project (like growl notifation) all in one place and still have project specific settings.
This also allows you to set up global mappings/exceptions and modify them at the project level. See Autotest’s RDoc for more info.
Presenting at QCon London
I’m pleased to report that I’m going to be presenting at QCon London in March. Aslak Hellesøy, Dr. Nic Williams, Kevin Clark and I have been invited to present about various aspects of The Rise of Ruby.
We’ll also be running tutorials on Monday. Aslak and I will present Ruby for Java and C# Programmers and Dr. Nic will present on Rails.
Advanced Rails Recipes 2
I’m pleased to announce that my contribution to Mike Clark’s new Advanced Rails Recipes book has been accepted and released. The book is available right now as a Beta PDF and includes dozens of delicious and nutritious recipes for enhancing your Rails applications and the process of developing them.
This is my first formal publication in the software world [1], and I couldn’t be more pleased than to have it be a Pragmatic Bookshelf [2] publication.
My recipe is entitled Describing Behaviour from the Outside-In With RSpec and it demonstrates the BDD approach to Rails apps starting with the view and working your way down to the controllers, models and database.
There is currently one other BDD recipe: Getting Started with BDD, which uses shoulda. There are also recipes for cooking up mocks, code coverage and html validity. And that’s just the testing related recipes.
There are also dozens of recipes dealing with UI, search, email, console, REST, db enhancements and even more general design improvements.
Like the first Rails Recipes book, this one is a must-have for any serious Rails developer who wants to take it up a notch in creating great web applications with Rails.
[1] My first publication of any kind was back around 1980 when I was a young professional magician. The book is called, simply, Coin Magic, and is a must have for any serious coin magician who wants to take it up a notch (see a trend here?) in presenting awesome feats of magic with ordinary coins. Back then I went by my first and middle name, David Arthur.
[2] The Pragmatic Programmers are also publishing my upcoming book with co-author Aslak Hellesøy, tentatively entitled Behaviour Driven Development in Ruby with RSpec.