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

Monthly Archives: February 2010

Pivotal Labs

Standup 2/8/2010: Potential Geminstaller issues

Pivotal Labs
Monday, February 8, 2010

Interesting Things

A project reported that GemInstaller failed when installing Rails 2.2.2, because it attempted to list the remote Rails 3.0.beta gem. There’s a bug open and awaiting more info, but since this is not reproducible on RubyGems 1.3.5, it may be due to an old RubyGems version not handling prerelease gems properly.

The GemInstaller author heartily recommends that you switch to Bundler anyway

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Sean Beckett

New Tech Talk: Contextually Remarkable: RSpec Testing Tools

Sean Beckett
Friday, February 5, 2010

Pivot David Stevenson introduces Remarkable and Contextually, testing tools that can be used on top of RSpec. Remarkable is tool that makes testing common ActiveRecord and ActionController functionality more declarative, making tests shorter and more legible. Remarkable is used heavily in Contextually, a role-based testing framework that simplifies testing the behavior of controllers against a variety of roles. David shares his experience and metrics from using these tools on a recent project.

See all our talks at http://pivotallabs.com/talks

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Sean Beckett

New Tech Talk: Demystifying Online Billing

Sean Beckett
Friday, February 5, 2010

Isaac Hall of Recurly describes many of the hidden challenges in managing recurring billing online. He offers step-by-step tips, tricks, and firsthand experience on how to better architect and more easily deploy billing in your application.

Isaac put up a synopsis of the main ideas on the Recurly site.

See all our talks at http://pivotallabs.com/talks

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Justin Richard

Standup 2/5/2010: Jasmine has shared examples

Justin Richard
Friday, February 5, 2010

Interesting##

If you’re using Jasmine to test your JavaScript code and you miss the shared examples functionality you used in RSpec, you can achieve the same result by just using a plain old function. Name your function something like “mySharedBehavior” and call it in each of your describe blocks that share the behavior. Jasmine will execute the function and print your results just as if you repeated all the shared examples in each of your describe blocks. Be careful not to modify the scope of the function that contains your shared examples (Jasmine needs to control the scope).

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
JB Steadman

javascriptTests.bind(reality)

JB Steadman
Friday, February 5, 2010

Javascript tests are good, but manually-maintained HTML fixtures are painful. It’s time consuming to keep fixture markup in sync with the actual markup produced by your app. Despite best efforts, deviations arise, leading to bugs and false positives in tests.

For the past few months on Mavenlink, we’ve been pre-generating real-life fixture markup and making it available in our javascript tests. Results have been positive.

The basic approach is simple:

1) Pre-generate real-life markup using any convenient mechanism.

2) When javascript tests run, load the pre-baked markup into the DOM for access by JS code.

For #1, we use a small set of RSpec controller specs that exist solely to generate fixtures. For #2, we retrieve fixture markup from our Jasmine server via ajax, and inject it into the DOM with jQuery. While our approach leans on the various bits of our stack, any part of it could be swapped out to adapt to different tools.

Big thanks to Jonathan Barnes for the code that got us started.

Generating the fixtures

Taking a closer look, here’s an RSpec test that generates an HTML fixture file named ‘workspace-page’:

describe WorkspacesController do
  it "generates a workspace page" do
    @workspace = create_workspace
    log_in @workspace.creator
    get :show, :id => @workspace.to_param
    response.should be_success
    save_fixture(html_for('body'), 'workspace-page')
  end
end

We create a workspace, hit the WorkspaceController‘s show method, and save the full text of the response’s <body> element to a file. This spec lives in a file with others like it, separate from the real controller specs. We have about a dozen of these specs, all in the same file.

We added save_fixture() and html_for() to ControllerExampleGroup to help with fixture generation. This gist has implementation details.

Our javascript tests sometimes require that we load different versions of the same page. We generate a different fixture for each version, giving them meaningful names like ‘busy-workspace-page’ and ‘empty-workspace-page’.

When we change markup consumed by our javascript tests, we re-run the controller specs that generate fixtures. Changes are picked up the next time we run our javascript tests. Fixture generation is hooked into continuous integration, so our javascript tests see the latest markup when running in CI.

Loading fixtures into the javascript test DOM

On the javascript side, fixture loading is handled by the code in this gist. Of note:

  • We use two methods for making fixture content available to our tests. loadFixture() inserts the fixture markup into the DOM for use by code that accesses the DOM. readFixture() returns fixture content as text; we use it to test our ajax callback methods.

  • Within the same test run, we cache fixture text in javascript to avoid multiple requests to the server for the same markup. Across test runs, we ensure our markup is fresh by appending a cache busting timestamp to our request path.

Ready to test!

Here’s how we typically use loadFixture() within our Jasmine tests:

describe('the status module', function() {
  it('switches tabs', function() {
    spec.loadFixture('workspace-page');
    var $tabContainer = $('#jasmine_content').find('.tab-container');
    expect($tabContainer).toHaveSelectedTab('team');
    $tabContainer.find('li[tab=schedule]').click();
    expect($tabContainer).toHaveSelectedTab('schedule');
  });
});

loadFixture() inserts markup into the #jasmine_content div. Then we examine the DOM, do stuff to it, and inspect it again. toHaveSelectedTab() is a custom Jasmine matcher. Jasmine matchers are super easy to write. We love them.

