Speaking About Testing and Socialism at Mountain.rb and RubyConf

After attending and organizing it is finally time for the next step, to speak at a conference, two actually, with three talks. Dive in head first. CJ will be speaking at Mountain.rb and RubyConf.

First: Mountain.rb in Boulder, Colorado, October 6-8
The Talk: The Front End Testing Frontier

While most Ruby developers are very familiar with testing their code, frontend and JavaScript-testing is still a new frontier for many. This talk will show you how to easily write and run JavaScript integration tests with Capybara and Cucumber, and unit tests with Evergreen and Jasmine. The goal is to get you excited about frontend testing, and point you in the right direction to get started yourself!

Second and Third: RubyConf in New Orleans, November 11-13
Talk #1: The Front End Testing Frontier, extended, with co-presenter Jonas Nicklas
Talk #2: Socialist Software Development

Socialism is often portrayed as pure evil by US media (hello Fox News), yet many socialist countries are ranked as some of the best countries in the world (Newsweek). So maybe it's not all bad? If you look at job listings for software developers, it seem like a lot of companies are looking for "programmer rock stars", "coding ninjas", etc. There is a romantic notion about the ultra productive independent super developer. This talk examines software development from a socialist perspective.

Might we get better results and provide more value if we set aside our egos and work together?

CJ Kihlbom is speaking at Mountain.rb


Inside Information

A new side of Elabs is about to be revealed. You will be granted access to our office, to our thoughts, to the very core of our work. The intention is to share our everyday life.

First we want to welcome our newest addition, the Stockholm crew: Peter Marklund, Ingemar Edsborn and Dennis Rogenius. Ingemar and Dennis have worked with us before and we are very happy to announce them as official Elabs employees! Peter and CJ have known each other for several years. You will soon get to know them better, and the old Gothenburg crew, through a series of personal interviews which will be posted here on the blog.

The Stockholm crew is currently in the Gothenburg office for a two week long Elabs bootcamp. We will share knowledge, get to know each other and have fun. Pair programming, talking and playing ping pong. Soon we will hopefully recruit a fourth crew member as well. Our Stockholm headquarter will be located in our customer Streamio's facilities on Sveavägen. We are very happy to be sharing space with them!

We would also like to thank our client Alessandro, from Tinet, who was here last week working with us. Thank you for great pastries, fun conversations and productive work. Now he is back in a sunny Sardinia, Italy. We are just a little bit envious.

We hope you will enjoy the coming inside information!


Announcing Elabs Stockholm

After two great years in Gothenburg, it's time to broaden our horizons a bit. I'm very happy to announce that we are opening an office in Stockholm, the capital of Sweden, in early October.

Most of our Swedish clients are located in Stockholm, so the primary reason for opening the new office is to get closer to them. We look forward to being able to provide even better service to our existing clients, and to exciting endeavors with new clients.

Another big reason for opening an office in Stockholm is because of all the great Ruby on Rails developers there. We've already added some great people to our initial Stockholm team, people we've worked with before, but we're looking to add at least one more. If you're interested, please have a look at our job listing. The listing is in Swedish, but we'll definitely consider applications from non-Swedish speakers too. We'll even help the right candidate move to Sweden if necessary.

Sergels Torg, one of Stockholm's distinctive landmarks

Photo by Simon Donini {: .caption}

Stay tuned for more info as we get closer to the premiere!


BizConf 2010

One of my highlights of last year was going to BizConf, so I was very happy to be able to go back to Amelia Island last week for the 2nd annual BizConf.

CJ Kihlbom, Randall Thomas and Marty Haught having lunch in the sunshine

Photo by Obie Fernandez {: .caption}

For me, the greatest part about attending a conference is hanging out with lots of great people. This is especially true about BizConf, which just as last year attracted a bunch of smart and interesting people who were eager to share their experiences. I learned just as much from them as from the presenters.

David Allen

David Allen shows how you feel when you're not "Getting Things Done". Photo by Obie Fernandez. {: .caption}

One of the many excellent presenters was David Allen (above), the creator and best-selling author of Getting Things Done (which all attendees got a copy of). David gave a really inspiring keynote and an engaging workshop about how and why you should do GTD.

Corey Haines

Corey Haines moderated the Software Craftsmanship panel. Photo by Obie Fernandez. {: .caption}

