Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker
Tyler Schultz

Standup 12/07/2010: bundler & rspec 2 & rails 3 – I go out of my head And I just can't get enough, I just can't get…

Tyler Schultz
Tuesday, December 7, 2010

Interesting:

  • Tests won’t run if rspec is included in the test group. rspec must be included in the development group, or both. When a test run is started the RAILS_ENV is development. After some initialization the RAILS_ENV is changed to test – a point at which the Gemfile has already been evaluated.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Upgrading your Rakefile from RSpec 1.3 to RSpec 2

Alex Chaffee
Tuesday, October 26, 2010

I’m updating Erector to RSpec 2 and came across two problems for which solutions were surprisingly difficult to Google. Here are my (finally successful) results.


Problem:

no such file to load -- spec/rake/spectask

Before:

require "spec/rake/spectask"  # RSpec 1.3

After:

require "rspec/core/rake_task" # RSpec 2.0

Problem:

undefined method `spec_files=' for #<RSpec::Core::RakeTask:0x00000101550aa8>

Before:

# RSpec 1.3
Spec::Rake::SpecTask.new(:core) do |spec|
  spec.spec_files = FileList['spec/erector/*_spec.rb']
  spec.spec_opts = ['--backtrace']
end

After:

# RSpec 2.0
RSpec::Core::RakeTask.new(:core) do |spec|
  spec.pattern = 'spec/erector/*_spec.rb'
  spec.rspec_opts = ['--backtrace']
end

See also http://github.com/rspec/rspec-core/blob/master/Upgrade.markdown (curiously cloaked from Google searches for the above problem strings).

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Standup 7/20/2010: The Daily Rubymine

Pivotal Labs
Tuesday, July 20, 2010

Interesting Things

  • RubyMine 2.0.2, refactor => extract partial == FAIL. If you select multiple divs and perform
    extract partial, the selected region is removed, but only the first complete div is included in
    the new partial.

  • Rspec/Rubymine focused tests. Rubymine attempts to run focused tests using the
    --example 'text' option. Rspec apparently finds the example group, and runs the examples that are
    directly a part of that example group, but does not include descendent example groups — *which can
    lead you to think examples are passing that were not actually run*. Apparently this is
    fixed in rspec 2.

Ask for Help

“Display of time is off by an hour, presumably due to Daylight Saving Time”

The team is displaying time stored as utc in the database, using strftime, and the time is off by an hour.

“Binding Click to Checkbox with Jquery”

A team was trying to check the value of a checkbox during the click event, but getting the opposite
value. They worked through it but was hoping to find a better solution.

“Why is there a new default for include_root_in_json for rails 3?”

Just curious.

“Fakeweb, Capybara w/Selenium Webdriver == end of file?”

Getting “end of file” failure on CI. There were a few suggestions:

  • There is a fork of fakeweb that allows it to ignore localhost.
  • Consider using Webmock instead of fakeweb.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Windowed String Comparison for RSpec

Alex Chaffee
Friday, July 16, 2010

When two strings fail to match, if the difference is somewhere in the middle of the strings, it can be annoying/impossible to track down the
actual difference. I’ve written a little Comparison object that
overrides the failure message for .should == like this:

Strings differ at position 12:
expected: ..."efghijklmnopqrst"...
  actual: ..."efghijklXXopqrst"...

It shows a “prelude” of a few characters, then the difference, lined up on successive lines so they’re easy to visually scan. It also does the right thing (or tries to) if the difference is near the beginning or end of the string (i.e. does or doesn’t show ellipses).

http://gist.github.com/474363

For people who can’t wait for this to get incorporated into RSpec
proper, you can grab the code from github and require "comparison" in your spec_helper.rb and it’ll override the existing RSpec == matcher. Or wait for Issue 9 to be pulled into version 2.1 (maybe). Or if you want to use it in your favorite testing framework, the object is completely self-contained and should be easy to call from your own assert_equals or whatever.

One open question is whether the exception message should show the
full actual string as well as the comparison… On one hand, it adds
to screen clutter, but on the other hand, it can be important in
tracking down the problem, especially if the prelude is ambiguous.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Standup 04/07/2010: Passenger, Solr, Git, and rSpec timeouts

Pivotal Labs
Friday, May 7, 2010

Ask for Help

Passenger Memory Bloat

“We found one of our passenger workers is using around 900MB of memory. Has anyone has problem with Passenger memory usage? We are using REE 1.8.7-2009.10.”

Solr Master-Slave Replication

“We are interested in adding automatic failover to our Solr slave when the master fails. What are some strategies for doing this?”

Interesting Things

Git Push –force Blocked
If you find your git push being rejected, even when you use git push -f, it’s probably because your git server is configured to not allow non fast-forward pushes. You’ll need to change the server configuration to allow them.

spec –timeout
Be careful when running rspec with the –timeout option. When the timeout occurs the test process will be interrupted and it will print out a stack trace for wherever it was executing when it was interrupted. This can lead to a lot of confusion if you do not immediately realize it was the result of timing out and instead think that an exception actually occurred at that point.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Standup 07/20/2009: render_template bug in RSpec

Pivotal Labs
Monday, July 20, 2009

Interesting Things

Prior to RSpec 1.2.7, render_template in rspec-rails had a bug where render_template('new') would pass if ‘newer’ was rendered (or anything that started with ‘new’). Internally render_template was converting the string argument to a regular expression which was allowing ‘new’ to positively match ‘newer’ even though it was not an exact match. In RSpec-Rails 1.2.7 this bug has been fixed.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Using assert_select and friends in Helper Tests

Pivotal Labs
Monday, July 6, 2009

Assertions such as assert_select, assert_tag, and css_select are powerful tools in view tests. Since view helpers generate a chunk of HTML, it is sometimes practical to use these assertions to test their return value.

If you attempt to use assert_select it will fail because there has not been a call to render, as is done in a view test. To get around this you can store the result of the helper method in @response.body. Once @response.body is populated, the assertions will work like expected.

Update: For people using RSpec, Pat Maddox posted a helpful suggestion in the comments showing how to use have_tag to accomplish the same thing in RSpec style.

Example

describe TagsHelper do
  describe "#tag_list"
    describe "when the user is not an admin"

      it "should not have links to delete the tags" do
        @response.body = helper.tag_list
        assert_select "a", 0
      end

    end
  end
end

Reality Check

If you find yourself writing a helper method that generates a lot of HTML, or is overly complex, stop and ask yourself whether it would be more appropriate to move this code into a partial.

Attribution

Credit for this tip goes to a comment by Bill Siggelkow on the Nuby on Rails blog.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Use Autospec to Your Advantage

Pivotal Labs
Saturday, July 4, 2009

I like Autotest because it allows me to stay within my code editor and let my test suite run automatically in the background. After each run I get a nice, unobtrusive, growl notification informing me whether my most recent change caused the tests to fail or pass.

It used to be that setting up and configuring Autotest for the OS X with pretty growl notifications was a nontrivial task. I remember that I spent several hours getting it working a year ago. However, there has been several developments with Autotest in recent months that greatly simplify the process. One of those enhancements is that Autotest can now use FSEvent introduced in OS X Leopard so that it no longer has to continuously poll the filesystem. This has the advantage of vastly reducing Autotest’s CPU usage when idle.

Install Autotest

To setup Autotest on a Mac I recommend following this nice, up-to-date, walkthrough on the Viget Labs Blog.

Using Autotest with RSpec

Complete instructions for Autotest integration with RSpec are described on the RSpec wiki. The gist of it is this:

Add an initialize hook to Autotest

Place the following code snippet in a file called .autotest in the root of your Rails project:

Autotest.add_hook(:initialize) {|at|
  at.add_exception %r{^.git}  # ignore Version Control System
  at.add_exception %r{^./tmp}  # ignore temp files, lest autotest will run again, and again...
  #  at.clear_mappings         # take out the default (test/test*rb)
  at.add_mapping(%r{^lib/.*.rb$}) {|f, _|
    Dir['spec/**/*.rb']
  }
  nil
}

Start Autospec in Terminal

RUBYLIB=./lib RUBYOPT=-rubygems AUTOFEATURE=true autospec

To avoid typing or remembering this cumbersome set of options to start autospec, I added it as an alias to my bash environment.

alias autospec='RUBYLIB=./lib RUBYOPT=-rubygems AUTOFEATURE=true autospec'

Autotest Alternative

For using Autotest with RSpec there is also the RSpactor gem which touts advantages homogeneous to those provided by the new autotest-fsevent. I have not tried RSpactor yet. If you do be sure to check out the RSpactor wiki as there is no README on Github.

Notes

  • I do not recommend using Autotest/Autospec with RubyMine. The auto save feature of RubyMine would cause Autotest to run incessantly.
  • Sometimes autospec seems to hang after running for a while and stops detecting that a file has changed. When this happens I send a SIGINT to the process by pressing CTRL+C. This causes autospec to reload and run the entire test suite.
  • To kill autospec press CTRL+C twice.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Capturing Standard Out In Unit Tests

Alex Chaffee
Monday, May 11, 2009
    def capturing_output
      output = StringIO.new
      $stdout = output
      yield
      output.string
    ensure
      $stdout = STDOUT
    end

then…

    it "exits immediately from --version" do
      output = capturing_output do
        lambda {
          Erector.new(["--version"])
        }.should raise_error(SystemExit)
      end
      output.should == Erector::VERSION + "n"
    end
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Parallelize Your RSpec Suite

Pivotal Labs
Friday, May 8, 2009

We all have multi-core machine these days, but most rspec suites still run in one sequential stream. Let’s parallelize it!

The big hurdle here is managing multiple test databases. When multiple specs are running simultaneously, they each need to have exclusive access to the database, so that one spec’s setup doesn’t clobber the records of another spec’s setup. We could create and manage multiple test database within our RDBMS. But I’d prefer something a little more … ephemeral, that won’t hang around after we’re done, or require any manual management.

Enter SQLite’s in-memory database, which is a full SQLite instance, created entirely within the invoking process’s own memory footprint.

(Note #1: the gist for this blog is at http://gist.github.com/108780)

(Note #2: The following strategy is relatively well-known, but I thought it might be useful for Pivots-and-friends to see exactly how one Pivotal project has used this tactic for a big speed win.)

Here’s the relevant section of our config/database.yml:

test-in-memory:
  adapter: sqlite3
  database: ':memory:'

Next, we need a way to indicate to the running rails process that it should use the in-memory database. We created an initializer file, config/intializers/in-memory-test.db:

def in_memory_database?
  ENV["RAILS_ENV"] == "test" and
    ENV["IN_MEMORY_DB"] and
    Rails::Configuration.new.database_configuration['test-in-memory']['database'] == ':memory:'
end

if in_memory_database?
  puts "connecting to in-memory database ..."
  ActiveRecord::Base.establish_connection(Rails::Configuration.new.database_configuration['test-in-memory'])
  puts "building in-memory database from db/schema.rb ..."
  load "#{Rails.root}/db/schema.rb" # use db agnostic schema by default
  #  ActiveRecord::Migrator.up('db/migrate') # use migrations
end

Note that in the above, we’re initializing the in-memory database with db/schema.rb, so make sure that file is up-to-date. (Or, you could uncomment the line that runs your migrations.)

Let’s give that a whirl:

$ IN_MEMORY_DB=1 RAILS_ENV=test ./script/console
Loading test environment (Rails 2.3.2)
connecting to in-memory database ...
building in-memory database from db/schema.rb ...
-- create_table("users", {:force=>true})
   -> 0.0065s
-- add_index("users", ["deleted_at"], {:name=>"index_users_on_deleted_at"})
   -> 0.0004s
-- add_index("users", ["id", "deleted_at"], {:name=>"index_users_on_id_and_deleted_at"})
   -> 0.0003s

...

>>

Super, we can see that the database is being initialized our of our schema.rb, and we get our console prompt. We’re ready to roll!

But, running this:

IN_MEMORY_DB=yes spec spec

will still only result in a single process, albeit one running off a database that’s entirely in-memory. We want parallelization!

The final step is a script that will run your spec suite for you. You may need to edit this for your particular situation, but then again, maybe not.

#  spec/suite.rb

require "spec/spec_helper"

if ENV['IN_MEMORY_DB']
  N_PROCESSES = [ENV['IN_MEMORY_DB'].to_i, 1].max
  specs = (Dir["spec/**/*_spec.rb"]).sort.in_groups_of(N_PROCESSES)
  processes = []

  interrupt_handler = lambda do
    STDERR.puts "caught keyboard interrupt, exiting gracefully ..."
    processes.each { |process| Process.kill "KILL", process }
    exit 1
  end

  Signal.trap 'SIGINT', interrupt_handler
  1.upto(N_PROCESSES) do |j|
    processes << Process.fork {
      specs.each do |array|
        if array[j-1]
          require array[j-1]
        end
      end
    }
  end
  1.upto(N_PROCESSES) { Process.wait }

else
  (Dir["spec/**/*_spec.rb"]).each do |file|
    require file
  end
end

Then, you simply run IN_MEMORY_DB=2 spec spec/suite.rb to run two parallel processes. Increase the number on larger machines for better results!

There’s room for improvement here, notably in the naive method used to allocate the spec files to processes, but even as simple as this method is, our spec suite runs in about half the time it used to, on a dual-core machine.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (780)
  • rails (113)
  • testing (88)
  • ruby (83)
  • ruby on rails (70)
  • jobs (62)
  • javascript (55)
  • techtalk (44)
  • rspec (38)
  • ironblogger (32)
  • productivity (30)
  • activerecord (29)
  • gogaruco (29)
  • git (28)
  • nyc (27)
  • rubymine (26)
  • bloggerdome (23)
  • mobile (22)
  • process (21)
  • pivotal tracker (20)
  • cucumber (20)
  • jasmine (19)
  • design (18)
  • ios (18)
  • webos (17)
  • objective-c (17)
  • android (16)
  • palm (16)
  • "soft" ware (16)
  • fun (15)
  • tracker ecosystem (15)
  • ci (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • bdd (14)
  • gem (13)
  • css (13)
  • tdd (13)
  • selenium (12)
  • goruco (12)
  • bundler (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • api (10)
Subscribe to rspec Feed
  1. ←
  2. 1
  3. 2
  4. 3
  5. 4
  6. →
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >