Posts Tagged ‘rspec’

Configuring Cruisecontrol, Git and RSpec

Tuesday, May 13th, 2008

The realization we needed a continuous integration server sank in good last week when work on our internal project really got started. The project has seen quite some development in the past, mainly when my skills in (RSpec) testing where, uhm, less than optimal. This on top of some high pressure hacking left the project in a pretty shabby shape. We are now working on it with three people and we’d like to introduce a bit more rigour in our development process.

One of the first steps was to use a continuous integration server. I was actually surprised so few existed and the choice for CruiseControl(CC) was a quick one. This pretty piece of software did not support Git out of the box but there exists a GitHub branch incorporating this functionality. What is even better is this post which explains how to use it! So I won’t go into the nitty gritty details, what I will do is point out some pit falls and how to make CruiseControl play nice with RSpec. Which it also does not support out of the box but which is really easy.

Install CC as per previously mentioned post. What threw me off where the site_config.rb and the cruise_config.rb I got the (wrong) impression that these files lived in the root directory of the CC install. This is not the case. When installing CC it, by default, creates a directory ~/.cruise which holds your projects. It is here where the site_config.rb file lives. And this is the file to configure ActionMailer! And in the directory ~/.cruise/projects/MyProject the other file can be found in which to configure the people who need to receive emails when the build breaks.

When CC builds a project it just runs some Rake tasks, one of which is cruise. Getting CC to use RSpec is as simple a overwriting this task! This is what I gleaned from other posts:


desc "Task to do some preparations for CruiseControl"
task :prepare do
RAILS_ENV = 'test'
end

desc "Task for CruiseControl.rb, automatically picked up"
task :cruise => [:prepare, "db:migrate", "spec"] do

end

The first task is to make sure the test environment is used which is really what you want in a situation like this.

The next step would be to produce something more readable than the dump of the log file with the results of the ran RSpecs.

Small Rspec revelations, RJS

Friday, February 29th, 2008

The closing scene of this series. Specing RJS templates. Again a topic which is not on the forefront of the RSpec community.  And again a blog post saved the day. It took me a little bit of time for figure out what kind of RJS type the response object should expect. To illustrate an example RSpec:


response.should have_rjs(:chained_replace_html, "some_id") do
response.should have_text(/some random text/)
end

The response object should have an RJS object but what type? According to the assert_select_rjs method, which the have_rjs method wraps, there are only a hand full of these types but apparently not all of them are listed. As I found out when my inline RJS:


render :update do |page|
page[update_div].update(text)
end

None of the mentioned types responded correctly. But I noticed that the blog post mentioned earlier used an other type. Browsing through the source code of assert_select_rjs I found my missing type: chained_replace_html. Hooray! Everything worked fine and dandy from there on.

One last hiccup was that code in the block passed to the have_rjs method does not scope by default the response.should directive, so this is wrong:


response.should have_rjs(:chained_replace_html, "some_id") do
have_text(/some random text/)
end

Obviously.

Small Rspec revelations, Modules

Wednesday, February 27th, 2008

It looks like this is going to be a three parter. For our current project we wanted to abstract some of the functionality which appeared in our models to a module. As we are taking TDD more seriously nowadays I set out to write a spec for the module first. Right. For a normal spec you need an instance of the object you are specing. But by their very nature models can not be instantiated! So how to write a spec then? Here you go:


before(:each) do
klass = Class.new { include FicklePricing }
@foo = klass.new
@foo.stub!(:id).and_return(1)
end

In this case we have created a class with does nothing but to include our module. And this almost empty class can by instantiated and used in this specs. Trivial example:


it "should respond_to price method" do
@item.should respond_to(:get_price)
end

Small Rspec revelations, ActionMailer

Tuesday, February 26th, 2008

At the office we are getting more and more serious about RSpec . Today we ran into two things we had not done so far. Specing an ActionMailer and a module. The Rails Way only covered Test::Unit and that looked dreadful. Way to much code. I still think I should be coding applications not tests. A quick google turned up not so much, nor did the RSpec site help. Fortunately someone on the RSpec mailinglist brought the subject up. With that I knew enough to get the tests working.


before(:each) do
ActionMailer::Base.delivery_method = :test
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.deliveries = []
end

This before block set the method for delivery method to :test. Normally it default to :smtp and an other possibility is :sendmail. The second directive tells ActionMailer to actually send the emails(who would have guessed?). The deliveries array keeps track of every email sent.

Now you can just send your email as you usually would:


mail = Notifications.deliver_some_random_email("name")
ActionMailer::Base.deliveries.size.should == 1
mail.body.should =~ /name/

Rock on RSpec.