How to set up Cucumber and RSpec for a non-Rails project
Often times when we use Cucumber and RSpec (and by 'we' I refer to Rails developers, sorry for the narrow focus here), we use them from within a Rails environment.
Here are some instructions on how to set up Cucumber and RSpec for a multi-file Ruby project in a non-Rails environment. Note: if you're here because you want to make your own gem, stop reading and check out jeweler instead. Jeweler will take care of it all for you with one command:
jeweler name_of_gem --cucumber --rspec
If you are not making a gem and just want to bootstrap your own project, here are instructions -- with explanations of what is what. Some may be obvious, but I find that when we are used to using generators it can be easy to overlook what they generate and why. It's the old "the gui made me dumb" syndrome. Therefore, I choose to both err on the side of verbosity in this post and include a link to a bash script that does it for you, at the bottom. For this example, imagine you are going to write a game of Tic Tac Toe in Ruby.
- Make sure you have Cucumber, RSpec and their necessary friends installed on your computer:
Note: sudo may not be necessary for your set up -- that's a matter of personal preference and your existing setup.
sudo gem install gherkin sudo gem install cucumber sudo gem install rspec sudo gem install webrat
- Create project directory. For this example, say you're making a Tic Tac Toe project:
mkdir tick_tac_toe
- Add the following directories and files for Cucumber and RSpec:
# Cucumber mkdir tick_tac_toe/features mkdir tick_tac_toe/features/step_definitions mkdir tick_tac_toe/features/support touch tick_tac_toe/features/support/env.rb # RSpec mkdir tick_tac_toe/spec touch tick_tac_toe/spec_helper.rb
- Add a lib directory where your own code will go. This is where all of your classes and files will live.
Note: some people prefer to have a named directory inside of lib and put all the app files in there. That would look like this:
# Your project code mkdir tick_tac_toe/lib touch tick_tac_toe/lib/tick_tac_toe.rb
File organization is a matter of personal preference and I'd say if you're planning on having more than one file, use a nested directory, otherwise just place it directly at the root of lib.mkdir tick_tac_toe/lib mkdir tick_tac_toe/lib/tick_tac_toe touch tick_tac_toe/lib/tick_tac_toe.rb
- Set up the files so they will recognize each other.
- open tick_tac_toe/features/support/env.rb and add the following lines:
$: Explanation: the first line adds the lib directory to your load path. The load path is stored in the $: variable. Yes, that is "$:", without the quotes. If you type $: in irb, you'll see an array come back with all of the directories that are looked in by default when you require files. The second line requires spec/expectations, which is what you use in RSpec all the time. Now you can use this behavior in Cucumber. And the third line requires your very own tick_tac_toe.rb file. - Open up spec/spec_helper.rb and add the following lines:
$: Explanation: It's that load path again ($:). And you're doing the same thing as before, adding your lib directory to it. Notice the difference between the Cucumber setup and the RSpec setup with regard to this line? spec_helper.rb is only one level below lib ("/../lib") while env.rb is two. It's all just about finding the files where they are in the tree. The second line requires spec, (RSpec). And the third line requires your very own tick_tac_toe.rb file.
That's it! It boils down to this file structure:
- open tick_tac_toe/features/support/env.rb and add the following lines:
tic_tac_toe--features----step_definitions----support------env.rb--lib----tic_tac_toe.rb--spec----spec_helper.rb----tic_tac_toe_spec.rb
- And then add your *.feature files inside of features/; your step files inside of features/step_definitions; and your *_spec.rb files inside of spec/.
- P.S. I wrote a bash script to automate this for myself and put it on github: feel free to use or improve.