The Devver Blog

A Boulder startup improving the way developers work.

Single-file Sinatra apps with specs baked-in

It’s so easy to create little single-file apps in Sinatra that it almost seems a shame to start a second file just for tests.  The other day Dan and I decided to see if we could create a Sinatra app with everything – including the tests – baked right in.  Here’s what we came up with.

#!/usr/bin/env ruby
require 'rubygems'
gem 'rack', '=0.9.1'
gem 'thin', '=1.0.0'
require 'sinatra'

get '/' do
  content_type 'text/plain'
  "Hello, world"

# Run me with 'spec' executable to run my specs!
if $0 =~ /spec$/
  set :environment, :test
  set :run,         false       # Don't autostart server

  require 'spec/interop/test'
  require 'sinatra/test'

  describe "Example App" do
    include Sinatra::Test

    it "should serve a greeting" do
      get '/'
      response.should be_ok
      response.body.should == "Hello, world"

    it "should serve content as text/plain" do
      get '/'
      response.headers['Content-Type'].should == 'text/plain'


view this gist
The code switches modes on the name of the executable used to run the file. If we run it with the


command, we get a test run:

$ spec -fs sinatra-tests-baked-in.rb

Example App
- should serve a greeting
- should serve content as text/plain

Finished in 0.007221 seconds

2 examples, 0 failures

Otherwise, if we call it as a Ruby program, it runs the Sinatra server as we would expect:

$ ruby sinatra-tests-baked-in.rb
== Sinatra/ has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.0.0 codename That's What She Said)
>> Maximum connections set to 1024
>> Listening on, CTRL+C to stop

And there you have it: a true single-file application, specs and all.


Written by avdi

May 13, 2009 at 9:00 am

Posted in Development, Hacking, Ruby

Tagged with , ,

One Response

Subscribe to comments with RSS.

  1. Great stuff Avdi, I hope to use this in the future.

    Michael Guterl

    May 13, 2009 at 10:05 am

Comments are closed.

%d bloggers like this: