- Thoughts in Computation – Using Phusion Passenger and Apache2 on Ubuntu with RVM and Gemsets
- RVM and project-specific gemsets in Rails
- Creates a new RVM gemset for the app
- Creates a directory for the app
- Creates an .rvmrc file under the new app directory to ensure the proper gemset is used whenever you switch to it
- Note: This assumes you have REE 1.8.7 installed under rvm (rvm install ree), which is the main ruby I’m still using for everything
- Installs latest prerelease of bundler
- Installs latest edge version of rails 3
- Ruby Inside
- Rails Inside
- Ruby Flow
- Rails Dispatch – Just ’cause there are some great Rails 3 articles
- many, many more out there, but that’s just a few
- Peepcode $$ – THE place to get your Ruby screencast fix (I’ve got a full subscription)
- Tekpub $$ – Pretty good series on building your own blog in Rails and a Rack screencast
- Gregg Pollack’s Rails 3 Screencasts
- RubyPulse – Nice, short ruby screencasts
- Railscasts – Nice, short rails screencasts
- raleigh.rb videos – Videos of user group talks from Raleigh
- SD Ruby videos – More good videos of user group talks in San Deigo
- Vimcasts – Not Ruby related, but had to get my Vim plug in somehow… 🙂
- http://www.capify.org/index.php/Capistrano
- https://github.com/capistrano/capistrano
- http://peepcode.com/products/capistrano-2
- http://rspec.info – Only covers RSpec 1.x, but some useful info nonetheless
- https://github.com/rspec
- Pure RSpec
- http://rvm.beginrescueend.com
- https://github.com/wayneeseguin/rvm
- <irc://irc.freenode.net/#rvm>
- http://www.ruby-lang.org
- http://rubyflow.com
- http://www.rubyinside.com
- <irc://irc.freenode.net/#ruby-lang>
- http://rubyonrails.org
- https://github.com/rails/rails
- http://railsdispatch.com
- http://guides.rails.info
- http://railsapi.com
- <irc://irc.freenode.net/#rubyonrails>
- http://haml-lang.com
- https://github.com/nex3/haml
- <irc://irc.freenode.net/#haml>
- https://github.com/nex3/haml
- <irc://irc.freenode.net/#sass>
- http://compass-style.org
- https://github.com/chriseppstein/compass
- http://www.blueprintcss.org
- http://960.gs
- http://www.mongodb.org
- https://github.com/mongodb/mongo
- <irc://irc.freenode.net/#mongodb>
- http://mongoid.org
- https://github.com/durran/mongoid
- http://vimeo.com/9864311 (Great talk by @modetojoy on MongoDB/Mongoid)
It’s not goodbye…
Hey there folks,
It’s a bittersweet moment for me, but the time has come for me to relaunch my personal blog/brand back under my own name. I truly appreciate everything Jason, Joe and everyone else in this community has done for me over the years. There are an awesome group of folks here in this community and I’ve enjoyed being a part of seeing it grow. I wish everyone here great success and I look forward to seeing where the donkey takes this community. 🙂
Of course thanks to the twitters and the interwebs, this isn’t goodbye… just a relocation or readdressing, if you will.
I’m still putting some final touches on things, but if you’re interested in following me at my new home:
</p>
Vlad, RVM and Bundler sittin’ in a tree
(Thanks to Chad for nudging me to write this post 🙂
Up until now, my only experience with deploying Rails or any other Ruby-based web application
has been to use the “standard” Capistrano. For the main Rails 3 application I’ve been building
the past few months, Capistrano has been fine and was mostly a set it and forget it kinda thing.
One of my clients asked me to do a small side project to perform a simple task and naturally I chose
the most excellent Sinatra framework. I could go on and on about the awesomeness of Sinatra, but that’s
not the point of this post. Suffice it to say when I finished this small Sinatra application, I needed to
deploy it somehow. Manual deployments are for the birds, so my first knee-jerk reaction was to get
Capistrano wired up to do the automated deployment. But after taking a glance at my existing Capistrano
deployment script for my Rails 3 application, it seemed like overkill for this tiny Sinatra ditty.
The first alternative I ran across was a deployment tool named Vlad the Deployer
(which clearly gets an award for the best name ever). What attracted me right off the bat was the simplicity of its usage
and configuration. I also liked the fact that it uses pure Rake for everything, instead of some of the
“magic” that Capristrano does under the hood.
Getting Vlad up and running is pretty straightforward, but I did have a couple issues getting it integrated
into my particular deployment process. Like all good Ruby developers 2 of my must use tools are RVM
& Bundler. Bundler is great for managing gem dependencies and RVM keeps you sane when working with many different versions
of Ruby and gems at the same time.
One thing I like to do during deployments is make sure “bundle install” gets run on the server. This ensures that any new gems I’ve introduced in my Gemfile get automatically installed on the server
during deployment. Usually this wouldn’t be much of an issue, but I’m a pretty big fan of RVM, so much
so that I actually run it on my staging/production servers as well. RVM does some serious magic under
the hood, including altering various environment variables affecting the path. Here is the series of
steps I had to take to get Vlad to properly run “bundle install” during deployment. (NOTE: I’m mainly
posting this to hopefully get feedback on a better way. I really don’t like my solution too much.)
Minor server preparation
Before I show the deploy script itself, you do need to make sure your server is set up properly with
RVM and Bundler installed in the global gemset. Here are 2 great articles that describe this process:
Extend Vlad’s update Rake task
Since Vlad uses simple Rake tasks for everything, it’s easy to “tack on” steps before or after the
built in Vlad tasks. In this case I wanted to run my Bundler command right after the built in update
process was complete. Here’s one easy way to do that:</p>
FYI, if you want to run something before the update process starts, you can simply add a dependency
to the built in update task like so:</p>
Create a Bundler task
Next I created a separate task (see next section about remote_task) to perform the Bundler command I
needed to run on the server and invoked it inside of Vlad’s built in update task:</p>
Remotely running commands via SSH
Before I show the commands necessary, it’s important to understand that all of this will be run in
the context of an SSH session. Thankfully, there was a nice feature of Vlad that was extracted out
into its own gem known as remote_task. This is a handy way to run Rake tasks in the context of remote
servers and is used heavily under the hood with Vlad. We’re also using it here for our custom Bundler
task and a “run” method can be called with whatever commands you want to be run on the remote server in
an SSH session.
Step by step
For clarity I put each command into its own local variable, each of which I’ll describe below.
Initialize RVM
When you login to a server via SSH, you have set of environment variables which include how paths
are resolved when running commands. Luckily, RVM takes care of all of that for us. Usually when using
RVM you simply load it via your .bashrc, but for some reason I couldn’t get this working in the
context of the SSH session used as part of the remote_task. I’m sure this is due to my lack of bash and
*nix skills which I’m actively trying to beef up. But to work around it for now, I just manually source
the RVM bootstrap script myself:</p>
Trust your RVM gemset
I’m not going to dive into RVM gemsets as part of this post, but just think of it as a way to manage gems
in isolation from other applications and environments. I like to use project-specific gemsets for everything
I do to keep things nice and clean. A nice companion to gemsets is the use of an .rvmrc file to
automatically switch to the correct gemset when navigating to your application’s directory. Creating a
.rvmrc is stupidly simple:</p>
Starting in version 1.0 of RVM,
there was a security measure put in place to force you to “trust” .rvmrc
files when changing into a directory with a .rvmrc for the first time. Normally this is fine, but it
presented an issue in the context of an automated script. This security measure can be disabled by this
next command:</p>
This tells RVM that I explicity trust the .rvmrc located in my release_path which is the root of my
application on the server.
Run bundle install – take 1
With RVM all loaded up, we can now issue our bundle command to install any new dependencies if necessary.
So naturally I tried the command below:</p>
But this blew up in my face with a nasty exception:</p>
Run bundle install – take 2
I had read somewhere previously (sorry, can’t remember exactly where) about sometimes needing to
explicitly specify the target path for the “bundle install” command. In this case I can just use
the $BUNDLE_PATH environment variable that RVM manages for me:</p>
This seems to fix the exception above, but I’ll be honest, I’m not exactly sure why yet. (And yes,
that does bug the heck out of me)
Putting it all together
Now that we have all of our commands ready to go, we can simply call the built in “run” method
and pass in each command concatenated one after another:</p>
If all is well, you should see a nice green message from Bundler saying your bundle is complete.
</post>
As I mentioned before I’m not all that happy with this solution, as it seems like there is probably
a better way to get Vlad, RVM and Bundler all working nicely together. I’d be really interested
to know of a better way.
Anyways, I hope this post benefits somebody in the future. Even if it’s myself a year from now. 🙂
RVM, Bash Scripting and Rails 3 Edge
I’ve only begun to tap into the power of bash scripting, but I had a need to automate setting up a Rails 3 app on edge, using RVM like I want. So I decided to whip up a very simple script that does the following for the name of app you’re creating:
</p>
OSX Terminal Automation
My OSX Terminal Environment (as of today)
Some of this might be old hat for a lot of you, but maybe this will help at least a few people. I’m a pretty big automation addict. During my Ruby on Rails work, I find myself opening up the same set of terminal windows, positioned in the same way, running the same commands…all the time. I typically keep at least 3 OSX terminal windows open (some with multiple tabs). But when I sit down to start working with nothing open yet, I usually keep 2 terminal windows tiled to the left, 1 on top of another.
The top one I usually use for most filesystem and git operations. I also use this one to open other tabs for running things like rails console or a mongodb console if necessary.
The bottom one I usually have rstakeout running in the background to run my specs or cucumber scenarios automatically.
Then I keep a third terminal window open, tiled to the right at full height running rails server in one tab and compass watch in another tab.
Automating It
First step is to set up specific terminal settings for each window/tab based on how you want them to behave when they start. Here is an example of a basic terminal that changes to the directory I want when started.
And here is a separate terminal setting for automatically starting Compass when the terminal session is started.
And here is a another one for autostarting the rails server when the terminal session is started.
Now, all these can easily be combined into a ‘Windows Group’ that can be opened by the OSX Terminal in one shot, opening multiple terminal windows/tabs all at once using separate terminal settings. Just open the terminal windows/tabs and position them how you like them, then just save it as a window group.
Here’s a quick video of a window group in action:</p>
My OSX Terminal Environment from Joey Beninghove on Vimeo.
As you can see, I can get my entire terminal environment up and running with a single command. (Even better when I can use the fabulous ViKing app by Kevin Colyar to navigate the OSX menus using Vim bindings!)
Wrap Up
In case you’re wondering which OSX terminal theme I’m using, it’s my own tweaked version of IR_Black which I really like. Also, if you want to try out my terminal settings directly, I’ve exported the terminal settings files and the window grouping and pushed them up to my terminal repo on GitHub. Also I’d LOVE to hear other tips on how you’re automating your development environments, specifically in OSX!
Happy Automating!
Getting plugged into Ruby
Brad Mead asked a question on my [previous
post](/blogs/joeydotnet/archive/2010/06/23/from-alt-net-to-not-net.aspx)
about my favorite community hang outs, lists, sites, etc. Instead of posting a long comment reply, I decided to turn it
into a post of its own.
If you don’t like link posts, then you might want to skip this one. But I always end up
picking up a couple things from other folks that share their online resources, so maybe this will do that for someone else
too. This post is kinda aimed at corporate-ish developers that maybe aren’t already plugged in too much. For the rest
of you, a lot of this might just be obvious.
Blogs
I don’t follow too many individual bloggers. In fact, I actually don’t read that many blogs at all these days. But the
ones I do check occassionally are usually aggregate blogs that give me a pretty good sense of what’s going on in the
world of Ruby.
Screencasts
I’m a big fan of screencasts. I tend to learn quite a bit from watching other people write code. Maybe you do too.
Podcasts
Considering I work at home nearly 100% of the time (with the exception an occasional nomading trip to Starbucks), I
don’t get much driving time to listen to podcasts. But I manage to squeeze in some time during my trips to Chipotle and late at
night to listen to a few. Here are some of the Ruby/OSS related ones.
Github
You’ll want to get very familiar with GitHub and the community surrounding it. Since who/what you follow largely
depends on what specific gems or frameworks you’re using, I won’t list specific ones here. But suffice it to say, that
GitHub plays a huge role in bringing the Ruby community together. Git wit it!
IRC/Mailing Lists
I’m grouping these two together since they tend to go hand in hand. Once you start using a particular Ruby
gem/framework out there, you’ll usually find they have an associated mailing list and/or IRC channel. I like to use
mailing lists mostly for learning interesting tidbits from other people’s questions and throwing out the occasional
question myself. IRC is great when you need to get some help (or give some help) in a ‘just in time’ type of way. I
know I mentioned it in my previous post, but it is quite amazing how helpful the folks in the Ruby and open source
communities can be. Even for newbies like me… 🙂
Conferences
I’ve yet to go to a Ruby-related conference, but hopefully I’ll make it to one sometime soon. Probably the best way to
find these is just to [google for
them](http://www.google.com/search?client=safari&rls=en&q=ruby+conferences&ie=UTF-8&oe=UTF-8).
User Groups
If you can’t make it to a conference, perhaps look for (or start) a Ruby users group in your area. I’ve started
attending our local CVREG group and it’s been great. I’ve met some great folks so far and
hope to get much more involved in the local Ruby community.
I admit that a lot of my community interaction does happen over Twitter. I went through my followers and created a
Ruby list which you can follow if you’re interested in some of the Ruby folks
I follow.
From ALT.NET to NOT.NET
For a long time now I’ve been known as “joeyDotNet”. Of course I’ll never make the mistake tying my name to a
particular technology like that again. Especially given some of the recent changes I’ve made in my career. For the
past 10 years I’ve been primarily a web developer using Microsoft-based technologies. In the latter years I started
to grow pretty frustrated with both the Microsoft development stacks as well as their operating systems. The ALT.NET
“movement” helped a little, but for me, the bloat of the development tools and ceremony required in the languages
overshadowed the well-intentioned ALT.NET efforts. Of course this is merely my own personal opinion.
A couple months ago I made a pretty big change by leaving .NET completely to start focusing on learning and building
software using tools and frameworks that I enjoy and involve less friction. But instead of hearing me whine about my
specific issues with .NET development, I thought maybe I would give a glimpse into my experience so far as I’ve become
part of the NOT.NET crowd.
Perhaps I’m a glutton for punishment, but I find that in order to really learn something, I have to throw myself into
the lake and basically sink or swim. That’s pretty much what I’ve done by leaving .NET into the world of Ruby.
Today marks exactly 2 months that I’ve been working exclusively with Ruby/Rails and I have to say it has been a very
enjoyable experience so far (and frustrating at a few times). I’ve dabbled with the Ruby language and with Rails a bit
over the past couple years, so I had an idea of what I was getting into. Doing it 100% day in/out is a completely
different story though. But at this point, I’m not looking back a bit.
Good
Operating systems are cool again
One of things I’ve very much enjoyed is being able to completely ditch Windows as an operating system in favor of using
my MacBook Pro with OSX for everything. It’s no secret that I’m a pretty big Apple fan, and I think, for good reason.
The simplicity of the OS and the top notch software that is available for OSX makes the actual usage of the various
design and development tools fun and productive again.
Simple tools, less friction
Since I’m a huge fan of Vim, I’m naturally using MacVim as my main editor, along with a few Terminal windows and a browser.
That’s it. No fancy IDEs or designers to get in my way. Just code. I am using a couple Vim plugins to allow better
navigation around the code. NERDTree and
Command-T which I would highly recommend. I’ve also jumped head
first into Git as my primary source control and I continue to be very happy with that decision. All those years wasted
on Subversion, which incidentally performs subversive acts on the instituion of actually getting things done!
Doing more with less
One of the common themes I’ve found so far in working with Ruby in general and Rails in particular is how much work you
can actually get done with so little code/effort. In 2 months time I’ve been able to build a fairly sizable greenfield
Rails app from the ground up and almost ready for the first production deployment next week. All while I do a TON of
learning in the process. I have no clue how long
this would’ve taken me in .NET, but I’m certain it would have been significantly longer. Once you don’t have to deal
with IDEs, solutions, project files, unnecessarily complex build scripts, high-ceremony languages or even compilation,
you really start to realize how much overhead all of that stuff adds, preventing you from getting real work done, fast!
Buh-bye IoC containers
In my experience with C# over the years, it became apparent to me that in order to be productive in building flexible
software in .NET that the use of an IoC container to handle dependency resolution was pretty much required. And I
totally bought into it, using them heavily for many years. And for the most part, I think it was a good idea. However
I will freely admit that a lot of my usage of them was to enable mocking and easier testing. I think if a lot of
developers were honest about it, they’d say the same thing. That’s not to say that’s the only reason of course. IoC
has its place in doing some crazy stuff with decorators/proxies and all kinds of other useful jazz.
Contrast that with Ruby and I can honestly say I have not missed IoC containers one bit. Being able to work in a much
more open language has been a joy. Composition over Inheritance is the real deal in Ruby and it’s being demonstrated
more and more in frameworks like Rails 3 and Mongoid. Being able to open up and extend any class in Ruby is also
extremely powerful (and dangerous!).
Feeling the love
Perhaps one of the more feel-good things about working with open technologies like Ruby is the community. I honestly
have never experienced a community who is more willing to help out with anything like I’ve seen in the Ruby community
so far. I’ve made a great many friends so far and hope that I can start contributing back to the community once I get
my head above water. Open source in the .NET world has grown a bit over the years, but it still seems light years away
from the Ruby and related communities. And I’m not sure why, but I can’t help but think it has something to do with a certain corporate
entity behind .NET.
Making dreams come true
For quite a few years now I’ve had an increasing urge to go “out on my own” and be “independent”. More specifically
I’ve dreamed for a long time now about making a living by building my own software. A
Microprenuer, if you will.
But the whole time I pretty much knew there is absolutely NO way I would build my own software products using Microsoft
technology. In my opinion technologies like Rails, Node.js and MongoDB are much better suited to building next generation
web applications than anything on the Microsoft stack right now. I’m sure many will differ with that opinion, but
that’s just how I see it. So in order to move closer to my dreams and goals, I knew I would have to move away from the
Microsoft world at some point. I’ll always wish I had done it sooner, but with Rails 3 getting ready to “ship” it seems
like a great time to be focusing my efforts there.
Bad
Becoming one with the *nix
I admit it. Early on, it has been tough to get up to speed on the _nix tools and setting up Linux servers, etc. I’ve
always been a pretty big command line junkie. But I’ve learned that being a *Windows_ command line dude is a whole lot
different than sitting down at a Bash shell for the Linux slice you just bought and now need to get setup with a full
Rails stack. Nevertheless, I’ve forced my way through it thanks to the interwebs and honestly in great part due to the
great articles over on Slicehost. I still have a lot more to learn, but I’m starting
to realize that those crazy bearded Linux heads are onto something. 🙂
Living on the edge
In accordance with my sink or swim style, I decided to jump on the edge of quite a few things including Rails 3 beta
and all of the associated “pre” gems for testing, persistence and others. That has been painful at times. Sometimes it
takes you a little bit to troubleshoot a huge stack trace of errors to find an issue with an incompatible gem. Lots of
times it was fixed by just updating the gem or actually applying specific patches. All in all, it hasn’t been too bad
though and it has forced me to dig into the actual code of the frameworks I’m using which has only increased my learning
of the Ruby language and certain patterns used in the language.
Ugly
Well about the only thing ugly so far is probably some of my Ruby code. I’ve hit a few roadblocks here and there
because of my lack of some of the advanced capabilities of Ruby as a language. And sometimes I’ve had to just get it
working and move on until I get more proficient with Ruby. Often times I just “know” that there is a better way to do a
particular thing, even if I don’t know exactly what that way is. Like anything else, I’m sure I’ll come back a month
later, a year later and throw up a little in my mouth when I see some of the Ruby I’m writing. But I’m down with the
continuous improvement lifestyle, so I’ll just keeping moving forward. 🙂
Well this was basically a stream of consciousness post, but perhaps it will give some insight into the life of a fellow
geek that is striving to reinvent his career.
Quick Fix (and a question): Mongoid Edge
I just went throught the process of upgrading my current app to the latest edge for Rails 3, Mongoid and all of my other
gems. And when I went to run my specs, I received this error:
Database command 'drop' failed: {"ns"=>"your_db.system.indexes", "errmsg"=>"assertion: can't drop system ns", "ok"=>0.0}
The only time a drop is called is in my spec_helper.rb file:
/spec/spec_helper.rb
Rspec.configure do |config| # other config stuff here config.before(:each) do Mongoid.master.collections.each(&:drop) end end
What that block does is drop all of my Mongoid collections before each spec is run to ensure I have a “known state” for
my specs. This has always worked just fine as is, but it appears that something has changed in the latest Mongoid
causing it to error on attempting to drop “system.indexes”. After some tinkering, this is how I resolved it:
/spec/spec_helper.rb
Rspec.configure do |config| # other config stuff here config.before(:each) do Mongoid.master.collections.select { |c| c.name != 'system.indexes' }.each(&:drop) end end
Simple fix, but it gets the job done. I just simply exclude “system.indexes” from the collections to drop and all is
well. Since this is only for my tests, I think this should be fine. But…
I want to know if anyone else knows why this is happening and if there is a better way to resolve it. Anyone?
Cucumber, A Brief Overview
Cucumber
I’ve found Cucumber to be a pretty nice way of doing
high level acceptance/integration testing. It’s also the first time I’ve ever thought that ATDD (acceptance test driven
development) is actually achievable. The idea is that you write your “stories” in plain english, preferrably
with your client/customer/product owner using the given/when/then style of syntax. Once written, these stories can be
run through the Cucumber framework where it is parsed and coupled with custom ruby code (some of which you have to
write) to essentially give you executable specifications. Of all the attempts I’ve seen out there to achieve ATDD and
executable specifications, Cucumber really seems to have it nailed the best so far. Writing the stories does take some
getting used to as you do somewhat have to learn to speak the “language” of Cucumber. But after writing your first
couple “features”, as Cucumber calls them, you pretty much get the hang of it.
Example
Here is an example of what a Cucumber feature looks like.
/features/users/add_new_user.feature
Feature: Add new user In order to allow a new user to access the system As an admin I want to add a new user to the system Scenario: New link is clicked from the users page Given I am logged in as an admin And I am on the users page When I follow "New" Then I should be on the new user page Scenario Outline: Required text fields are blank Given I am logged in as an admin And I am on the new user page When I fill in "" for "" And I press "Save" Then I should see an error for "" Examples: | field_name | | First name | | Last name | | Email | | Password |
The first section under the feature name is simply text to describe the feature in a typical As a/I want to/So that
format. That text is for display purposes only and is not used during execution.
Next comes the scenarios which are executed when run through Cucumber. The first scenario simply verifies that
when a link named “New” is clicked from the main users page, that it takes you to the “New User” page. This is a pretty
simple one, but it’s nice to have some of these as kind of smoke tests.
The second one is interesting in that it acts as an outline to keep your cucumber features DRY. If there is one thing
you’ll notice about the Ruby/Rails community and the tools/frameworks used is that there is an extreme emphasis on
keeping things DRY, which I love. What this outline does is use tokens in the actual scenario steps, then specify a
simple table representation that is used to plug in each “example” value when the scenario is run. So this scenario
outline actually gets run 4 different times, once with each value for listed. The closest parallel I can
think of in .NET land is RowTests with MBUnit, but I’m sure there are others such as Fitness, which I haven’t used too
much.
I’ve used Cucumber to drive out almost every feature so far in this Rails app I’m building. And I can definitely
say it’s been worth it. Especially when I go to update my gems to a new version or even try out the edge version
straight from the Git repo. I’ve been able to lean on my Cucumber features to give me a nice sense at a high level
as to the health of my application from the user’s point of view.
Great, so how does all this work?
Under the hood, Cucumber is actually spinning up the Rails app, opening the pages you tell it and clicking links and
filling out text fields on the actual page. It does this using a web testing framework such as Capybara or Webrat.
Each one comes with a set of pre-defined steps that you can use to cover a lot of the common actions you need to do
on a web page such as clicking links/buttons, filling out forms and inspecting the content on the page using css or
xpath helpers. Capybara seems to be taking over Webrat’s long rule in this space and is the default option when
getting Cucumber set up. There is also the ability to test javascript/AJAX using Capybara with either EnvJs or
Culerity/Celerity. Unfortunately I haven’t been able to get this working yet, but I plan to very soon because
I’m already starting to build some non-trival client side stuff now that I’d really like to get some automated
tests around.
No, really, how DOES this work?!?
Ok, so the “magic” of Cucumber is all in the step definitions, which are defined using Ruby. There is also some
supporting Ruby code that you get out of the box with Cucumber that can help get you started. For example, it
creates a file named “paths.rb” for you which is where you tell Cucumber where to navigate given a set of text.
So when Cucumber encounters a line like this in your plain text scenario, “And I am on the users page”, it
automatically knows the phrase “I am on” and signals to Cucumber that you’re wanting to navigate somewhere.
Then it looks at the text after that, which is “the users page” in this case. This is where you need to give
Cucumber a little help.
Here is an example of how to help a cuke out.
/features/support/paths.rb
module NavigationHelpers def path_to(page_name) case page_name when /the users page/ users_path # rails routing helper method when /the new user page/ new_user_path # rails routing helper method end end end
Since the Cucumber feature files are plain text and you are encouraged to use whatever language feels
natural to you and your customer, you’re going to inevitably write something that Cucumber just doesn’t
know how to do out of the box. This is where custom step definitions come into play. But don’t worry,
they’re not as scary as they may look.
From the scenario above, Cucumber has no idea how to interpret “Given I am logged in as an admin” without
a little help. Below you can see that I’m specifiying a regular expression for the text that Cucumber
needs help with and then simply using Capybara to visit a page, fill in a couple fields and click a button
to perform the login using the actual login page. Don’t let the regular expressions stuff scare you off.
The awesome thing about running your Cucumber features is that when it comes across something it doesn’t
understand it gives you the exact snippet of Ruby code that you can literally copy/paste from the terminal
into a custom step file like the one show below. Since I’m still not a regular expression guru, I LOVE that
Cucumber helps me with that!
/features/step_definitions/login_steps.rb
Given /^I am logged in as an admin$/ do user = Factory.create(:admin) # I'll get to this later (factory_girl) visit(login_url) fill_in('Email', :with => user.email) fill_in('Password', :with => user.password) click('Login') end
Cucumber integration with Capybara (or Webrat) comes with a nice set of web related steps that cover a lot
of the common cases. But at some point you’ll definitely want to define your own web related steps. I just
created a file named “custom_web_steps.rb” to place them in. This is a simple web step I defined to allow me
to assert that an error is shown on the page containing the text I supply, which comes from my plain text scenario.
Notice that you can chain together other web steps within each other like I’m doing below. My custom web step below
is simply leveraging one of the built in Capybara web steps to do what it needs.
/features/step_definitions/custom_web_steps.rb
Then /^I should see an error for "([^"]*)"$/ do |text| Then "I should see "#{text}" within ".error"" end
Clear as mud?
Well hopefully that gives you a little insight into how to get going with using Cucumber to drive top-down development
using acceptance testing. At least, this has been my experience with it so far. I’d be very interested to hear your
feedback and some of the ways you’ve been successful with acceptance testing using Cucumber or any other framework for
that matter.
The Ruby/Rails Life – My Rails 3 Stack – Part 2
Rails Deployment & Testing
There are some really nice tools available for deployment and testing rails. Below is a brief description
of some of the ones I’ve been using with success.
Capistrano
I remember in the early days of my attempts of using Rails back in the 1.x days, the deployment/hosting
story was a bit of a headache, even with Capistrano back then. However things have improved dramatically,
especially with things like Phusion Passenger. Capistrano is still strong too and I’ve
found that it makes deploying Rails apps extremely simple. The ability to make that “one quick change” and redeploy
in seconds is an awesome feeling.
Here is a somewhat annotated example of what my deploy script looks like just to give you a glimpse of what a
Capistrano script looks like (with certain information removed of course). If you’ve never used Capistrano before
then this might look a bit foreign. Again, this is just a taste, but you’ll have to dig in a bit more to really
understand the moving parts here.
Example
/config/deploy.rb
# just some basic info, including where to grab the code from set :application, "My Groovy Rails App" set :repository, "[git repo]" set :scm, :git # there are some SSH options that i don't fully understand yet... :) default_run_options[:pty] = true ssh_options[:forward_agent] = true # ex. /var/www/my_groovy_rails_app set :deploy_to, "[path]" # just some basic server properties role :web, "[server]" # Your HTTP server, Apache/etc role :app, "[server]" # This may be the same as your `Web` server role :db, "[server]", :primary => true # This is where Rails migrations will run # configure environment variables to propertly use RVM (Ruby Version Manager) on the server # as you can see i'm using Ruby 1.8.7 Enterprise Edition on the server set :default_environment, { 'PATH' => '/home/you/.rvm/gems/ree-1.8.7-2010.01/bin:/home/you/.rvm/gems/ree-1.8.7-2010.01@global/bin:/home/you/.rvm/rubies/ree-1.8.7-2010.01/bin:/home/you/.rvm/bin:$PATH', 'RUBY_VERSION' => 'ree-1.8.7-2010.01', 'GEM_HOME' => '/home/you/.rvm/gems/ree-1.8.7-2010.01', 'GEM_PATH' => '/home/you/.rvm/gems/ree-1.8.7-2010.01:/home/you/.rvm/gems/ree-1.8.7-2010.01@global', 'BUNDLE_PATH' => '/home/you/.rvm/gems/ree-1.8.7-2010.01' # If you are using bundler. } # automatically restarts the app after deployment namespace :deploy do task :start do ; end task :stop do ; end task :restart, :roles => :app, :except => { :no_release => true } do run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}" end end # tasks for bundler, which is the new way dependencies are managed in Rails 3 namespace :bundler do task :create_symlink, :roles => :app do shared_dir = File.join(shared_path, 'bundle') release_dir = File.join(current_release, '.bundle') run("mkdir -p #{shared_dir} && ln -s #{shared_dir} #{release_dir}") end task :bundle_new_release, :roles => :app do bundler.create_symlink run "cd #{release_path} && bundle install --without test" end task :lock, :roles => :app do run "cd #{current_release} && bundle lock;" end task :unlock, :roles => :app do run "cd #{current_release} && bundle unlock;" end end # the actual task that runs bundler to ensure all dependencies on the server are up to date after "deploy:update_code" do bundler.bundle_new_release end
RSpec 2
A lot of you have probably at least heard of RSpec, with some of you perhaps even using it now. It’s a pretty
awesome testing framework, dare I say, BDD framework. Surprisingly I’ve really only scratched the surface as to
what RSpec is capable of, but it’s a joy to use for sure. So far I’m mainly using it for testing my models and a
little bit of controller testing. However I’m leaning on my higher level Cucumber integration tests for exercising
my controllers for the most part. I also haven’t gotten into mocking all that much yet, which RSpec has support for
as well. Perhaps at some point I’ll get into mocking. This is probably going to get me flamed by the ALT.NET’ers,
but honestly I just haven’t felt the pain in the fact that most of my tests DO in fact hit my local test database.
Perhaps that’s because I’m using MongoDB as my database which is so fast I don’t really notice that much of a
performance hit.
Example
Here’s a brief example of a simple model spec in RSpec.
/spec/models/user_spec.rb
describe User do context "first name" do it "is required" do user = User.new user.should_not be_valid user.errors[:first_name].first.should == "can't be blank" end end context "email" do it "is unique" do user1 = User.create!(:email => "[email protected]") user2 = User.new(:email => "[email protected]") user2.should_not be_valid user2.errors[:email].first.should == "is already taken" end end end
Certainly not an exhaustive example, but it gives you the idea of how a basic spec looks in RSpec. And even this is
not nearly as elegant as I’ve been seeing others show lately. I would highly recommend you watch
@l4rk‘s presentation at the Scottish Ruby Conference on
Pure RSpec. I learned a ton from this presentation
and hope to incorporate some of his tips into my specs soon. Specifically the elegance of “let” and “subject”.
Oh, one more note. I’m using RSpec 2, which is still in the early stages, but works with Rails 3. And I’m
actually running it straight from the master git repo. So, use at your own risk!
Cucumber
I’ve named this cute little guy Larry. If you have kids, then you know why. 🙂 This is a pretty nice way of doing
high level acceptance/integration testing. It’s also the first time I’ve ever thought that ATDD (acceptance test driven
development) is actually achievable. The idea is that you write your “stories” in plain english, preferrably
with your client/customer/product owner using the give/when/then style of syntax. Once written, these stories can be
run through the Cucumber framework where it is parsed and coupled with custom ruby code (some of which you have to
write) to essentially give you executable specifications. Of all the attempts I’ve seen out there to achieve ATDD and
executable specifications, Cucumber really seems to have it nailed the best so far. Writing the stories does take some
getting used to as you do somewhat have to learn to speak the “language” of Cucumber. But after writing your first
couple “features”, as Cucumber calls them, you pretty much get the hang of it.
Example
/features/users/add_new_user.feature
Feature: Add new user In order to allow a new user to access the system As an admin I want to add a new user to the system Scenario: New link is clicked from the users page Given I am logged in as an admin And I am on the users page When I follow "New" Then I should be on the new user page Scenario Outline: Required text fields are blank Given I am logged in as an admin And I am on the new user page When I fill in "" for "" And I press "Save" Then I should see an error for "" Examples: | field_name | | First name | | Last name | | Email | | Password |
I have another post written that gives a bit more of an overview of Cucumber with more code examples, so look for that
soon.
Steak
I’ve only started to play around with this one, but it’s a pretty interesting take on acceptance/integration testing.
Unlike Cucumber, it doesn’t use plain text stories. Instead it’s basically just a small wrapper of aliases on top
of RSpec that give you same kinda feel as Cucumber, but without the overhead of the English language. I’m going to
be spiking a bit more with this one as I think it might come in handy for some of my other integration testing needs.
Oh, and gotta love its logo! Beef! It’s what’s for…testing?
factory_girl
Interesting name, very useful tool. You might have guessed that this is a tool to create objects for you. Not a whole
lot to say, but it’s really handy to easily create objects in varying states for testing purposes.
Example
/spec/factories.rb
# creates a new User model Factory.define :user do |u| u.first_name 'Bud' u.last_name 'Abbott' u.email { |x| "#{x.first_name.downcase}.#{x.last_name.downcase}@blah.com" } u.password 'secret' u.password_confirmation 'secret' u.group_ids { [Factory.create(:group, :name => 'Users').id] } u.roles ['manager'] end
You can use this factory in a variety of ways.
# instantiates the User model only, does NOT save it to the database Factory.build(:user) # creates the User model and saves it to the database Factory.create(:user) # returns a hash of attributes representing this user # useful for testing controllers simulating params or for validation Factory.attributes_for(:user) # I haven't really found a use for this one yet Factory.stub(:user) # You can override specific values if desired # This would build the user setting a name # of "Lou Costello" instead of the default "Bud Abbott" Factory.build(:user, :first_name => "Lou", :last_name => "Costello")
rstakeout
This is a nice little script I got from Geoffrey Grosenbach, of PeepCode fame. I use to automatically run my Cucumber
features and RSpec tests anytime I change a file in my Rails app. I find rstakeout to be a lot simpler to get going than
Autotest/Autospec. It has growl integration too. And yes, I do like my green and red growl notifications. 🙂
Example (from a terminal)
rstakeout "cucumber -t @wip"
If I run that in my terminal, it automatically watches all files in my Rails app for changes and runs the command I give
it on each change. In this case, it runs my cucumber features, but only ones I’ve tagged with @wip, meaning ones I’m working
on at the given moment.
I’ve posted a Gist of the rstakeout script I’m using since there has been some confusion over which version to use.
Conclusion
Well I hope that gives you a taste of some of the deployment and testing tools I’m using so far in Rails. I feel like I
still have a ton to learn of course, but so far I’m really enjoying the testing experience that the Ruby language gives
me.
What are your favorite deployment/testing tools in Ruby/Rails? Leave a comment and let me know!
The Ruby/Rails Life – My Rails 3 Stack – Part 1
As some of you might know, About a month ago I left my almost 10 year career as a Microsoft developer to become
an independent Ruby/Rails developer (a term I’m deeming “pulling a Gunderloy”).
It was long overdue for me and I couldn’t be happier to be free from the shackles of Microsoft.
It seems lately there are more and more folks coming to the
same realization as I have and are making the jump to work with more open technologies and platforms on the web.
But I’ll leave that conversation to the twitterverse.
Big Fat Disclaimer
As noted above, I’ve only been doing full-time professional Ruby/Rails development now for about a month.
So what you see below is the outcome of my past month of both struggles and successes. I don’t claim to
be anywhere near a Rails expert yet, so please feel free to leave nice and helpful comments about any misconceptions
I may convey below. 😀
My Rails Stack
I’ve been given a pretty great opportunity to build a large greenfield product from the ground up using any
technology stack I want. Here is a brief overview of the technologies I’ve chosen to use for my current project,
which I’m loving so far. I’m not going to go into too much detail, but will provide a few useful links for the
relevant projects where you can read up on how to get rolling with them. I’m purposefully not including links
to everything I’m going to talk about because Google is your friend.
RVM (Ruby Version Manager)
This is such an awesome tool. This not only allows you to run completely different Ruby versions
side by side in isolation, but also the entire environment include gems are isolated from each other.
So you can set up different Ruby environments to test out different versions, and the gems you install
in a particular environment don’t affect anything else. This is a must have if you’re experimenting
with different Ruby versions, which I am not yet.
Ruby 1.8.7 (for now)
I decided to stick with Ruby 1.8.7 for now since it seems to work just fine with Rails 3 and plays
nice with all of the gem dependencies I’ve taken on so far, some of which may not be up to par yet
with Ruby 1.9.x. I suspect at some point I’ll make the switch over to Ruby 1.9 and see how it does.
And most certainly once Rails 3 finally drops.
Rails 3 (Beta 3/Edge)
I decided to go with Rails 3 for this new project, mainly because Rails 3 is quite a huge update over
2.3.5 2.3.8, the current “offical” version of Rails. And because Rails 3 comes with some
really awesome new features and improvements. I started with just running Beta 3, which is pretty solid,
but decided to switch over to Edge Rails for a while to get some of the benefits of some of the dependencies
I’m using that take advantage of Edge Rails. There have been a few minor hiccups along the way,
but nothing major so far.
There are many great resources out there for Rails 3, but if you’re interested in really nice detailed
posts and screencasts on new Rails 3 features, check out the Rails Dispatch blog
where Yehuda himself and other great guys are posting some really great content. The excellent
Rails Guides are also being updated pretty rapidly to cover the changes in Rails 3.
Or if you want to dig directly into the API documentation check out one of my favorite Ruby API sites,
RailsAPI. RailsAPI is pretty cool in that it lets
you create a customized API documentation package for Ruby, Rails and popular gems that you can either
browse online or even download.
Haml
A lot of folks might already know my LOVE for Haml. I’ve been using Haml for about a year
and half already in the ASP.NET MVC world using NHaml. So it was a no brainer for me to choose it for this Rails
project. Not sure there is really much more I can say about it except you must try it. 🙂 No, seriously, just do it.
Your hands will thank you!
Sass
The lovely sister to Haml, allowing you to create DRY stylesheets with the use of variables, mixins and all kinds
of other goodness. This is the first time I’ve used Sass on a real project and even though I’m not leveraging
all of its capabilities yet, I love the simplicity of the language. Hopefully I can dig in a bit more soon to
further improve my stylesheets.
Compass/Blueprint
Taking styles and page layout to a whole new level. Compass is a really nifty “framework of frameworks” that sits
on top of Sass and a handful of grid-based CSS frameworks such as Blueprint or 960.gs to name a couple. I chose to
go with the default of Blueprint and it’s been pretty good so far. The out of the box CSS resets, browser-specific
fixes and typography make it really easy to get a decent looking site up and running fast.
jQuery
The fact that Rails 3 still ships with Prototype out of the box still kinda boggles my mind. Nevertheless
with the increased modularity of Rails 3, it’s really easy to swap out a lot of the parts of Rails with
alternatives. For example, you can pretty easily swap out Prototype for jQuery as the default javascript in
Rails 3.
/app/views/layouts/application.html.haml
= javascript_include_tag :defaults
/config/initializers/jquery.rb
if ActionView::Helpers::AssetTagHelper.const_defined?(:JAVASCRIPT_DEFAULT_SOURCES) ActionView::Helpers::AssetTagHelper.send(:remove_const, "JAVASCRIPT_DEFAULT_SOURCES") end ActionView::Helpers::AssetTagHelper::JAVASCRIPT_DEFAULT_SOURCES = ['jquery-1.4.2.min.js', 'rails.js'] ActionView::Helpers::AssetTagHelper::reset_javascript_include_default
MongoDB
After watching the rise of document-oriented databases for a while and some of my own learning/experimentation,
I decided to make the move to MongoDB as my primary database platform. I say “primary” because I’m a firm believer
in choosing the right tool for the job. So if there are some models that are, for instance, heavily relational
or need strict transactions then MySQL might be a good fit for those particular pieces. If I have a set of simple data, say,
lookup data, perhaps throwing it in a wicked fast key/value store like Reddis might be better for that particular data.
However, most of my models so far in this project are well suited for a schema-less document store given their
hierarchical nature and need to be flexible with possible custom attributes.
MongoDB has been an absolute joy to use so far. It just simple stores whatever you give without complaining.
Don’t have a database named my_cool_app yet? No problem, just attempt to write to a non-existent database and it’ll create it for you.
Don’t have a collection named codemonkeys yet? No problem, just send off a new collection to MongoDB and it’ll
create a new collection (aka table) for you. No migrations, no fuss. I hardly even notice the database is there sometimes.
Mongoid
There are quite a few mappers out there now for Ruby and MongoDB. MongoMapper, MongoDoc, Mongoid, Candy and a bunch
of others (sorry if I left your favorite one out). At the time when I was starting my Rails 3 project Mongoid seemed
to be the most “Rails 3 friendly” one since it supports the new ActiveModel abstraction and Rails Validations out of the box. I
believe some of the others are getting up to speed now as well, but I’m really liking Mongoid so far. Each MongoDB mapper
takes a slightly different approach. Some try to mimic Active Record, while others just give you the bare bones for
you to handle your persistence and querying any way you’d like. Right now I like Mongoid because it seems to strike a
pretty good balance. You get some Active-Record like querying methods, but it also has a very powerful Criteria API.
But like most OSS projects, Mongoid has its own opinions about how you should be persisting your objects. Specifically,
Mongoid leads you down the path of using embedded documents as much as possible, which is the ideal way to store documents
in MongoDB. Oh and did I mention that Mongoid heavily favors composition over inheritance, which is a big win for me.
Another interesting tidbit is that Mongoid is the brainchild of Durran Jordan, of Hashrocket fame. I continue
to be amazed at the number of awesome OSS contributions that come out of the guys at Hashrocket.
Devise
One of the first things I needed to tackle in this new Rails 3 project was authentication. I knew there were a few
good Ruby authentication frameworks out there. Authlogic is the “big guy” in the room here. But Devise is gaining
quite a bit of traction and after I spiked with it for a bit, I really liked it. It really takes advantage of Rails 3
and is extremely flexible and extensible. Devise is one of the few frameworks I’ve used that has managed to achieve
a high degree of flexibility while maintaining its simplicity. Then again, I’m starting to see that characteristic in
a lot of Ruby-based frameworks. Some of the things that Devise will do for you is database authentication, new user
registration, confirmation, password recovery, “remember me” functionality, user login tracking, session timeouts,
validations and account lockout to name a few. There also a growing number of plugins for Devise for things like
Facebook, LDAP and OpenID authentication.
CanCan
Of course authorization usually goes hand in hand with authentication. Don’t get them confused! There are quite a
few players solving this problem as well. Declarative Authorization was the first one I looked at and, while it looked
great, I didn’t need quite that many features yet. I found a simpler solution called CanCan by none other than Ryan
Bates of RailsCasts fame. CanCan is very easy to sit on top of Devise and all authorization rules are set up in single
model class you define named Ability. CanCan makes no assumptions about how you want to handle authorization. Whether
it’s role-based or custom or both, it’s pretty easy to write a few simple rules to get things going. Also very easy to
check your authorization rules in your controllers and views with simple methods like can? and cannot?.
To Be Continued…
That’s enough for this post I think. In Part 2, I’ll talk about the deployment and testing tools I’m currently using.
subscribe via RSS