Posts Tagged ‘Cucumber’

h1

Salad, adding cucumber

October 9, 2009

Well I was hoping to get this post published a month or so ago but better late than never.

As some of you may know, I’ve taken some time to learn Ruby & Rails over the past few months and have been using RSpec & Cucumber quite a bit to roll out new functionality.

It soon came to my attention that though Cucumber is a wonderful tool it would be nice to be able to manage scenarios and stories a lot easier and give stack holders a front-end to which they can get a view of what features are to be implemented and how what steps are required to complete a story.

This is where Salad was born, inspired by my latest blog series ‘Jumping on the Rails‘ I decided to make a small rails app that allows users to import and create features for a specific project.

My aim is to integrate the functionality of cucumber along with the other major project management tool (BaseCamp, LightHouse, etc) giving stakeholders and developers alike an easy way to manage, prioritise and understand the stories needed to complete a given scenario.

Functionality

  • Create project features
  • Upload project features
  • Manage features, stories & steps
  • Link stories to a project
  • Link steps to a story

Future Features

  • Sychronise feature, stories & steps
  • Link a feature to a milestone
  • Estimate feature implementation

Over the next few weeks I’ll hopefully have time to improve the general layout of the application, making it more visually pleasing but for the moment it has all the basic functionality necessary to manage your projects new & present features.

Salad can be found here and is easy to install, as outlined below.

Installation

  1. Download from here.
  2. cd to the applications directory
  3. Run script/server
  4. Point your browser to http://localhost:3000/projects
  5. Enjoy

Comments and contributions are more than welcome, my main goal is to provide a simple application that can help bridge the gap between stakeholders and developers.

h1

Jumping on the Rails Pt.5 – Veggie validations

July 23, 2009

So if you’ve been following along from the other parts of the series, you’d remember that we have been building a project story builder using cucumber and BDD. So far we have learnt how to use the process to flesh out functionality from the outside in and generate the basic functionality for our application, this part of the series will focus on saving our project and validating its data using the same process.

Although it may seem that we haven’t covered much ground in the last two parts, as we build up on our steps, the less we will have to do later. You’ll see what I mean shortly.

So lets move on to our next scenario, our projects needs to be able to save & have its data validated, we’ll start with the below scenario.


Scenario: When submitting the form the user must be alerted if the title is not present
  	Given an activated user logged in as 'reggie'
  	When I click new project
	And fill in the new project form without a title
	And submit the form
	Then the project will not be save
	And a validation message will be displayed

So we’ll add this snippet to our

projects.feature

So our first step to implement is filling in the form without a title, so lets get that step out the way.

registere_user_steps.rb

When /^fill in the new project form without a title$/ do
  fill_in 'project_description', :with => 'This project will help us manage stuff'
  fill_in 'project_aim', :with => 'To provide a service'
end

Strange, our test passed, why is that? Well if you remember from the last post, we didn’t implement the save functionality & we haven’t got any validation in place. Either way our tests are passing, so lets move on to the next.

When /^submit the form$/ do
  submit_form 'new_project'
end

Again our tests are passing but that ok, it’s what we expect, we have already implemented the submission process. So we can happily move on to the next step.


Then /^a flash the message will be displayed$/ do
  flash.should contain "A project must have a title"
end

Aha, our first failure, we haven’t implemented a validation message yet, so lets open up our project controller spec and create a few specs.

Here’s what we want:

  • It should save if it is valid
  • It should not save the project if it is not valid
  • It should display a validation error if no title is present

Here’s a rough outline of what we need to spec out


require File.dirname(__FILE__) + '/../spec_helper'

describe ProjectsController do
  it "should save if it is valid"
  it "should not save"
  it "should display a validation error"
end

If you notice there’s alot of repeation here, as we love being DRY, well restructure this a little

  • a valid project
    • should save if it is valid
  • an invalid project
    • should not save
    • It should display a validation error

Nice, now that reads better & we have a layout for our specs, lets see how this effects our specs layout.

describe ProjectsController do
	describe "POST create"
	  context "a valid project"
		it "should save"
	  end
	  context "an invalid project" do
	        it "should not save"
		it "should display a validation error"
	  end
	end
end

So our project controller spec now looks like the code above, as we can see, our specs are a lot more expressive in this fashion and allow others to quickly understand what a tests is supposed to do.

