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
  • Tools
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Getting “by” with rspec feature specs

Stephan Hagemann
Monday, June 10, 2013

If you find that you are making your rspec feature specs longer and longer to cram more coverage in or to prevent the setup costs for more, shorter tests, you will probably have found that it becomes very hard to figure out what’s going on. If you find yourself wanting to add comments to your specs to state what is happening, like so:

it "allows the user to manage her account" do
  #Login user
  visit "/login"
  fill_in "Username", :with => "jdoe"
  fill_in "Password", :with => "secret"
  click_button "Log in"

  expect(page).to have_selector(".username", :text => "jdoe")

  #Account management
  click_link "Account"
  expect(page).to have_content("User Profile")
  ...
end

Why not throw this code into your spec_helper.rb…

def by(message)
  if block_given?
    yield
  else
    pending message
  end
end

alias and_by by

… and replace the above section with this:

it "allows the user to manage her account" do
  by "logging in the user" do
    visit "/login"
    fill_in "Username", :with => "jdoe"
    fill_in "Password", :with => "secret"
    click_button "Log in"

    expect(page).to have_selector(".username", :text => "jdoe")
  end

  and_by "managing the account" do
    click_link "Account"
    expect(page).to have_content("User Profile")
  end
  ...
end

Instead of having comments, which I personally am trained to a) ignore and b) expect to be outdated, I now have a block which denotes that a part of the spec as doing something specific. I like to think that the benefit of the block over the comment is that

  • it has a start and an end (and thus adds programmatic structure),
  • it adds indentation (and thus visual structure),
  • it can have behavior (like the use of rspec’s pending).
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Rails autoloading for your gem [Rails application suites series]

Stephan Hagemann
Wednesday, May 29, 2013

We have been developing gems a lot as part of giving more structure to Rails applications: the idea and some techniques. Doing this often sees a Rails application and one or more gems being developed at the same time. This unfortunately breaks Rails autoloading. This article will show you how to get it back…

Continue reading →

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Showing and hiding conditional HTML without Javascript

Stephan Hagemann
Tuesday, May 21, 2013

Have you ever filled out an address form that had a checkbox for “my shipping address differs from my mailing address”? When you click that box a conditional form part gets revealed that allows you to enter another address. We had to build something very similar the other day and stumbled on a neat way to make the conditional part show and hide with CSS only.
Continue reading →

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

My must-see list from MWRC 2013

Stephan Hagemann
Saturday, May 4, 2013

TL;DR

If you watch one talk from Mountain West Ruby 2013, watch Greg Baugues: Devs and Depression.

Talks @ Mountain West Ruby Conference

Mountain West Ruby, was a great conference: lots of content and awesome people. It had one DevOps day and two Ruby days. Its presentations have recently been posted on confreaks.

There were a total of four talks by Pivots, including one by myself (in order of appearance):

  • Andy Pliszka: Extending CRuby with native Graph data type.
  • Matt Kocher: Ruby off the Rails: Building a distributed system in Ruby.
  • Stephan Hagemann: Component-based Architectures in Ruby and Rails.
  • Sarah Mei: Work, Play & Code.

What follows is the list of talks that I recommend watching.

There is one talk that I want to highlight within my list of highlights: “Devs and Depression”. It is the last one in this list and as you can guess it is not about technology. It’s different, bold, and in my opinion very important. Watch it!

Alright, here we go…

DevOps Day

Gene Kim: Why we need devops? - 30000 feet view of why devops is valuable and how to do it. It’s a 3 trillion market.

Will Farrington: Boxen: How to manage an army of laptops – Some impressive stuff github is doing for machine management.

Lindsay Holmwood: Escalating complexity: DevOps learnings from Air France 447 - Chilling: Case study of an airplane crash. Systems within complex systems. Local vs global rationality.

If you want more:

James Turnbull: Hell has frozen over: DevOps & Security – How security people should change their work and how they talk about it.

Drew Blas: Migrating a live site across the country without downtime – Actionable story on how to move data centers.

Jesse Newland: ChatOps at Github – Using hubot (in campfire chat) to manage puppet (and everything). Documenting, interacting, interfacing among remote teams.

Ruby Day 1

Yukihiro Matsumoto: Ruby 2.0 – History of Ruby and features of Ruby 2.0. Maybe don’t watch if you already know about the new features. Maybe watch it, because its Matz.

Michael Fairley: Immutable Ruby – How immutability can benefit your code.