One of my favourite moments of the conference was the panel on Software Craftsmanship in Small Business. It was lead by Corey Haines, who was kind enough to invite me to be on it together with Gustin Prudner, Paul Pagel and Obie Fernandez. It was a real honour to be on the panel alongside such esteemed colleagues, and we had some great discussions.

Obie and Desi are in over their heads

Conference pool parties are awesome. Photo by Lan Bui. {: .caption}

Fitting to a conference in Florida, BizConf finished with a great pool party. Relaxed atmosphere, good food and drinks, great people and lots of fun. That pretty much sums up the whole conference. I'm already looking forward to next year!


You're Cuking It Wrong

Opinions on cucumber seem to be divided in the Ruby community. Here at Elabs we've been using cucumber to fantastic success on all of our projects for more than a year. At the same time Steak and projects like it seem to be gaining traction; some people are seemingly frustrated and fed up with cucumber.

So where does this gulf of experiences come from, why is cucumber loved by some and hated by others. At the risk of over-generalisation and mischaracterisation I recently came up with a theory: the cucumber detractors are not using cuke the way it was intended.

This is in fact not their fault. The entire cucumber ecosystem, and in fact even cucumber itself, encourage its misuse.

A while ago someone created an issue on the Capybara issue tracker. The interesting thing about this issue wasn't the problem itself, but rather the cucumber feature that the author presented in order to replicate the problem. This is the feature the author submitted:

Scenario: Adding a subpage
  Given I am logged in
  Given a microsite with a Home page
  When I click the Add Subpage button
  And I fill in "Gallery" for "Title" within "#document_form_container"
  And I press "Ok" within ".ui-dialog-buttonpane"
  Then I should see /Gallery/ within "#documents"

At first glance this seems reasonable. But contrast this with the following, improved version:

Scenario: Adding a subpage
  Given I am logged in
  Given a microsite with a home page
  When I press "Add subpage"
  And I fill in "Title" with "Gallery"
  And I press "Ok"
  Then I should see a document called "Gallery"

The difference isn't huge, the steps are largely the same, and there's an argument to be made for writing in a more declarative style, but there's one crucial difference: the first feature is code, the second isn't.

The argument against cucumber that's often presented is that as a programmer, plain text is unnecessary, because we can all read code. While it's true that we all can read code, I still find it beneficial to jump out of the code writing mode for describing the behaviour of the application. When you're writing features first, you don't want to be bothered with the details of how this functionality works. In this initial stage you care nothing about the implementation, about how the result is achieved. You care nothing about things like #document_form_container or .ui-dialog-buttonpane.

I believe that it's in this switching between designer mode and developer mode where cucumber, done right, really shines.

In order to evaluate the bigger picture before hacking
As a developer
I want to write my stories before writing my code

There are some secondary benefits as well. Writing truly plain text features leads to better maintainability as well, since the features are robust against code changes. Plain text is also easier to understand for new developers coming to an existing project. Probably the nicest advantage though is that over time a library of steps is built up, which can then be simply combined to describe new features.

The above feature is nicely illustrative of this anti-pattern, but it is far from the only example. In many of our cucumber suites here at Elabs, we have steps like the above, some of them were written by me. Which leads me to what's really wrong with the last three lines of the above feature. They are written using nothing else than the standard web steps generated by cucumber-rails own generator. Cucumber itself ships with steps which in my opinion encourage an anti-pattern.

Pickle my fancy

Another tool which we've experimented a bit with is Pickle, which allows you to easily generate models from your feature files. A basic example from the README:

Given a user exists
And a post exists with author: the user

Given a person: "fred" exists
And a person: "ethel" exists
And a fatherhood exists with parent: user "fred", child: user "ethel"

It actually looks fairly nice, reads quite naturally, so a first instinct might be to call this plain text. But on closer inspection, there is a whole language in there. To comprehend what these steps are doing you'd need to understand not only the domain models involved, but also the language Pickle uses to manipulate these. I'm pretty sure a non-technical person couldn't make sense of the above. This is really no different, and in fact worse, than writing actual code:

@user = User.make
Post.make(:user => @user)

@fred = Person.make(:name => 'Fred')
@ethel = Person.make(:name => 'Ethel')
Fatherhood.make(:user => @fred, :child => @ethel)

Note how there is an almost one-to-one mapping between the feature above, and the code below. The only thing cucumber does in this case is act as some kind of phoney translator. We write code, but not actual code. So we can do some stuff, but mostly it comes out worse than if we'd just written it as code in the first place. I can't blame anyone for disliking cucumber when using it like this.

However, try this instead:

Given there is a user called "Jimmy"
And there is a post authored by "Jimmy"

Given there is a person called "Fred"
And there is a person called "Ethel"
And "Fred" is the father of "Ethel"

There's not a huge difference between the first couple of lines, even though they read somewhat nicer when written out like this. The real difference is in the last line. Here cucumber is adding value by explaining this abstract concept of a Fatherhood into something very concrete: one person is the other's dad. Cucumber added value to this feature, instead of only acting as a hindrance.

I believe that Pickle is flawed as a concept, in order to achieve readable steps, they need to be written by hand.

The worst feature ever written.

As a curiosity, I present the worst cucumber feature known to man. If you are responsible for something like this, please go slap yourself in the face as hard as you can.

Scenario: User creates some sites and circuits, check connected sites list
    Given a "site" exists with {"name"=>"Somewhere1", "identifier" => "TER1", "provider"=>"TER1 Provider"}
    And a "site" exists with {"name"=>"Somewhere2", "identifier" => "TER2", "provider"=>"Some Provider"}
    And a "site" exists with {"name"=>"Somewhere3", "identifier" => "TER3", "provider"=>"TER3 Provider"}
    And a "circuit" exists with {"provider_name"=>"Another provider", "redacted_circuit_id"=>"ABC1", "provider_circuit_id"=>"C1", "circuit_type"=>CircuitType.find_by_name("Peering"), "service_type"=>CircuitServiceType.find_by_name("Dark Fiber"), :capacity => CircuitCapacity.find_by_name("1 Gbps"), "physical_wire_type"=>PhysicalWireType.find_by_name("Multi Mode Fiber"), "status"=> CircuitStatus.find_by_name("Cancelled"), "a_end"=>Site.find_by_identifier("TER1"), "b_end"=>Site.find_by_identifier("TER2")}
    And a "circuit" exists with {"provider_name"=>"Switch and Data", "redacted_circuit_id"=>"ABC2", "provider_circuit_id"=>"C2", "circuit_type"=>CircuitType.find_by_name("Backbone"), "service_type"=>CircuitServiceType.find_by_name("Dark Fiber"), :capacity => CircuitCapacity.find_by_name("1 Gbps"), "physical_wire_type"=>PhysicalWireType.find_by_name("Multi Mode Fiber"), "status"=> CircuitStatus.find_by_name("Cancelled"), "a_end"=>Site.find_by_identifier("TER1"), "b_end"=>Site.find_by_identifier("TER3")}
    When I am on the "connected_sites" page for site "TER1"
    Then the "connected-sites-list" should look like
      |   Site ID    |  Site Name | Site Provider | Provider Circuit ID  | Provider Name    | Circuit Status |
      |     TER2     | Somewhere2 | Some Provider |         C1           | Another provider |  Cancelled     |
      |     TER3     | Somewhere3 | TER3 Provider |         C2           | Switch and Data  |  Cancelled     |
    When I am on the "connected_sites" page for site "TER2"
    Then the "connected-sites-list" should look like
      |   Site ID    |  Site Name | Site Provider | Provider Circuit ID  | Provider Name    | Circuit Status |
      |     TER1     | Somewhere1 | TER1 Provider |         C1           | Another provider |  Cancelled     |
    When I am on the "connected_sites" page for site "TER3"
    Then the "connected-sites-list" should look like
      |   Site ID    |  Site Name | Site Provider | Provider Circuit ID  | Provider Name    | Circuit Status |
      |     TER1     | Somewhere1 | TER1 Provider |         C2           | Switch and Data  |  Cancelled     |

Yes, those are Hashes inside a feature, which are then eval'd. Make sure to scroll to the right to experience the full horror of it all. I challenge anyone to find a worse cucumber feature than this. I assure you, that thing is real (from one of our rescue mission projects), and there is much more where it came from.

Writing better steps

So how do we write better steps? For me personally, I've found that sticking to the following rule seems to lead to nice, maintainable steps:

A step description should never contain regexen, CSS or XPath selectors, any kind of code or data structure. It should be easily understood just by reading the description.