You may be wondering how we’ve established our event bindings. jQuery’s html() method, used within loadFixture(), executes any scripts in the markup passed to it. If you’ve bound events in your fixture markup, within a $(document).ready() or not, they will execute when you call loadFixture(). This is really nice, because it means the same mechanism used for binding events in real life is also used within tests, keeping our tests that much closer to reality.

If, on the other hand, you bind events not within fixture markup, but instead within a script loaded once per suite globally, you’ll have to invoke your event binding code explicitly before each test.

Speaking of event bindings, you’ll need to clean them up properly between tests. For example, jQuery live events are bound to document. We clear them in a global beforeEach():

beforeEach(function() {
  $('#jasmine_content').empty();
  spec.clearLiveEventBindings();
  jasmine.Clock.useMock();
});

spec.clearLiveEventBindings = function() {
  var events = jQuery.data(document, "events");
  for (prop in events) {
    delete events[prop];
  }
};

Any events bound on elements within #jasmine_content are cleared out by jQuery when we call $('#jasmine_content').empty(), which also wipes the DOM clean between our test runs.

Results

Managing html fixtures like this has been a big win. In a recent team retrospective, consensus was “I can’t imagine doing it any other way.”

Building fixtures for tests is often simple as writing a 5-line controller spec. Maintaining fixtures just means re-running the specs, or perhaps enhancing the specs with additional data. We don’t see any production bugs from fixture markup vs. real markup discrepancies, and we spend very little time dealing with the fixtures.

We sometimes forget to re-generate fixtures after we change our markup, but, by now, realizing our mistake is a reflex action.

Test speed was one of our concerns going into this. Loading the fixtures takes time, of course. In practice, the runtime hit is dwarfed by the time saved by automating fixtures.

We have 224 javascript tests, and 200 of them load an html fixture. Our suite runs in 38 seconds in Chrome on a 2.4 GHz Core 2 iMac. (Other browsers are considerably slower). Of that 38 seconds, 9 seconds are spent loading fixtures and re-binding events.

We end up running our tests on fairly large DOM. We could probably save some running time by more narrowly focusing the markup that we generate and load. However, we haven’t felt it worth the additional development overhead. Additionally, running tests on our full DOM has an advantage – it exposes event handlers that conflict with each other.

Other gotchas

Nested describes are another great feature of Jasmine. It can be difficult, though, to keep track of where you’ve called loadFixture() within your hierarchy of describes. We sometimes found that we were calling loadFixure() twice in the same spec. To prevent that, we now keep track of how many times loadFixture() is called within a single test, and fail the test if the count exceeds 1.

At one point, we noticed that our javascript suite was consuming hundreds of megabytes of memory as it executed. We traced the problem to two jQuery plugins. Each time we loaded a fixture, the plugins claimed memory that never got freed. Now we mock out the plugins where we’re not explicitly testing them.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Demystifying Online Billing

Thursday, February 4, 2010 | Run time: 59:01

Isaac Hall of Recurly.com describes many of the hidden challenges in managing recurring billing online. He offers step-by-step tips, tricks, and firsthand experience on how to better architect and more easily deploy billing in your application.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

webOS Dev Camp

Thursday, February 4, 2010 | Run time: 2:12:30

Pivot Davis W. Frank presents Pivotal’s experience writing apps for Palm’s webOS. Including a live test-driven coding exercise, Davis covers agile development practices, our testing framework Pockets, and good development patterns.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Contextually Remarkable: RSpec Testing Tools

Thursday, February 4, 2010 | Run time: 44:51

Pivot David Stevenson introduces RSpec tools Remarkable and Contextually. Remarkable makes testing ActiveRecord and ActionController more declarative. Contextually simplifies testing the behavior of controllers against a variety of roles.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Justin Richard

Standup 2/4/2010: What remote screen sharing VNC clients are you using

Justin Richard
Thursday, February 4, 2010

Help

What remote screen sharing or VNC clients are people using for remote pairing?

Chad described his optimal remote pairing setup in 2008, but since then Apple removed the ability to do true full-screen sharing in the included Screen Sharing application with the 10.5.8 update. We’ve been looking for other solutions since. Apple’s Remote Desktop does this, but it gets expensive on a per seat basis and isn’t focused on solving our simple use case.

We’re interested in finding out what you’re using? Do you have a favorite VNC client?

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Justin Richard

Standup 2/3/2010: Refraction 0.2.0; Pulse is now open source; has_many association #destroy behavior

Justin Richard
Wednesday, February 3, 2010

Interesting

  • Pivotal’s Pulse is now open source. It’s a nice big view of the state of your multiple CI builds. Check out our public projects here: ci.pivotallabs.com

  • Refraction was updated to v0.2.0. It’s a testable replacement for mod_rewrite that’s implemented as Rack middle ware.

  • Calling #destroy on an ActiveRecord instance associated through a has_many relationship removes it from the database, but not the collection. #delete removes it from the collection and database, but you don’t get the before and after callbacks.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (778)
  • rails (113)
  • testing (87)
  • ruby (83)
  • ruby on rails (70)
  • jobs (62)
  • javascript (54)
  • techtalk (44)
  • rspec (38)
  • activerecord (29)
  • productivity (29)
  • gogaruco (29)
  • ironblogger (29)
  • git (28)
  • nyc (27)
  • rubymine (25)
  • bloggerdome (22)
  • mobile (22)
  • cucumber (20)
  • process (19)
  • pivotal tracker (19)
  • 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)
  • tdd (13)
  • selenium (12)
  • css (12)
  • goruco (12)
  • bundler (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • api (10)
Subscribe to Community 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 >