Daniel Huckstep: Ruby Batteries Included – Don’t require gems: Use the Ruby Standard Library.

Ryan Davis: Trolls of 2013 – Not abut trolls, but implementing an interpreter in Ruby. Talk got cancelled on the first day, due to a fire alarm. Way to deal with it Ryan!

If you want more:

John Pignata: Code Smells: Your Refactoring Cheat Codes – Run through a long list of code smells and refactorings.

Ruby Day 2

Brandon Keepers: Ruby at Github – Musings on Ruby: when to use, why to use. And problems (over time) in a big setup.

Craig Kerstins: Postgres Demystified – Lots of stuff you did not know about Postgres.

Greg Baugues: Devs and Depression – Personal story of mental illness. Talks about depression and why we should be more attentive to our fellow developers.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

GoSpotCheck Is Looking For A Web Application Developer

Stephan Hagemann
Wednesday, February 20, 2013

At Pivotal Labs, one of the services we provide our clients is helping them interview and hire. Pivotal Labs and our clients place a strong emphasis on Agile development and its many aspects: Pair Programming, Test-Driven Development, rapid iterations, and frequent refactoring.

LEAD DEVELOPER
GoSpotCheck is seeking a Ruby developer to join our growing team and take an integral role in building our product. GoSpotCheck is a simple way to collect, structure, and share retail intelligence for distributed field teams. We have mobile applications for capturing data and a web application for digesting and analyzing field intelligence. Our applications streamline the process of getting from data to insights to action for enterprise retail customers, enabling them to more effectively manage retail execution.

JOB REQUIREMENTS

  • Proven experience in development of flexible and scalable web-based applications
  • Passion for technology, specifically software development
  • 2+ years of experience with Ruby language and the Rails framework, be proficient with the entire Ruby on Rails stack
  • 3+ years of hands-on web development, demonstrating:
  • Proficiency with HTML/XHTML, CSS, JavaScript and JQuery
  • Sound object oriented design skills and knowledge of application architecture patterns
  • Proficiency with relational databases, including design and development
  • Working knowledge in development of MVC-based web solutions
  • Competency managing source control and automated build processes
  • Excellent analytical and problem solving skills
  • Strong communication and interpersonal skills
  • Android and iOS a big plus

ABOUT OUR COMPANY
GoSpotCheck was founded in May 2011 and is a graduate of the renowned TechStars program. We are backed by some of the best early stage tech investors including 500Startups, Venture51, Doug Feirstein, Walter Winshall, Dave Carlson, and former Coca-Cola CMO Sergio Zyman.

BENEFITS & COMPENSATION
Along with a competitive salary and 100% paid benefits, we offer a highly dynamic and exciting work environment where you will get the chance to make huge contributions to the company. We believe in giving everyone the ability to excel at their job, and that means giving our people the ability to create impact in any way they see fit.

Contact careers@gospotcheck.com and we’ll get back to you ASAP!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Migrating from a single Rails app to a suite of Rails engines [Rails application suites series]

Stephan Hagemann
Tuesday, March 13, 2012

TL;DR

We moved a Rails app into an unbuilt engine of a new blank slate container app to allow new parts of our app to live next to it as engines as well. It has been working great for us!

I have a sample app rails_container_and_engines of the result’s structure on github.

Skip to the pitfalls and discoveries section to read about some of the speed bumps we during our transition. Interested in the why and how? Read on!

Rationale

As part of the project we had built a web app, a mobile app that talks to the web app’s API, two ETL tools to 1) do the initial data import from the app we were replacing and 2) get data into another of our client’s apps. At this point we knew that we would create one more big web app and several auxiliary apps.

Running up to the decision to using unbuilt engines we had several intense discussions on how to build loosely-coupled, highly-cohesive systems with Rails applications. We saw basically three choices:

  • All-in-one app that could get more structure through namespacing of its interals.
  • Services (REST or whatever, but) running as separate apps and communicating via APIs.
  • Engines running within a mostly feature-less container app.

The two big web apps share several models within the data access layer and use the same data. Because of this we chose the third option and left all of the apps within the same rails code base.

Internal discussions highlighted the costs/benefits of having all of these apps live within their own Rails project versus an engines approach. We feel that by using engines we are getting many of the benefits of a component based architecture without breaking Rails patterns. In addition, we feel that the cost of maintaining individual applications that share a central database or one giant application with less defined components would have been very high.

