<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>8th Light Blog: Getting started with Rails and FitNesse</title>
    <link>http://blog.8thlight.com/articles/2007/01/15/fitnesse-rails-tutorial</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>In the minds of the craftsmen...</description>
    <item>
      <title>Getting started with Rails and FitNesse</title>
      <description>This is intended to be a tutorial to get you started using FitNesse with ruby on Rails.  There is some explanation needed about FitNesse, Fit, and Rails.  Smart people have written about such things, I will leave you to google them as interested.  Two good references are listed at the bottom of this tutorial.
&lt;br&gt;&lt;br&gt;
So lets get started.  Our customer has just written a test that looks like this:
&lt;br&gt;
&lt;pre&gt;
|vending machine|
|check|amount|$0.00|
|enter|currency|$.35|
|press|add change|
|check|amount|$.35|
|enter|selection|juicy fruit|
|press|vend|
|check|amount|$0.00|
&lt;/pre
&lt;br&gt;
This would be a common first fixture for a product, as it is limited in scope, it is a very specific example from which to build a conversation about requirements about.  Anyway, the first thing to making this pass is getting some of the FitNesse infrastructure in place around your rails app.
&lt;br&gt;
First, lets create a rails app for our vending machine
&lt;pre&gt;
$rails vending_machine
&lt;/pre&gt;&lt;br&gt;
We see all the normal rails stuff, all the creates.
&lt;br&gt;
Lets download FitNesse and place it in our vending_machine root directory.  FitNesse can be downloaded at http://fitnesse.org.  And start the FitNesse server. 
&lt;br&gt;
So, now we go to the FitNesse main page and create the page for our acceptance test.  Then put the test from the customer into the page and try to run it.  Failures?  We need to set up the environment to run with ruby fit.  Follow the instructions here (http://fitnesse.org/FitServers.RubyFit) to set up the right test runner for ruby.
&lt;br&gt;
Lets write our first fixture in a fixtures directory we create in the root folder.  
&lt;br&gt;
Our new test with the path and test runner set up looks like this
&lt;pre&gt;
!define COMMAND_PATTERN {ruby -I%p ruby/bin/FitServer.rb}
!path &lt;insert path to rails root dir&gt;
&lt;br&gt;
!3 Make one transaction with a vending machine
&lt;br&gt;

!|fixtures.VendingMachine|
|check|amount|$0.00|
|enter|currency|$.35|
|press|add change|
|check|amount|$.35|
|enter|selection|juicy fruit|
|press|vend|
|check|amount|$0.00|
&lt;/pre&gt;
There are a few things to notice about the changes.&lt;br&gt;
* The path is the rails root dir.&lt;br&gt;
* Fixtures.VendingMachine is mapping to the folder name/module name of  where the fixutures are located.  In this instance it is a folder in the rails directory called fixtures.&lt;br&gt;
* If you run the test, you will get all sorts of exceptions, because the fixture code is not written yet.&lt;br&gt;


Note: If the table is not even showing up when you run the fixture go here.
&lt;br&gt;
Now it is time to write a fixture to make this test fail without any exceptions.  In the fixtures directory, create a file called vending_machine.rb.  The naming of your fixtures maps with the name of your file, which it will require.  Lets make a stub file to make the test fail without exceptions.
&lt;br&gt;
&lt;pre&gt;
require 'ruby/lib/fit_helper'
module Fixtures
  class VendingMachineFixture &lt; Fit::ActionFixture
    attr_accessor :currency, :selection
    
    def initialize
      super
      @@actor = self
    end
    
    def add_change
    end
    
    def vend
    end
   
  end
end
&lt;/pre
&lt;br&gt;
Now we should have failures with the amount not changing.  
&lt;br&gt;

Lets create our controller for the vending machine and start to implement the code.  I am going to leave out the specs I use to write the controller, just show the code.  Here is the first version of the controller.  Note it has the same stubbed methods the fixture has.&lt;br&gt;
&lt;pre&gt;
class VendingMachineController &lt; ApplicationController
  def add_change
  end
  def vend
  end
end
&lt;/pre&gt;
&lt;br&gt;
Lets hook up the fixture to the imaginary controller.  There is a fair amount of set up which is rails related.  
&lt;br&gt;
First, we need to load up the environment and the controllers.  Add these lines to the beginning of your fixture.
&lt;pre&gt;
require File.expand_path(File.dirname(__FILE__) + "&lt;insert rails root dir&gt;/config/environment")
require File.expand_path(File.dirname(__FILE__) + '&lt;insert rails root dir&gt;/app/controllers/application')
&lt;/pre&gt;&lt;br&gt;
Which should allow us to change the initialize method to:
&lt;pre&gt;
def initialize
      super
      @@actor = self
      @controller = VendingMachineController.new
      @controller.params = {}
    end
&lt;/pre&gt;&lt;br&gt;
Which creates the controller, and initializes its params to an empty dictionary.  There are other ways to do this, like creating test params, but for simplicity, we are going to create our own for now.
&lt;br&gt;
Next, we set up the values in the params and call the controller methods.
&lt;pre&gt;
    def add_change
      @controller.params[:amount] = @currency
      @controller.add_change  
    end
    
    def vend
      @controller.params[:selection] = @selection
      @controller.vend
    end
&lt;/pre&gt;
&lt;br&gt;
Now, we make the test pass by implementing the controller.
&lt;br&gt;
 &lt;pre&gt;
class VendingMachineController &lt; ApplicationController
  
  def initialize
    @items = {"juicy fruit" =&gt; 35 , "doublemint" =&gt; 45 }
    @session = {} if not @session
    @session[:amount_entered] = 0.0;
  end
  
  def add_change
    @session[:amount_entered] += params[:amount].to_f
  end
  
  def vend
    @items.each_pair do |key, value|
      if(params[:selection] == key)
        @session[:amount_entered] = 0.0
      end
    end
  end
end
&lt;/pre
There is your first version of this fixture.  Have fun adding on to it.
&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;Missing Requires&lt;/h3&gt;
There is some weirdness around the way RubyFit collects exceptions after failing to find the file to require.  If this occurs, dig into ruby fit&#226;&#8364;&#8482;s FixtureLoader, specifically the find_class method.  Usually you can get some information from the exceptions being silently caught.
&lt;br&gt;
&lt;h3&gt;References &lt;/h3&gt;
http://fit.rubyforge.org/basics.html - RubyFit
http://www.cornetdesign.com/2005/12/fitnesse-and-ruby-basic-tutorial.html - Fitnesse and Ruby


</description>
      <pubDate>Mon, 15 Jan 2007 14:54:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:acc0f516-1f8a-4e37-96df-57a7eabb23c0</guid>
      <author>Paul Pagel</author>
      <link>http://blog.8thlight.com/articles/2007/01/15/fitnesse-rails-tutorial</link>
      <category>Coding</category>
      <category>Testing</category>
    </item>
    <item>
      <title>"Getting started with Rails and FitNesse" by User</title>
      <description>&lt;p&gt;You need a spam filter&lt;/p&gt;</description>
      <pubDate>Sun, 09 Dec 2007 07:12:04 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:44537f01-d4c2-4970-a3ac-3f27b68f6a01</guid>
      <link>http://blog.8thlight.com/articles/2007/01/15/fitnesse-rails-tutorial#comment-456</link>
    </item>
  </channel>
</rss>