describe ProjectsController do
  describe "POST, create" do
    before(:each) do
      @project = mock_model(Project,
				:title=>"A project",
				:null_object=>true).as_new_record
      Project.stub!(:new).and_return @project
    end
    context "a valid project" do
      before(:each) do
        @project.stub!(:save).and_return true
        post :create
      end

      it "should save" do
	 @project.save.should eql true
     end
     it "should display a success flash message" do
      	flash.should contain "You have successfully created your new project"
     end
   end

   context "title is not present" do
    it "should not save the story"
   end

  end
end

For those that didn’t notice we’ve refactored our controller spec a little, firstly we’ve added a project mock and stubbed out its call to new. We’ve also added a spec to make sure that we can save our project, this passes automatically seeing as we implemented this code earlier via step definitions.

Now lets create our failing spec:

context "an invalid project" do
  before(:each) do
    @project.stub!(:title).and_return nil
    post :create
  end

  it "should not save the story" do
    @project.save.should eql false
  end

end

Here we basically make sure that we don’t get redirected to the projects info page, as it should not be save & we render the form again.

Now we have our condition to save our project, lets setup our validation we still need to get this passing, we need to add validation to our model, so lets open that and add the following:

validates_presence_of :title

Doing so makes our test pass, now on to our next step, we’ll come back to our spec in a sec.

Now we still have a few more steps to run through, these should be pretty simple though.

Then /^a validation message will be displayed$/ do
  response.should have_selector(:li, :content => "Title can't be blank")
end

To fix this we won’t bother with any spec’s, we’ll just add the following snippet to our new projects form:

<%= error_messages_for :project %>

All our scenario’s are now all passing and we can happily move on. Ok, now your probably wondering, hell what was all that effort for, we only setup validation for the title but we created crap loads of code.

It’s true, we setup quite a bit in the last post but in this one, we’ll see how much of a benefit that little bit of leg work was in a sec. Lets get a little ambitious and add to scenario to our projects.feature file.


Scenario: When submitting the form the user must be alerted if the description is not present
  	Given an activated user logged in as 'reggie'
	When I visit the home page
	And I click new project
	And fill in the new project form without a description
	And submit the form
	Then a validation message will be displayed say 'Description can't be blank'

Scenario: When submitting the form the user must be alerted if the aim is not present
  	Given an activated user logged in as 'reggie'
	When I visit the home page
	And I click new project
	And fill in the new project form without a aim
	And submit the form
	Then a validation message will be displayed say 'Aim can't be blank'

Running cucumber quickly we notice that we only have 5 steps to complete our scenario’s. Now if you remember we already created a step to cover validation of messages, wouldn’t it be nice if we could use that same step to cover our the other validation messages.

As we know we going to need this step in a second & our tests are running, lets do a little refactor our previous scenario so that it will cover the other validation messages as well. Change the last step to match the snippet below.

Then a validation message will be displayed say 'Title can't be blank'

Now we refactor its associated step to look like the following:

Then /^a validation message will be displayed say '(.*)'$/ do |message|
  response.should have_selector :li, :content => message
end

Here we’re telling cucumber to take the regular expression and pass it as the ‘message’, this nice little feature not only helps refactor our previous step, run cucumber again the other validation message steps will now cover too, how cool is that 😀

Using this method can save us a lot of time when it comes to writing scenario,s as well as helping us cover a lot ground quickly. Having said that take care when writting your steps, it’s not hard to find yourself lost, trying to work out why a step is not working. With that said, explicit names help to alleviate this no end.

Now with that said let’s move along.

When /^fill in the new project form without a description$/ do
  fill_in 'project_title', :with => 'new project'
  fill_in 'project_aim', :with => 'To provide a service'
end

As we have defined the step for submitting the button all the leg work is already done and we are greated by an error. We’ll we didnt get the validation message, so we’ll add this below snippet to our Project model.

validates_presence_of :description

We’re all passing again & we only have one more step to roll out, nice!

When /^fill in the new project form without a aim$/ do
  fill_in 'project_title', :with => 'new project'
  fill_in 'project_description', :with => 'This project will help us manage stuff'
end

Again we get the same error, so this time we added validation for our projects aim.

validates_presence_of :aim

We now have a fully functionality CRUD for our projects, we’ll look into making this more functional, adding scenarios to our project.

I’ve decided to put the code for this series on github partly to help myself remember what I’m learning here but also for others see the code in action & contribute to. I’d love input on the series and and suggestions on improvements as a whole.

h1

Jumping on the Rails Pt.2 – RSpec, Cucumber & Webrat

June 27, 2009

Well it’s been a while since I’ve written anything really technical & seeing as Rails is taking up a lot of my personal time, I thought I made sense to put some of my newly found knowledge together.

I thought it best to not go over material that has already been done and very well I might add, I’ll just focus on the things have have interested me most & how to take advantage of them in real world situations. This and the next few posts will focus on developing and application using Cucumber, Rails & Webrat to drive the development process. Before I go on, I’d say that none of this would be possible if not for The RSpec book, I’ve read it for a couple times whilst the beta has been floating about and recommend the book to everyone developing in Rails, if only to see what it has to offer.

Lets start of with a basic application. StoryBoard, allows users to create & manage projects and their features with a focus on capturing features that can be used with Cucumber.


rails PROJECTNAME
cd PROJECTNAME

Now we need to setup our BDD environment


script/plugin install --force git://github.com/aslakhellesoy/cucumber.git &&
script/plugin install --force git://github.com/dchelimsky/rspec.git &&
script/plugin install --force git://github.com/dchelimsky/rspec-rails.git &&
script/plugin install --force git://github.com/brynary/webrat.git &&
script/generate rspec &&
script/generate cucumber

Now that’s all we really need to setup our BDD environment, let start with a basic feature to get our feet wet:


Feature: Users must be able to register to the site

In order to allow new users to join the site they need to be able to view the home page & register.
As a guest user
I want to be able to register to the site so that I can create new scenarios for a project

Scenario: A user must be able to view the welcome page
Given I am not logged in
When I visit the home page
Then I should see the sign up link

Seems reasonable, users should be able to view the home page and see a sign up link, after all no one can register without one.

Now a nice little gift that comes with our plugins is autospec, I added the following to my .bash_profile

export AUTOFEATURE=true

This allows me to test both my specs & step definitions.

Starting script/autospec allows us to run our tests automatically on ever save, which can be a nice time saver for those who forget to test after a change.

You can implement step definitions for undefined steps with these snippets:
1 scenario (1 undefined)

3 steps (2 undefined, 1 passed)
0m0.050s

You can implement step definitions for undefined steps with these snippets:

Given /^I am not logged in$/ do
pending
end

When /^I visit the home page$/ do
pending
end

Then /^I should see the sign up link$/ do
pending
end

Cucumber is nice enough to give us code snippets to use in our step definitions, lets start with the first.

Create the file registration_steps.rb

We’ll cheat here seeing as we don’t need to set anything up, it passes.

Given /^I am not logged in$/ do
end

That gets our first part, lets move on to the next, again cucumber will nicely give us the next step definition, we’ll modifiy to look like the code below.

To take advantage of webrat within our specs we’ll need to add the following to our spec_helper.rb

require 'webrat'
config.include Webrat::Matchers, :type => :views

It should now look something like this:

ENV["RAILS_ENV"] ||= 'test'
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
require 'spec/autorun'
require 'spec/rails'
require 'webrat'

Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}

Spec::Runner.configure do |config|
config.use_transactional_fixtures = true
config.use_instantiated_fixtures  = false
config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
config.include Webrat::Matchers, :type => :views
end

Now for the next step definition

When /^I visit the home page$/ do
visit '/'
end

Ok, we obviously need to setup a route for this one.

map.root :controller => "welcome"

We get another error saying:

uninitialized constant WelcomeController (NameError)

Okay we know we don’t have a controller, how about we cheat and make one just to make things pass for now. Especially as we don’t want to get bogged down with detail.

script/generate rspec_controller Welcome index

That will basically create our welcome page for us. We can now move on to the next step definition.

Then /^I should see the sign up link$/ do
response.should contain 'Sign up'
end

Now our tests are back to failing again, we’ll move to the controllers view to iron out our functionality.

Own spec_controller was nice enough to create our view for us, lets open up the view spec and add a spec.


#Delete this example and add some real ones or delete this file
it "should tell you where to find the file" do
response.should have_tag('p', %r[Find me in app/views/welcome/index])
end

Is our first test in our view spec, lets replace this with something more meaningful.


it "should have a sign up link" do
response.should have_selector("a", :content => "Sign up")
end

Here we just want to make sure that we have a page where we can sign the user up. Let get it to pass, remove the index.html from the public directory, the add the code below to your Welcome controllers index view.

<a href="/signup">Sign up</a>

Nice and simple, right. Now we’re still got alot of work to do but that is what the other stories are for ;), we’ll follow up with those in the next post.