In order to make day to day development easier, and to avoid the “where do migrations live…” conversation and top level Rails deployment patterns, there is one twist to the architecture: everything resides in one git repo and engines are referenced from a single container application (similar to old school enterprise archive files). Each application is exposed via a unique context or resource identifier (each engine/app could also be isolated per instance via Apache). Here is the directory structure we ended up with:

container_rails_app/
  ...
  app
  config
  engines/
    etl/
    shared_modules/
    web_app_1/
    web_app_2/
  ...

Mike described this pattern in his recent blog posts Unbuilt Rails Dependencies: How to design for loosely-coupled, highly-cohesive components within a Rails application and Rails Contained: A Container for Web Application Development and Deployment. On how to make RubyMine work seamlessly with engines, read my post on IntelliJ Modules in Rubymine.

The steps we took

  • Generate a new, empty Rails app
  • Within the engines folder, create a new, mountable Rails engine
  • Copy all the tests from the original Rails app into the test directory and make them green.

    Ok. This step is a bit more involved. Essentially that’s it thought. Find some of the pitfalls we ran into described below. Here are a couple of highlights of what needs to happen:

    • Copy the files you need for a test to pass and namespace its class
    • Start with the model tests and work your way up towards integration and acceptance tests
    • Namespace everything with the name of the engine (either by fully qualifying every name – don’t do that) or with the lexical scope trick explained below. This includes tests and all classes.
    • Load needed gems explicitly: engines don’t load as much automatically as a Rails app
    • Namespace tables and assets
  • Copy the old .git directory into the new root folder in order to not loose any history. For us, git was not able to detect the changes as moves in many cases. This is certainly an area where you can improve on our solution!

For us, the real work started after this, when we started pullling out common code into a common models engine and began work on the second app.

We got all the tests to pass before we had namespaced any of the assets or rake tasks. That was an additional search-and-replace heavy step after the actual transition to an engine. It is not necessary right away if you do not have multiple applications at first, but to achieve the full effect, you will need to namespace the things as well.

Pitfalls and discoveries

Namespaces

Modules in your enige are not automatically loaded: make sure you reference them yourself before they are needed in other files.

Asset pre-compilation

Rails creates a default app/assets/stylesheets/application.css file which contains these lines:

/* ...
*= require_self
*= require_tree .
*/

If you have this file in your main app, all css files will be compiled into one file. For us, this made almost everything look right. Almost. Little things broke here and there. Our app contained a couple of sections for which the stylesheets were meant to be loaded separately. Add files that you want to have precompiled as individual files to config.assets.precompile list to have them precompiled into separate files and solve this problem.

Are all your references and associations breaking?

Try this

module M
  class X
    def use_y
      Y.do_it!
    end
  end
  class Y
    def self.do_it!
    end
  end
end

instead of

class M::X
  def use_y
    M::Y.do_it!
  end
end
class M::Y
  def self.do_it!
  end
end

The first way sets the lexical scope to the module M as well as to the class Y and allows you to reference other classes in M without their full name. The second way sets the scope only to class M::Y and you have to fully qualify every class name to find it.

Don’t fight conventions

We were using fixture builder and while we were namespacing classes in modules we were trying to override the default table names to not be namespaced… Fixture builder didn’t like that at all. There may or may not be other dependencies that make leaving the conventions hard. So, save yourself the trouble and do the migrations (and stay consistent!) and namespace your tables as well!

HABTM

They seem to be falling out of favor, which is probably a good thing. With engines they don’t seem to work (well). We ended up getting rid of our last two habtm relationships instead of trying to make them work. Creating the join as a class and adding the necessary has many :through relationships is straight forward enough.

We ended up with one production performance bug due to this: Rails

Engines depending on engines

We used kaminari for our pagination requirements. When our app first became an engine, kaminari stopped picking up our custom views. Instead it used its standard views. The load order got screwed up to which there are basically two solutions:

  • require => nil on both engines in the Gemfile and force the correct load order in your app, or…
  • avoid name clashes by namespacing your views (which you were going to do anyways, right?)
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Never use shared examples groups! Usually.

Stephan Hagemann
Friday, March 9, 2012

Shared example groups are a feature of rspec that allow specifying common behavior in a reusable group of specs.

I believe that there is a very specific way in which one can benefit from shared examples groups (and should keep them) and many more in which they come in handy at some point and should be refactored away from as development continues.

When shared examples may seem a good idea

If an application employs mechanisms such as mixins, delegation, or inheritance (which every Rails app by default does…), one can probably find some common behavior. Take a soft-delete functionality for example: specifying for each class that it’s objects are soft-deletable and that it_behaves_like :soft_deletable seems nice, but comes at a cost (and isn’t appropriate).

Shared examples make for a slow test suite

If there are n test cases and m specs in the shared examples, there is a total of n*m specs that will run. Obviously the shared example saves a lot of spec coding: m shared specs, and n references to it. Meaning you need to write only n+m specs.

If, however, it were possible to test the common functionality separately (m specs) and then test only its integration (n specs), there would still be n+m specs to write, but more importantly, there would also be only n+m specs to execute.

n*m vs. n+m, that’s a huge difference.

How to test common code without shared example groups

There are a couple of ways to test common code without resorting to shared examples.

In your spec, write a test harness class that gets your mixin, delegate, or (abstract) super class. This class only has the abilities of a non-special object and the common code. Testing this class allows testing the common code in an isolated way.

If you happen to be relying on ActiveRecord for your mixin as soft-deletable probably would be, use Temping to create an ActiveRecord object that only has ActiveRecord::Base behavior and that of the common code.

In case you have shared example groups in place, but can’t apply either of the above options, you probably haven’t extracted the code enough yet. Do that first and then come back here and refactor away from the shared example group.

Is a shared example group ever the right thing to do?

Imagine a mixin that has complex interactions with the objects it gets mixed in to, like a it_behaves_like :fuzzy_matchable. Fuzzy matching will always work in a similar way, but be working on different attributes or methods depending on the object. In this case the interactions between the object and the mixin are important to specify and verify. David Chelimsky describes this situation in his post about specifying Mixins with shared example groups. This kind of complex interaction seems to me to be the only case in which shared example groups are truly beneficial.

Am I missing good use cases of shared example groups here? Where do you use them?

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Specific interfaces – in the small

Stephan Hagemann
Wednesday, March 7, 2012

Everyone on the Web I found who states that quote I was looking for says “I don’t know who said it, but be ‘Generous on input, strict on output’” (or some variation on this). While I am unsure about the first proposition, I wholeheartedly agree with the second.

Edit 3/8: the quote is known in a different wording as Postel’s Law, which shows up as the Robustness Principle in RFC 793, the specification of TCP. Thanks for the hint, Austin!

Unfortunately, the closest a Rubyist typically gets to the implementation of an interface specification is his tests. This provides a pretty good, but somewhat disconnected specification that can sometimes cover up imprecisions in the interface’s implementation.

On top of that, sometimes our frameworks make it easy to forget what our tests are asserting or spec’ing.

Take rspec’s predicate matchers and this example:

require 'rspec/core'

class VeryImportantQuestions
  def self.really?(answer)
    answer == 'Yes. I am telling you.'
  end

  def self.really_really?(answer)
    answer == 'Yes. I am telling you.' ? 42 : nil
  end
end

describe "really?" do
  context "using rspec predicate matchers" do
    context "if someone is telling you" do
      it "should be really really the case and return true" do
        VeryImportantQuestions.really?('Yes. I am telling you.').should be_true
      end
    end
    context "if someone is not sure" do
      it "should return false" do
        VeryImportantQuestions.really?('I am not sure.').should be_false
      end
    end
  end
end

describe "really_really?" do
  context "using rspec predicate matchers" do
    context "if someone is telling you" do
      it "should be really really the case and return true" do
        VeryImportantQuestions.really_really?('Yes. I am telling you.').should be_true
      end
    end
    context "if someone is not sure" do
      it "should return false" do
        VeryImportantQuestions.really_really?('I am not sure.').should be_false
      end
    end
  end
end

be_true and be_false effectively hide the fact that what’s actually spec’ed is truthiness and falsiness. Only when the following context is added is this imprecision revealed:

  context "spec'ing the actual output of the method fails" do
    context "if someone is telling you" do
      it "should be really really the case and return true" do
        VeryImportantQuestions.really_really?('Yes. I am telling you.').should == true
      end
    end
    context "if someone is not sure" do
      it "should return false" do
        VeryImportantQuestions.really_really?('I am not sure.').should == false
      end
    end
  end

With regard to rspec, I suggest to consider twice whether the benefits of using specific matchers to not outweigh their benefits in your situation. You might get nicer test output, but you might lose the ability to immediately tell what you’re spec’ing.

With regard to tests in general: be specific about what you output – aka be specific about what you test.

Here is the gist: https://gist.github.com/1998462

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Boulder Standup – Feb 16, 2012

Stephan Hagemann
Thursday, February 16, 2012

rspec should render_template still behaving weirdly

Specing a partial being rendered with render_template blows up. What to do?

render_template has been brittle for a long time. It obviously still is:

response.should render_template("template") #works fine
response.should render_template(partial: "template") #works fine
response.should render_template(partial: "template", locals: {local_array: []}) #blows up within rspec

You know how to fix it? Solve it here

RubyMine 4 is out

RubyMine “compare two files” isn’t broken

It is just really, really weird: if you have to scroll when comparing two files check the file that is above in the project drawer first. If you scroll up to do select the second file to compare, the compare window won’t open.

Stubbing can? can be hard

In a system with a lot of cancan abilities – what is the best way to stub a particular ability for controller specs? In the hierarchy of controllers, a lot of abilities may be checked, all of which would need to stubbed in order to get to the code under test.

Instead of stubbing the abilities, create a new, anonymous, ability class specific for your spec that gets all the necessary abilities and then stub current_ability to return an instance of that class. Internally cancan calls current_ability when you call can?: cancan controller additions

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

IntelliJ Modules in Rubymine

Stephan Hagemann
Tuesday, February 7, 2012

IntelliJ has a feature called modules: “a functional unit which you can compile, run, test and debug independently.”

Modules in IntelliJ: Multiple top-level folders

A module in IntelliJ is a top-level view on a part of a codebase. IntelliJ is for Java, which is why I do not typically use it. I use Rubymine – no similar functionality exists here… but a way around that!

It may have been true at some point that these kind of modules were not something that Rails offered, but they have been around for quite a while: Engines!

Engines are typically seen as a way to package a Rails app that can be reused and configured in the context of other Rails apps. However, many big Rails projects can benefit from engines and their ability to structure a large codebase into smaller, more independent parts. Namespacing within one Rails app can achieve a similar effect, but engines take it to the next level: all the code, including views, javascript, and even rake tasks and migrations can be separated consistently. Now, if the apps were totally separate, several independent Rails apps might be the right solution, but if those are tied together by the same database, one might do more harm then good when ripping that code apart…

The Problem

Imagine a Rails project with the following folder structure:

rails_app/
  app/
  ...
  engines/
    custom_engine1/
    custom_engine2/
  ...

The engines are somewhat hidden away, two levels deep in the folder structure. Also, running specs for engines in these sub-folders won’t work from Rubymine, because the paths it tries to use are wrong.

Whether you are actually working with engines or just want to see multiple root folders in Rubymine at once, here is how to do it.

Make modules work in Rubymine

1) You can get modules to work in Rubymine by opening your Rails project in IntelliJ: Cmd + ; opens the project structure dialog, select Modules from the list on the left and create a new module with the + button. Or, you can simply add a few files to your project…

2) The .idea folder in the root of your project holds the Rubymine configuration files. Edit modules.xml and add a module line for every module you would like to create:

<!-- ROOT/.idea/modules.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/custom_engine1/module1.iml" filepath="$PROJECT_DIR$/custom_engine1/custom_engine1.iml" />
      <module fileurl="file://$PROJECT_DIR$/custom_engine2/module2.iml" filepath="$PROJECT_DIR$/custom_engine2/custom_engine2.iml" />
    </modules>
  </component>
</project>

In the root folder of every module create a .iml file with the name of that module like so:

<!-- ROOT/engines/custom_engine1/custom_engine1.iml -->
<?xml version="1.0" encoding="UTF-8"?>
<module type="RUBY_MODULE" version="4">
  <component name="NewModuleRootManager">
    <content url="file://$MODULE_DIR$" />
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
  </component>
</module>

Voila: The next time you open the project folder in Rubymine, the custom_engine folders show up as top-level entries in the projects file list!

Modules in Rubymine!

Here is the gist: https://gist.github.com/1764127

This worked for me with Rubymine 3.2.4 and IntelliJ IDEA 11 CE.

Edit March 14: make sure that all module names are distinct and no module names are substrings of other module names. This confuses RubyMine and can prevent specs from running successfully.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Stephan Hagemann

Stephan Hagemann
Boulder

Subscribe to Stephan's Feed

Author Topics

bdd (1)
feature specs (1)
journey specs (1)
rspec (5)
testing (5)
engines (3)
gems (1)
rails (3)
rails application suites (3)
css (1)
html (1)
javascript (1)
conferences (1)
boulder (1)
jobs (1)
refactoring (1)
ruby (3)
cancan (1)
rubymine (2)
rake (1)
basics (1)
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Tools
  • 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 >