<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[John Wilger]]></title>
  <link href="http://johnwilger.com/atom.xml" rel="self"/>
  <link href="http://johnwilger.com/"/>
  <updated>2012-05-15T11:03:35-07:00</updated>
  <id>http://johnwilger.com/</id>
  <author>
    <name><![CDATA[John Wilger]]></name>
    <email><![CDATA[johnwilger@gmail.com]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Kookaburra 0.24.0 Released; Exorcised ActiveSupport]]></title>
    <link href="http://johnwilger.com/blog/2012/05/15/kookaburra-0-dot-24-dot-0-released-exorcised-activesupport/"/>
    <updated>2012-05-15T10:39:00-07:00</updated>
    <id>http://johnwilger.com/blog/2012/05/15/kookaburra-0-dot-24-dot-0-released-exorcised-activesupport</id>
    <content type="html"><![CDATA[<p>I just released version 0.24.0 of <a href="http://github.com/jwilger/kookaburra">Kookaburra</a> to
<a href="http://rubygems.org/gems/kookaburra/versions/0.24.0">Rubygems.org</a>. While there were no changes to <em>Kookaburra&#8217;s</em> API
with this release, it is a minor release rather than a patch release,
because I removed <a href="http://rubydoc.info/gems/activesupport/3.0.0/frames" title="ActiveSupport 3.0.0 API Documentation">ActiveSupport</a> from Kookaburra&#8217;s dependencies.
Previously, Kookaburra depended on ActiveSupport >= 3.0, and this
prevented it from working smoothly with Rails 2.x applications (at least
in the same Bundler bundle.) Since Kookaburra only used a small fraction
of ActiveSupport, it seemed easiest just to break the dependency, so
that your application can use whatever version of ActiveSupport it
needs.</p>

<p>Because of the fact that ActiveSupport makes a number of modifications
to core Ruby classes, if your application does not otherwise explicitly
require ActiveSupport, some of these core classes may now behave
differently. Specifically, <code>Hash</code> and <code>String</code> core extensions were
being used, as well as <code>ActiveSupport::CoreExt::Module::Delegation</code>.</p>

<p>Also, where <code>Kookaburra::JsonApiDriver</code> used <code>ActiveSupport::JSON</code> for
encoding and decoding of JSON data, it now uses <code>::JSON</code> as provided by
<em>either</em> the <a href="http://rubygems.org/gems/json" title="json | RubyGems.org">json</a> or the <a href="http://rubygems.org/gems/json_pure" title="json_pure | RubyGems.org">json_pure</a> gems. The tests
on Kookaburra itself pass just by swapping out ActiveSupport JSON
library for the new one, but these tests do not comprehensively test
JSON usage, and there may be differences that impact your application.</p>

<p>Kookaburra declares its dependency on the <code>json_pure</code> gem (a pure-ruby
version) in order to ensure that it works cross-platform. However, both
<code>json</code> and <code>json_pure</code> are written in such a way that, when you <code>require
'json'</code>, it will detect if both libraries are installed and prefer the
natively compiled <code>json</code> gem&#8217;s version of the library.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[tmux and the OSX Clipboard]]></title>
    <link href="http://johnwilger.com/blog/2012/04/12/tmux-and-the-osx-clipboard/"/>
    <updated>2012-04-12T10:48:00-07:00</updated>
    <id>http://johnwilger.com/blog/2012/04/12/tmux-and-the-osx-clipboard</id>
    <content type="html"><![CDATA[<p>I started using <a href="http://tmux.sourceforge.net/" title="tmux">tmux</a> recently after a) I was informed that GNU screen is
basically an outdated POS, and b) an <a href="http://pragprog.com/book/bhtmux/tmux" title="tmux: Productive Mouse-Free Development">excellent book</a> on the subject
was published. I&#8217;m glad to have made the switch, as tmux is a wonderful
improvement over screen. However, on OSX, I found that the <code>pbcopy</code> and
<code>pbpaste</code> commands (among other things) would no longer work from within a tmux
session.</p>

<p>After a bit of searching, I found <a href="http://writeheavy.com/2011/10/23/reintroducing-tmux-to-the-osx-clipboard.html" title="Reintroducing tmux to the OSX Clipboard">this post</a> that explains how to make
things right again.</p>

<p>TL;DR:</p>

<figure class='code'><figcaption><span>run this</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>brew install reattach-to-user-namespace
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>add this to ~/.tmux.conf</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="c"># Reattach to user namespace so that clipboard integration with OSX works again</span>
</span><span class='line'><span class="nb">set</span>-option -g default-command <span class="s2">&quot;reattach-to-user-namespace -l zsh&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Obviously, replace <code>zsh</code> above with whatever you use for your shell.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Kookaburra Rewrite for 0.15.1]]></title>
    <link href="http://johnwilger.com/blog/2012/03/10/kookaburra-rewrite-for-0-dot-15-dot-1/"/>
    <updated>2012-03-10T16:25:00-08:00</updated>
    <id>http://johnwilger.com/blog/2012/03/10/kookaburra-rewrite-for-0-dot-15-dot-1</id>
    <content type="html"><![CDATA[<p>After getting some good feedback on <a href="http://github.com/jwilger/kookaburra" title="jwilger/kookaburra">Kookaburra</a> since the original
release announcement as well as using it in a few more projects, <a href="http://livingston-gray.com" title="Sam Livingston-Gray">Sam</a> and
I decided to treat all of the versions prior to 0.15.0 as a spike and rewrite
the framework from the ground up. Although we certainly learned a lot about the
approach with the pre-0.15 versions, the problems with continuing to grow
Kookaburra from that seed became apparent as we tried to use it in more
applications.</p>

<p>Because the original code was extracted from another project, the Kookaburra
framework itself was not well tested. It had been indirectly tested due to its
position within that other project&#8217;s tests, but as a seperate library it lacked
tests that would help bot document the project and ensure newcomers can work on
it with a good safety net. Additionally, there were a number of design decisions
made in the earlier versions of Kookaburra that were&#8230;questionable. Not only
would these decisions probably have been made differently if the development of
the framework itself had been driven with unit tests, these decisions in many
cases made it difficult to go back and add tests after the fact.</p>

<p>Starting with 0.15.1, which I just <a href="http://rubygems.org/gems/kookaburra" title="kookaburra | Rubygems.org">released</a> a few moments ago,
Kookaburra has been rewritten using a proper TDD approach. In some ways, 0.15.1
is possibly less functional than its 0.14.x cousins, but it is almost certainly
easier to understand and contribute to the project from this point on. Please
have a look at the new codebase, try it out in your projects, and send me a pull
request with updates to the library. Also, if you have any problems getting it
running, please don&#8217;t hesitate to <a href="https://github.com/jwilger/kookaburra/issues?sort=created&amp;direction=desc&amp;state=open" title="Issues jwilger/kookaburra">let me know</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using Jeweler for Private Gems]]></title>
    <link href="http://johnwilger.com/blog/2012/01/25/using-jeweler-for-private-gems/"/>
    <updated>2012-01-25T11:41:00-08:00</updated>
    <id>http://johnwilger.com/blog/2012/01/25/using-jeweler-for-private-gems</id>
    <content type="html"><![CDATA[<p>I really like using <a href="http://github.com/technicalpickles/jeweler" title="technicalpickles/jeweler - GitHub">Jeweler</a> to create and manage gems, but its default
behavior is to publish your gem to <a href="http://rubygems.org" title="RubyGems.org | your community gem host">rubygems.org</a> whenever you run <code>rake
release</code>. This is great for generally useful libraries that you want to
open-source, but not as great when you want to use gems as shared libraries for
internal use only (whether because the code contains business secrets or just
because it&#8217;s not something that would be useful to the community at large.)</p>

<p>After a bit of poking around, I figured out how to use Jeweler to manage
your versioning, gemspec and git tagging without pushing the result to
rubygems.org when running the release task. It turns out to be both obvious and
trivial. Just add the following line to the end of your gem project&#8217;s
<code>Rakefile</code>:</p>

<figure class='code'><figcaption><span>Rakefile</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">Rake</span><span class="o">::</span><span class="no">Task</span><span class="o">[</span><span class="ss">:release</span><span class="o">].</span><span class="n">prerequisites</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="s1">&#39;gemcutter:release&#39;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Acceptance and Integration Testing with Kookaburra]]></title>
    <link href="http://johnwilger.com/blog/2012/01/21/acceptance-and-integration-testing-with-kookaburra/"/>
    <updated>2012-01-21T20:57:00-08:00</updated>
    <id>http://johnwilger.com/blog/2012/01/21/acceptance-and-integration-testing-with-kookaburra</id>
    <content type="html"><![CDATA[<p><strong>UPDATE (2012-01-22):</strong> <em>I realized this morning that the credit I gave to <a href="http://resume.livingston-gray.com/">Sam
Livingston-Gray</a> below may not have
adequately shown how instrumental he was in getting this project off the ground;
especially since much of his work was done in the private repository from which
this was extracted. So, thanks, Sam. This might not have gone anywhere if you
hadn&#8217;t worked to put the idea in practice in our application and helped everyone
on our team learn how to use the approach. I made a few minor changes below to
reflect this a bit better.</em></p>

<p>We&#8217;ve been using <a href="http://cukes.info/">Cucumber</a> for acceptance testing at
<a href="http://renewfund.com">Renewable Funding</a> since back when it was still part of
the <a href="http://rspec.info">RSpec</a> project (indeed, since before we were even
Renewable Funding). While we&#8217;ve always liked the ability to have plain-language
feature documentation that we could automatically test against, after years of
adding to and maintaining a fairly large set of Cucumber scenarios, the cost of
that maintenance was starting to really slow us down. The test suite began to
grow fragile, and it seemed like every time one of our UX designers changed
anything about the application&#8217;s interface, the development team would spend a
bunch of time just babysitting Cucumber tests to get them passing again.</p>

<p>Last year, as I was reading Jez Humble&#8217;s excellent <a href="http://www.amazon.com/gp/product/0321601912?tag=contindelive-20">Continuous
Delivery</a> book,
I was inspired when I came across the section titled &#8220;The Application Driver
Layer&#8221; (p. 198). This section describes an approach to acceptance testing where
the specification and the test implementation are isolated from the details of
the application&#8217;s user interface by inserting a layer between the two that uses
good old OOP to abstract the user interface components. Martin Fowler describes
it as the <a href="http://martinfowler.com/eaaDev/WindowDriver.html" title="Window Driver - Martin Fowler">Window Driver</a> pattern on his website.</p>

<p>I started a proof-of-concept implementation of this pattern last summer, then my
coworker, <a href="http://resume.livingston-gray.com/">Sam Livingston-Gray</a> and I
started pulling it into a new project at work. After Sam and the rest of the
Renewable Funding team helped improve on my original attempt while putting it to
use for the last six or so months, we extracted a library to make it easier for
other Ruby developers to implement this pattern in their testing. I&#8217;m happy to
introduce <a href="http://github.com/projectdx/kookaburra">Kookaburra</a> to the world.</p>

<!-- more -->


<p>The following comes from Kookaburra&#8217;s README as of version 0.7.1.</p>

<hr />

<h1>Kookaburra</h1>

<p>Kookaburra is a framework for implementing the <a href="http://martinfowler.com/eaaDev/WindowDriver.html" title="Window Driver - Martin Fowler">Window Driver</a> pattern in
order to keep acceptance tests maintainable.</p>

<h2>Setup</h2>

<p>Kookaburra itself abstracts some common patterns for implementing the Window
Driver pattern for tests of Ruby web applications built on <a href="http://rack.rubyforge.org/" title="Rack: a Ruby Webserver Interface">Rack</a>. You will need
to tell Kookaburra which classes contain the specific Domain Driver
implementations for your application as well as which driver to use for running
the tests (currently only tested with <a href="https://github.com/jnicklas/capybara" title="jnicklas/capybara - GitHub">Capybara</a>). The details of setting up your
Domain Driver layer are discussed below, but in general you will need the
following in a locations such as <code>lib/my_application/kookaburra.rb</code> (replace
<code>MyApplication</code> with a module name suitable to your actual application:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">module</span> <span class="nn">MyApplication</span>
</span><span class='line'>  <span class="k">module</span> <span class="nn">Kookaburra</span>
</span><span class='line'>    <span class="o">::</span><span class="no">Kookaburra</span><span class="o">.</span><span class="n">adapter</span> <span class="o">=</span> <span class="no">Capybara</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># Note: the following assigned classes are defined under your</span>
</span><span class='line'>    <span class="c1"># application&#39;s namespace, e.g. MyApplication::Kookaburra::APIDriver</span>
</span><span class='line'>    <span class="o">::</span><span class="no">Kookaburra</span><span class="o">.</span><span class="n">api_driver</span> <span class="o">=</span> <span class="no">APIDriver</span>
</span><span class='line'>    <span class="o">::</span><span class="no">Kookaburra</span><span class="o">.</span><span class="n">given_driver</span> <span class="o">=</span> <span class="no">GivenDriver</span>
</span><span class='line'>    <span class="o">::</span><span class="no">Kookaburra</span><span class="o">.</span><span class="n">ui_driver</span> <span class="o">=</span> <span class="no">UIDriver</span>
</span><span class='line'>
</span><span class='line'>    <span class="o">::</span><span class="no">Kookaburra</span><span class="o">.</span><span class="n">test_data_setup</span> <span class="k">do</span>
</span><span class='line'>      <span class="n">provide_collection</span> <span class="ss">:accounts</span>
</span><span class='line'>      <span class="c1"># See section on Test Data for more examples of what can go here.</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h3>RSpec</h3>

<p>For <a href="http://rspec.info" title="RSpec.info: home">RSpec</a> integration tests, just add the following file to your project:</p>

<figure class='code'><figcaption><span>spec/support/kookaburra_setup.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;my_application/kookaburra&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="no">RSpec</span><span class="o">.</span><span class="n">configure</span> <span class="k">do</span> <span class="o">|</span><span class="n">c</span><span class="o">|</span>
</span><span class='line'>  <span class="n">c</span><span class="o">.</span><span class="n">include</span><span class="p">(</span><span class="no">Kookaburra</span><span class="p">,</span> <span class="ss">:type</span> <span class="o">=&gt;</span> <span class="ss">:request</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Cucumber</h3>

<p>For Cucumber, add the following file to your project</p>

<figure class='code'><figcaption><span>features/support/kookaburra_setup.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;my_application/kookaburra&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="no">Kookaburra</span><span class="o">.</span><span class="n">adapter</span> <span class="o">=</span> <span class="no">Capybara</span>
</span><span class='line'><span class="no">World</span><span class="p">(</span><span class="no">Kookaburra</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="no">Before</span> <span class="k">do</span>
</span><span class='line'>  <span class="c1"># Ensure that there isn&#39;t state-leakage between scenarios</span>
</span><span class='line'>  <span class="n">kookaburra_reset!</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>This will cause the #api, #given and #ui methods will be available in your
Cucumber step definitions.</p>

<h2>Defining Your Testing DSL</h2>

<p>Kookaburra attempts to extract some common patterns that make it easier to use
the Window Driver pattern along with various Ruby testing frameworks, but you
still need to define your own testing DSL. An acceptance testing stack using
Kookaburra has the following four layers:</p>

<ol>
<li>The <strong>Business Specification Language</strong> (Cucumber scenarios and step definitions)</li>
<li>The <strong>Domain Driver</strong> (Kookaburra::GivenDriver and Kookaburra::UIDriver)</li>
<li>The <strong>Window Driver</strong> (Kookaburra::UIDriver::UIComponent)</li>
<li>The <strong>Application Driver</strong> (Capybara and Rack::Test)</li>
</ol>


<h3>The Business Specification Language</h3>

<p>The business specification language consists of the highest-level descriptions
of a feature that are suitable for sharing with the non/less-technical
stakeholders on a project.</p>

<p>Gherkin is the external DSL used by Cucumber for this purpose, and you might
have the following scenario defined for an e-commerce application:</p>

<figure class='code'><figcaption><span>purchase_items_in_cart.feature</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='cucumber'><span class='line'><span class="k">Feature:</span><span class="nf"> Purchase Items in Cart</span>
</span><span class='line'>
</span><span class='line'><span class="nf">  </span><span class="k">Scenario:</span><span class="nf"> Using Existing Billing and Shipping Information</span>
</span><span class='line'><span class="k">    </span>
</span><span class='line'><span class="k">    Given </span><span class="nf">I have an existing account</span>
</span><span class='line'><span class="nf">    </span><span class="k">And </span><span class="nf">I have previously specified default payment options</span>
</span><span class='line'><span class="nf">    </span><span class="k">And </span><span class="nf">I have previously specified default shipping options</span>
</span><span class='line'><span class="nf">    </span><span class="k">And </span><span class="nf">I have an item in my shopping cart</span>
</span><span class='line'>
</span><span class='line'><span class="nf">    </span><span class="k">When </span><span class="nf">I sign in to my account</span>
</span><span class='line'><span class="nf">    </span><span class="k">And </span><span class="nf">I choose to check out</span>
</span><span class='line'>
</span><span class='line'><span class="nf">    </span><span class="k">Then </span><span class="nf">I see my order summary</span>
</span><span class='line'><span class="nf">    </span><span class="k">And </span><span class="nf">I see that my default payment options will be used</span>
</span><span class='line'><span class="nf">    </span><span class="k">And </span><span class="nf">I see that my default shipping options will be used</span>
</span></code></pre></td></tr></table></div></figure>


<p>Note that the scenario is focused on business concepts versus interface details,
i.e. you &#8220;choose to check out&#8221; rather than &#8220;click on the checkout button&#8221;. If
for some reason your e-commerce system was going to be a terminal application
rather than a web application, you would not need to change this scenario at
all, because the actual business concepts described would not change.</p>

<h3>The Domain Driver</h3>

<p>The Domain Driver layer is where you build up an internal DSL that describes the
business concepts of your application at a fairly high level. It consists of
three top-level drivers: the <code>APIDriver</code> (available via <code>#api</code>) for interacting
with your application&#8217;s external API, the <code>GivenDriver</code> (available via <code>#given</code>)
which really just wraps the <code>APIDriver</code> and is used to set up state for your
tests, and the UIDriver (available via <code>#ui</code>) for describing the tasks that a
user can accomplish with the application.</p>

<p>Given the Cucumber scenario above, the step definitions call into the Domain
Driver layer to interact with your application:</p>

<figure class='code'><figcaption><span>step_definitions/various_steps.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">Given</span> <span class="s2">&quot;I have an existing account&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">given</span><span class="o">.</span><span class="n">existing_account</span><span class="p">(</span><span class="ss">:my_account</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="no">Given</span> <span class="s2">&quot;I have previously specified default payment options&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">given</span><span class="o">.</span><span class="n">default_payment_options_specified_for</span><span class="p">(</span><span class="ss">:my_account</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="no">Given</span> <span class="s2">&quot;I have previously specified default shipping options&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">given</span><span class="o">.</span><span class="n">default_shipping_options_specified_for</span><span class="p">(</span><span class="ss">:my_account</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="no">Given</span> <span class="s2">&quot;I have an item in my shopping cart&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">given</span><span class="o">.</span><span class="n">an_item_in_my_shopping_cart</span><span class="p">(</span><span class="ss">:my_account</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="no">When</span> <span class="s2">&quot;I sign in to my account&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">ui</span><span class="o">.</span><span class="n">sign_in</span><span class="p">(</span><span class="ss">:my_account</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="no">When</span> <span class="s2">&quot;I choose to check out&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">ui</span><span class="o">.</span><span class="n">choose_to_check_out</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="no">Then</span> <span class="s2">&quot;I see my order summary&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">ui</span><span class="o">.</span><span class="n">order_summary</span><span class="o">.</span><span class="n">should</span> <span class="n">be_visible</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="no">Then</span> <span class="s2">&quot;I see that my default payment options will be used&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">ui</span><span class="o">.</span><span class="n">order_summary</span><span class="o">.</span><span class="n">payment_options</span><span class="o">.</span><span class="n">should</span> <span class="n">be_account_default_options</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="no">Then</span> <span class="s2">&quot;I see that my default shipping options will be used&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">ui</span><span class="o">.</span><span class="n">order_summary</span><span class="o">.</span><span class="n">shipping_options</span><span class="o">.</span><span class="n">should</span> <span class="n">be_account_default_options</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The step definitions contain neither explicitly shared state (instance
variables) nor any logic branches; they are simply wrappers around calls into
the Domain Driver layer. There are a couple of advantages to this approach.
First, because step definitions are so simple, it isn&#8217;t necessary to force <em>Very
Specific Wording</em> on the business analyst/product owner who is writing the
specs. For instance, if she writes &#8220;I see a summary of my order&#8221; in another
scenario, it&#8217;s not a big deal to have the following in your step definitions (as
long as the author of the spec confirms that they really mean the same thing):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">Then</span> <span class="s2">&quot;I see my order summary&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">ui</span><span class="o">.</span><span class="n">order_summary</span><span class="o">.</span><span class="n">should</span> <span class="n">be_visible</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="no">Then</span> <span class="s2">&quot;I see a summary of my order&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">ui</span><span class="o">.</span><span class="n">order_summary</span><span class="o">.</span><span class="n">should</span> <span class="n">be_visible</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The step definitions are nothing more than a natural language reference to an
action in the Domain Driver; there is no overwhelming maintenance cost to the
slight duplication, and it opens up the capacity for more readable Gherkin
specs. The fewer false road blocks you put between your product owner and a
written specification, the easier it becomes to ensure her participation in this
process.</p>

<p>The second advantage is that by pushing all of the complexity down into the
Domain Driver, it&#8217;s now trivial to reuse the exact same code in
developer-centric integration tests. This ensures you have parity between the
way the automated acceptance tests run and any additional testing that the
development team needs to add in. You could write the same test using just
RSpec as follows:</p>

<figure class='code'><figcaption><span>spec/integration/purchase_items_in_cart_spec.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="s2">&quot;Purchase Items in Cart&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">example</span> <span class="s2">&quot;Using Existing Billing and Shipping Information&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">given</span><span class="o">.</span><span class="n">existing_account</span><span class="p">(</span><span class="ss">:my_account</span><span class="p">)</span>
</span><span class='line'>    <span class="n">given</span><span class="o">.</span><span class="n">default_payment_options_specified_for</span><span class="p">(</span><span class="ss">:my_account</span><span class="p">)</span>
</span><span class='line'>    <span class="n">given</span><span class="o">.</span><span class="n">default_shipping_options_specified_for</span><span class="p">(</span><span class="ss">:my_account</span><span class="p">)</span>
</span><span class='line'>    <span class="n">given</span><span class="o">.</span><span class="n">an_item_in_my_shopping_cart</span><span class="p">(</span><span class="ss">:my_account</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">ui</span><span class="o">.</span><span class="n">sign_in</span><span class="p">(</span><span class="ss">:my_account</span><span class="p">)</span>
</span><span class='line'>    <span class="n">ui</span><span class="o">.</span><span class="n">choose_to_check_out</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">ui</span><span class="o">.</span><span class="n">order_summary</span><span class="o">.</span><span class="n">should</span> <span class="n">be_visible</span>
</span><span class='line'>    <span class="n">ui</span><span class="o">.</span><span class="n">order_summary</span><span class="o">.</span><span class="n">payment_options</span><span class="o">.</span><span class="n">should</span> <span class="n">be_account_default_options</span>
</span><span class='line'>    <span class="n">ui</span><span class="o">.</span><span class="n">order_summary</span><span class="o">.</span><span class="n">shipping_options</span><span class="o">.</span><span class="n">should</span> <span class="n">be_account_default_options</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Whether in Cucumber step definitions or developer integration tests, you will
usually interact only with the GivenDriver and the UIDriver.</p>

<h4>TestData</h4>

<p><code>Kookaburra::TestData</code> is the component via which the <code>GivenDriver</code> and the
<code>UIDriver</code> share information. For instance, if you create a user account via the
<code>GivenDriver</code>, you would store the login credentials for that account in the
<code>TestData</code> instance, so the UIDriver knows what to use when you tell it to
<code>#sign_in</code>. This is what allows the Cucumber step definitions to remain free
from explicitly shared state.</p>

<p>The <code>TestData</code> class can be configured to contain both collections of test data
as well as default data that can be used as a starting point for creating new
resources in the application. To configure <code>TestData</code>, call
<code>Kookaburra.test_data_setup</code> with a block (usually in your
<code>lib/my_application/kookaburra.rb</code> file):</p>

<figure class='code'><figcaption><span>lib/my_application/kookaburra.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">module</span> <span class="nn">MyApplication</span>
</span><span class='line'>  <span class="k">module</span> <span class="nn">Kookaburra</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>    <span class="o">::</span><span class="no">Kookaburra</span><span class="o">.</span><span class="n">test_data_setup</span> <span class="k">do</span>
</span><span class='line'>      <span class="n">provide_collection</span> <span class="ss">:animals</span>
</span><span class='line'>      <span class="n">set_default</span> <span class="ss">:animal</span><span class="p">,</span>
</span><span class='line'>        <span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s1">&#39;horse&#39;</span>
</span><span class='line'>        <span class="ss">:size</span> <span class="o">=&gt;</span> <span class="s1">&#39;large&#39;</span><span class="p">,</span>
</span><span class='line'>        <span class="ss">:number_of_legs</span> <span class="o">=&gt;</span> <span class="mi">4</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then, in any context where you have an instance of <code>TestData</code> (such as in
<code>GivenDriver</code> or <code>UIDriver</code>), you can add/retrieve items to/from collections and
access default data:</p>

<figure class='code'><figcaption><span>lib/my_application/kookaburra/given_driver.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">MyApplication</span><span class="o">::</span><span class="no">Kookaburra</span><span class="o">::</span><span class="no">GivenDriver</span> <span class="o">&lt;</span> <span class="no">Kookaburra</span><span class="o">::</span><span class="no">GivenDriver</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">existing_account</span><span class="p">(</span><span class="n">nickname</span><span class="p">)</span>
</span><span class='line'>    <span class="n">default_account_data</span> <span class="o">=</span> <span class="n">test_data</span><span class="o">.</span><span class="n">default</span><span class="p">(</span><span class="ss">:account</span><span class="p">)</span>
</span><span class='line'>    <span class="c1"># do something to create account in application</span>
</span><span class='line'>    <span class="c1"># ...</span>
</span><span class='line'>    <span class="c1"># make the details of the new account available to the rest of the test</span>
</span><span class='line'>    <span class="n">test_data</span><span class="o">.</span><span class="n">accounts</span><span class="o">[</span><span class="n">nickname</span><span class="o">]</span> <span class="o">=</span> <span class="n">account</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>lib/my_application/kookaburra/ui_driver.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">MyApplication</span><span class="o">::</span><span class="no">Kookaburra</span><span class="o">::</span><span class="no">UIDriver</span> <span class="o">&lt;</span> <span class="no">Kookaburra</span><span class="o">::</span><span class="no">UIDriver</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">sign_in</span><span class="p">(</span><span class="n">account_nickname</span><span class="p">)</span>
</span><span class='line'>    <span class="c1"># pull stored account details from TestData</span>
</span><span class='line'>    <span class="n">account_info</span> <span class="o">=</span> <span class="n">test_data</span><span class="o">.</span><span class="n">accounts</span><span class="o">[</span><span class="n">account_nickname</span><span class="o">]</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># do something to log in using that account_info</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h4>APIDriver</h4>

<p>The <code>Kookaburra::APIDriver</code> is used to interact with an application&#8217;s external
web services API. You tell Kookaburra about your API by creating a subclass of
<code>Kookaburra::APIDriver</code> for your application:</p>

<figure class='code'><figcaption><span>lib/my_application/kookaburra/api_driver.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">MyApplication</span><span class="o">::</span><span class="no">Kookaburra</span><span class="o">::</span><span class="no">APIDriver</span> <span class="o">&lt;</span> <span class="no">Kookaburra</span><span class="o">::</span><span class="no">APIDriver</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">create_account</span><span class="p">(</span><span class="n">account_data</span><span class="p">)</span>
</span><span class='line'>    <span class="n">post_as_json</span> <span class="s1">&#39;Account&#39;</span><span class="p">,</span> <span class="s1">&#39;api/v1/accounts&#39;</span><span class="p">,</span> <span class="ss">:account</span> <span class="o">=&gt;</span> <span class="n">account_data</span>
</span><span class='line'>    <span class="n">hash_from_response_json</span><span class="o">[</span><span class="ss">:account</span><span class="o">]</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h4>GivenDriver</h4>

<p>The <code>Kookaburra::GivenDriver</code> is used to create a particular &#8220;preexisting&#8221;
state within your application&#8217;s data and ensure you have a handle to that data
(when needed) prior to interacting with the UI. Like the <code>APIDriver</code>, you will
create a subclass of <code>Kookaburra::GivenDriver</code> in which you will create part of
the Domain Driver DSL for your application:</p>

<figure class='code'><figcaption><span>lib/my_application/kookaburra/given_driver.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">MyApplication</span><span class="o">::</span><span class="no">Kookaburra</span><span class="o">::</span><span class="no">GivenDriver</span> <span class="o">&lt;</span> <span class="no">Kookaburra</span><span class="o">::</span><span class="no">GivenDriver</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">existing_account</span><span class="p">(</span><span class="n">nickname</span><span class="p">)</span>
</span><span class='line'>    <span class="c1"># grab the default account details and add a unique username and</span>
</span><span class='line'>    <span class="c1"># password</span>
</span><span class='line'>    <span class="n">account_data</span> <span class="o">=</span> <span class="n">test_data</span><span class="o">.</span><span class="n">default</span><span class="p">(</span><span class="ss">:account</span><span class="p">)</span>
</span><span class='line'>    <span class="n">account_data</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;test-user-</span><span class="si">#{</span><span class="sb">`uuidgen`</span><span class="o">.</span><span class="n">strip</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span class='line'>    <span class="n">account_data</span><span class="o">[</span><span class="ss">:password</span><span class="o">]</span> <span class="o">=</span> <span class="n">account_data</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span> <span class="o">+</span> <span class="s2">&quot;-password&quot;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># use the API to create the account in the application</span>
</span><span class='line'>    <span class="n">account_details</span> <span class="o">=</span> <span class="n">api</span><span class="o">.</span><span class="n">create_account</span><span class="p">(</span><span class="n">account_data</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># merge in the password (since API doesn&#39;t return it) and store details</span>
</span><span class='line'>    <span class="c1"># in the TestData instance</span>
</span><span class='line'>    <span class="n">account_details</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="ss">:password</span> <span class="o">=&gt;</span> <span class="n">account_data</span><span class="o">[</span><span class="ss">:password</span><span class="o">]</span><span class="p">)</span>
</span><span class='line'>    <span class="n">test_data</span><span class="o">.</span><span class="n">accounts</span><span class="o">[</span><span class="n">nickname</span><span class="o">]</span> <span class="o">=</span> <span class="n">account_details</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h4>UIDriver</h4>

<p><code>Kookaburra::UIDriver</code> provides the necessary tools for driving your
application&#8217;s user interface using the Window Driver pattern. You will subclass
<code>Kookaburra::UIDriver</code> for your application and implement your testing DSL
within your subclass:</p>

<figure class='code'><figcaption><span>lib/my_application/kookaburra/ui_driver.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">MyApplication</span><span class="o">::</span><span class="no">Kookaburra</span><span class="o">::</span><span class="no">UIDriver</span> <span class="o">&lt;</span> <span class="no">Kookaburra</span><span class="o">::</span><span class="no">UIDriver</span>
</span><span class='line'>  <span class="c1"># makes an instance of MyApplication::Kookaburra::UIDriver::SignInScreen</span>
</span><span class='line'>  <span class="c1"># available via the instance method #sign_in_screen</span>
</span><span class='line'>  <span class="n">ui_component</span> <span class="ss">:sign_in_screen</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">sign_in</span><span class="p">(</span><span class="n">account_nickname</span><span class="p">)</span>
</span><span class='line'>    <span class="n">account</span> <span class="o">=</span> <span class="n">test_data</span><span class="o">.</span><span class="n">accounts</span><span class="o">[</span><span class="n">account_nickname</span><span class="o">]</span>
</span><span class='line'>    <span class="n">navigate_to</span> <span class="ss">:sign_in_screen</span>
</span><span class='line'>    <span class="n">sign_in_screen</span><span class="o">.</span><span class="n">submit_login</span><span class="p">(</span><span class="n">account</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">,</span> <span class="n">account</span><span class="o">[</span><span class="ss">:password</span><span class="o">]</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h3>The Window Driver Layer</h3>

<p>While your <code>GivenDriver</code> and <code>UIDriver</code> provide a DSL that represents actions
your users can perform in your application, the <a href="http://martinfowler.com/eaaDev/WindowDriver.html" title="Window Driver - Martin Fowler">Window Driver</a> layer describes
the individual user interface components that the user interacts with to perform
these tasks. By describing each interface component using an OOP approach, it is
much easier to maintain your acceptance/integration tests, because the
implementation details of each component are captured in a single place. If/when
that implementation changes, you can&#8212;for example&#8212;fix every single test that
needs to log a user into the system just by updating the SignInScreen class.</p>

<p>You describe the various user interface components by sub-classing
<code>Kookaburra::UIDriver::UIComponent</code>:</p>

<figure class='code'><figcaption><span>lib/my_application/ui_driver/sign_in_screen.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">MyApplication</span><span class="o">::</span><span class="no">Kookaburra</span><span class="o">::</span><span class="no">UIDriver</span><span class="o">::</span><span class="no">SignInScreen</span> <span class="o">&lt;</span> <span class="no">Kookaburra</span><span class="o">::</span><span class="no">UIDriver</span><span class="o">::</span><span class="no">UIComponent</span>
</span><span class='line'>  <span class="n">component_locator</span> <span class="s1">&#39;#new_user_session&#39;</span>
</span><span class='line'>  <span class="n">component_path</span> <span class="s1">&#39;/session/new&#39;</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">username</span>
</span><span class='line'>    <span class="n">in_component</span> <span class="p">{</span> <span class="n">browser</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;#session_username&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">value</span> <span class="p">}</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">username</span><span class="o">=</span><span class="p">(</span><span class="n">new_value</span><span class="p">)</span>
</span><span class='line'>    <span class="n">fill_in</span><span class="p">(</span><span class="s1">&#39;#session_username&#39;</span><span class="p">,</span> <span class="ss">:with</span> <span class="o">=&gt;</span> <span class="n">new_value</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">password</span>
</span><span class='line'>    <span class="n">in_component</span> <span class="p">{</span> <span class="n">browser</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;#session_password&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">value</span> <span class="p">}</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">password</span><span class="o">=</span><span class="p">(</span><span class="n">new_value</span><span class="p">)</span>
</span><span class='line'>    <span class="n">fill_in</span><span class="p">(</span><span class="s1">&#39;#session_password&#39;</span><span class="p">,</span> <span class="ss">:with</span> <span class="o">=&gt;</span> <span class="n">new_value</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">submit!</span>
</span><span class='line'>    <span class="n">click_on</span><span class="p">(</span><span class="s1">&#39;Sign In&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="n">no_500_error!</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">submit_login</span><span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span>
</span><span class='line'>    <span class="nb">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="n">username</span>
</span><span class='line'>    <span class="nb">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">password</span>
</span><span class='line'>    <span class="n">submit!</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[RPG Character Tokens]]></title>
    <link href="http://johnwilger.com/blog/2012/01/01/rpg-character-tokens/"/>
    <updated>2012-01-01T14:47:00-08:00</updated>
    <id>http://johnwilger.com/blog/2012/01/01/rpg-character-tokens</id>
    <content type="html"><![CDATA[<p>I recently started playing <a href="http://www.wizards.com/dnd/">Dungeons &amp; Dragons</a>
again (after not playing since I was in high school). I&#8217;m DM-ing a game for my
son, Jacob, and a few other folks. We&#8217;re playing 4th Edition, which relies
heavily on a battle grid and character tokens to represent combat encounters.
In order to save money and hassle, I wanted an alternative to searching for and
buying the correct miniatures for each encounter.</p>

<!-- more -->


<p>I don&#8217;t mind spending money on nice miniatures for player characters, but
you can spend an insane amount buying miniatures to represent the
monsters and NPCs the characters might encounter. Also, if you&#8217;re going to use
miniatures for monsters and NPCs, you need to have the <em>right</em> miniatures; using
a kobold figure to represent a needle demon doesn&#8217;t really help with the
suspension of disbelief.</p>

<p>Maybe it&#8217;s just that I have fond memories of games that took place entirely in
our heads, but I like the idea of using generic tokens to represent
position and leaving the physical description up to the DM&#8217;s skills and the
players&#8217; imaginations.</p>

<p>A good way to make character tokens is to stick a 1&#8221; diameter, felt furniture
pad to one side of a 1&#8221; (outer!) diameter, metal washer. The metal washer gives
the token enough weight to stay put on the battle grid, and the felt furniture
pad gives it enough height to be easy to pick it up and move it around. Then,
you can just use those Post-It™ Flags to identify each token (and keep track of
any active effects on it).</p>

<p><img src="http://johnwilger.com/images/2012/01/2012-01-01-token.jpg" width="350" title="D&D Token" alt="photograph of a 1-inch metal washer with a 1-inch felt pad attached to one side"></p>

<p>You could probably do the same with 2&#8221;, 3&#8221; and 4&#8221; diameter washers and pads for
your bigger creatures, although huge and gargantuan creatures may be special
enough that buying nice models for these is probably worth the money.</p>

<p>Giving credit where it&#8217;s due, I riffed on this <a href="http://newbiedm.com/2008/11/22/newbiedm-tutorial-counters-tokens-or-pogs/">process for creating tokens
posted at Newbie
DM</a>.
I just don&#8217;t bother with all the graphics editing and printing, and I like to
give the height to <em>all</em> of the tokens (with the furniture pads), because washers
by themselves can be hard to pick up when they&#8217;re laying flat.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[OMFG]]></title>
    <link href="http://johnwilger.com/blog/2011/12/26/omfg/"/>
    <updated>2011-12-26T17:34:00-08:00</updated>
    <id>http://johnwilger.com/blog/2011/12/26/omfg</id>
    <content type="html"><![CDATA[<p><img src="http://johnwilger.com/images/20111226-387.jpg" title="OMFG" alt="An image of a man covering his face with his hand and wearing a shirt with the acronym OMFG on it."></p>

<p>I wish this photo was a bit sharper, but it still sums up my feeling pretty well
about&#8230; well&#8230; a lot of things. :-)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Switched to Octopress]]></title>
    <link href="http://johnwilger.com/blog/2011/12/20/switched-to-octopress/"/>
    <updated>2011-12-20T11:12:00-08:00</updated>
    <id>http://johnwilger.com/blog/2011/12/20/switched-to-octopress</id>
    <content type="html"><![CDATA[<p>Sometimes it seems the only time I post to my website anymore is when I decide
to switch out the software that&#8217;s used to publish years-old articles. :-(</p>

<p>At any rate, I&#8217;m switching over to <a href="http://octopress.org">Octopress</a> to run this
site, because a) it&#8217;s the new awesome, and b) maybe I&#8217;ll spend more time writing
articles if I&#8217;m not trying to tweak my home-grown blogging engine while I do it.
I chose Octopress because it has the parts I like about
<a href="https://github.com/mojombo/jekyll/">jekyll</a> (I get to write my posts in vim and
eaisly manage the content with git), but it has more of the rough edges smoothed
out (again, so I can spend my time writing articles instead of working on the
engine.)</p>

<p>As part of this, I&#8217;m also moving the site from <a href="http://heroku.com">Heroku</a> to <a href="http://pages.github.com">Github
Pages</a>. Nothing at all wrong with Heroku; it&#8217;s just one
fewer thing for me to deal with.</p>

<p>I&#8217;m now going to port over old articles (a much easier task than last time,
since the last version of this site was also using markdown-formatted text
files.) The comment system was already on <a href="http://disqus.com">Disqus</a> before, so
hopefully I can figure out how to get the old comments associated with the new
URLs.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Capybara, Selenium and Firefox 3.5]]></title>
    <link href="http://johnwilger.com/blog/2011/04/30/capybara-selenium-and-firefox-3-5/"/>
    <updated>2011-04-30T20:08:00-07:00</updated>
    <id>http://johnwilger.com/blog/2011/04/30/capybara-selenium-and-firefox-3-5</id>
    <content type="html"><![CDATA[<p>I banged my head against this one while setting up our CI build for a new
project at work and just now figured it out. I added an example integration
spec that just visits the default Rails homepage, clicks the &#8220;About your
application&#8217;s environment&#8221; link, and verifies the Rails version. This link
uses an AJAX action to load the environment details, so I marked it as a
JavaScript test, which would cause it to use Capybara&#8217;s Selenium driver.</p>

<p>The test passed fine on my machine (with Firefox 4 installed), but it failed
consistently on CI, which has Firefox 3.5. It kept failing with the exception
<code>Capybara::TimeoutError: failed to resynchronize, AJAX request timed out</code>. I
didn&#8217;t dig enough into the guts of Selenium/Firefox to find out exactly what
is going on (and a Google search for that error message turned up nothing that
really explained it) but I did at least find a workable fix. Just add the
following line to <code>spec/support/capybara.rb</code>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Capybara::Selenium::Driver::DEFAULT_OPTIONS[:resynchronize] = false</span></code></pre></td></tr></table></div></figure>




<!-- more -->


<p>Now, I can&#8217;t guarantee that this won&#8217;t have a negative effect further down the
line, but it works for my smoke-test. The <code>resynchronize</code> option must be using
something that is only available in later versions of Firefox.</p>

<p>Obviously the better solution would be to upgrade Firefox on our build-agents.
Unfortunately there isn&#8217;t a Firefox 4 RPM available for the Linux
distribution/version that those machines are using, and our sysadmin doesn&#8217;t
have any room on his plate to come up with a custom solution. Also, we have an
older application that still uses Webrat/selenium-rc, and I don&#8217;t believe that
supports Firefox 4 yet.</p>

<p>I&#8217;d love to see any comments or pointers to information that would help me
understand exactly what that resynchronize option is doing, especially if
someone knows why turning it off could be a Very Bad Thing™.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Apprenticeship Program at Renewable Funding - Thoughts?]]></title>
    <link href="http://johnwilger.com/blog/2011/03/04/apprenticeship-program-at-renewable-funding-thoughts/"/>
    <updated>2011-03-04T16:09:00-08:00</updated>
    <id>http://johnwilger.com/blog/2011/03/04/apprenticeship-program-at-renewable-funding-thoughts</id>
    <content type="html"><![CDATA[<p>The <a href="http://renewfund.com">Renewable Funding</a> technology team is moving into
some new office space in a few months, and now that we&#8217;ll have our own space,
I&#8217;d like to start up a variation on an apprenticeship program at work.  I&#8217;m
still in the early stages of designing this, and I want to gather some input
from the community before deciding how we might run the program.</p>

<!-- more -->


<p>My goals for this program are as follows:</p>

<ul>
<li><p>Contribute back to the local and global software development communities by
providing mentoring, a place to work, and stewardship of one or more
open-source projects.</p></li>
<li><p>Provide a safe, open, fun environment for people of all backgrounds to
improve their skill in a non-competitive, supportive learning environment.</p></li>
<li><p>Increase local knowledge about Renewable Funding&#8217;s software development
team, so that when we post job openings, you all know who we are.</p></li>
<li><p>Identify local developers who—while they may not have a lot of
experience—have a lot of talent and passion, so that we know who to talk to
when we have appropriate positions open up.</p></li>
</ul>


<p>Here&#8217;s what I&#8217;m thinking as a starting point, please let me know what might not
work, and what might work better:</p>

<ul>
<li><p>Recruit a group of between 2 and 6 local developers who are interested in
participating in the program for N months. (What is an appropriate time
period?)</p></li>
<li><p>The group gets together at our office one evening per week for the duration
of the term. (Thursdays from 4pm-8pm? Is once per week the right frequency?)</p></li>
<li><p>At least one senior developer from my team will be at each session to coach
and mentor the team. Renewable Funding will pay for dinner and/or snacks.</p></li>
<li><p>The group will decide on an open source project to work on. It could be a
new creation or contributions to an existing project.</p></li>
<li><p>The group will work on project following an agile methodology similar to
what we employ during our daily work at Renewable Funding.</p></li>
<li><p>We <em>may</em> be able to open our office to participants during regular work
hours to provide a space to work and access to individual mentoring.</p></li>
</ul>


<p>So, is this a good idea? Would anyone be interested in this? Am I overlooking
some obvious and potentially disastrous outcome?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Production Release Workflow with Git]]></title>
    <link href="http://johnwilger.com/blog/2011/01/08/production-release-workflow-with-git/"/>
    <updated>2011-01-08T20:54:00-08:00</updated>
    <id>http://johnwilger.com/blog/2011/01/08/production-release-workflow-with-git</id>
    <content type="html"><![CDATA[<p>After growing the <a href="http://www.projectdx.com">ProjectDX</a> team from three to
eight software developers, our release process was a complete pain, and it
typically took two to three hours to get a good build on the production branch
(and even then some insidious issues would sneak through). By making a few
changes to our development and acceptance process, we were able to turn it
into a five-minute, low-stress job.</p>

<!-- more -->


<p>A couple of years ago, our team was much smaller. We had around three
full-time developers working on the code, and we would all commit our
work-in-progress to the master branch in our <a href="http://git-scm.com/">git</a>
repository and push those commits out when we had a set that made sense to
share with the other developers. With only a few developers, we would usually
be working on one feature at a time, and once a small number of features were
accepted and ready, we could go ahead and release them to production. This
worked pretty well at the time, and when we <em>did</em> have a merge conflict, we
were all familiar enough with what was being worked on to be able to work it
out reasonably.</p>

<p>In 2010, the ProjectDX team was acquired by <a href="http://www.renewfund.com">Renewable
Funding</a>. Among other things, this gave us both the
resources and the need to grow the team beyond just a few developers. I took
over management of the software development team, and within several months
had hired three new developers and then added 2-3 contract developers to the team
at any given time. It&#8217;s no big surprise that increasing the size of a team by
a factor of three in a six month period is going to have some challenges, and
one of those was how the flow of work through the system needed to
change.</p>

<p>At first, we didn&#8217;t change anything about that process (I prefer not to change
things before I have any idea what the real problems are going to be).
Developers still committed work to the master branch, and that branch was
deployed to our internal alpha server by our automated CI system if and when
all of the tests passed. When the developers working on a feature felt that it
was complete, they put it up for acceptance, and the product owner verified
the feature on alpha before either accepting or rejecting the work. However,
our increased capacity meant that more individual features were worked on at
any given time, and this parallel development ran up against some shortcomings
in our process.</p>

<p>Our release cycle is once every two weeks. We plan our work into two-week
sprints, and a feature isn&#8217;t considered &#8220;done&#8221; until it is accepted by the
product owner <em>and</em> actually released to production. The problem we ran into
was that—on occasion—a feature planned for a sprint would not be accepted in
time for that sprints&#8217;s production deployment. This caused problems putting
together the production release. For example, let&#8217;s say the team worked on
Feature A and Feature B during the sprint. Feature A gets accepted and is
ready to release, but there are some issues with Feature B that mean we are
not going to put it in production this time around. Since we worked on both
features at the same time, the commit log on the master branch contained a mix
of commits for both features and looked like:</p>

<ul>
<li>A</li>
<li>A</li>
<li>B</li>
<li>A</li>
<li>B</li>
<li>A</li>
<li>A</li>
<li>B</li>
<li>B</li>
</ul>


<p>When it came time to put together the release, we only wanted to take the
commits for the accepted feature and merge them into the production branch. This
meant that someone would have to go through the commit logs, find the relevant
commits, and cherry-pick them into production one at a time. First problem:
that&#8217;s a mind-numbing chore for whoever is tasked with it.</p>

<p>Now imagine that—even if there are no inherent dependencies between Feature A
and Feature B—there are changes made in one of the early commits for Feature B
to a commonly used area of the code. Then, in the further work on Feature A,
the code is written in such a way that depends on this new behavior added by
Feature B&#8217;s commits. Not a problem if both features get approved for the
release, but it does become an issue when only Feature A makes it to
production. At that point, the person tasked with putting together the
production branch ends up with failing tests and—possibly—a merge conflict.
It&#8217;s especially fun when that person didn&#8217;t actually work on the changes
involved.</p>

<p>That&#8217;s bad enough; but it gets worse. It&#8217;s not as if we stop working on
Feature B just because it doesn&#8217;t get accepted for this release. The people
working on it continue to do so, and the est of the team starts work on
Feature C. By the end of the sprint, we have a commit log on the master branch
that looks something like:</p>

<ul>
<li>A</li>
<li>A</li>
<li>B</li>
<li>A</li>
<li>B</li>
<li>A</li>
<li>A</li>
<li>B</li>
<li>B</li>
<li>C</li>
<li>B</li>
<li>C</li>
<li>B</li>
<li>B</li>
<li>C</li>
<li>C</li>
</ul>


<p>Luckily, both B and C get accepted this sprint, so we can cherry-pick both of
these into production, and everything should be fine, right?</p>

<p>Well, the production branch now looks like this:</p>

<ul>
<li>A</li>
<li>A</li>
<li>A</li>
<li>A</li>
<li>A</li>
<li>B</li>
<li>B</li>
<li>B</li>
<li>B</li>
<li>C</li>
<li>B</li>
<li>C</li>
<li>B</li>
<li>B</li>
<li>C</li>
<li>C</li>
</ul>


<p>Notice an issue there? The production branch contains all of the same commits
as the master branch, but now they are applied in a different order. In
practice, this led to some <em>very interesting</em> merge conflicts. In
some cases, it didn&#8217;t lead to conflicts that git was able to detect, but it
caused some defects to appear in production that were not present during our
internal acceptance process (performed against the master branch).</p>

<p>After a couple of &#8220;releases from hell&#8221;, it was apparent to the whole team
that this was a problem that we needed to solve. We put our heads together and
came up with a solution that has been working great for us in the several
months since adopting it.</p>

<p>The first change is that we no longer have the whole team committing
work-in-progress to master. Whereas we used to have a master branch that
contained the main line of development and a production branch that only
contained work that was in (or ready to go to) production, we decided to turn
that on it&#8217;s head a bit. We made the decision that the master branch wasn&#8217;t
really all that important, and that the production branch was the most
critical part of the system. Regardless of what undeployed work might be in
commits on the master branch, the production branch is what is &#8220;real&#8221; and
&#8220;permanent&#8221;. If you want to keep feature development independent from work on
other features, the production branch is the one thing you can rely on not
changing prior to the next production release.</p>

<p>Now, that&#8217;s all well and good, but I&#8217;d have to cut a corner off my agile
practitioner&#8217;s card if I suggested that we based each feature off of the
production branch and didn&#8217;t integrate them until the end of the sprint.
On the other hand, we don&#8217;t want to change the production branch until we&#8217;re
ready for a release (in case we need to push out an emergency, mid-cycle
release to fix a critical defect.)</p>

<p>The challenge was to come up with a workflow that would protect the &#8220;actually
in production&#8221; nature of the production branch while making sure we didn&#8217;t
fall into the trap of &#8220;big bang integration&#8221; at the end of the sprint.
In order to meet these goals, at the beginning of every sprint we
create a new branch based off of the production branch called sprint-N (where
N is the number of that sprint). Each feature that is being worked on during
that sprint also gets its own branch, and the feature branch is based off of the
sprint branch.</p>

<p>When a feature is ready for acceptance, the developer in charge of the feature
will deploy the code from our feature branch to the alpha environment for the
product owner to review. The product owner is able to review that feature in
isolation from all of the other work in progress. This gives him confidence
that—even if this were the only thing we got done this sprint—it would behave
the same way in production.</p>

<p>If the product owner rejects the feature, the developers go back to working on
it, and no other features are directly impacted. If the product owner accepts
the feature, then and only then does the feature branch get merged into the
sprint branch (we use <code>git merge --squash</code> so that the changes for the feature
show up as a single commit in the sprint branch). After the changes are merged
in, the rest of the team is notified that the sprint branch has been updated,
and all other in-progress feature branches are rebased onto the new HEAD of
the sprint branch. (For those not familiar with git, rebasing—in layman&#8217;s
terms—means rewriting history such that all of the commits made only to the
feature branch will be applied <em>after</em> any changes that appear on the sprint
branch, regardless of the actual chronological order of those commits.)</p>

<p>With this system, we make sure that no feature has any unintentional
dependencies on work that may not be accepted, because the sprint branch
<em>only</em> contains code that is actually in production plus already accepted work
that will go out in the next release. At the same time, because changes are
merged into the sprint branch as soon as they are accepted, we are able to
test integration at the earliest practical point in time. When the developers
working on other features rebase their branches onto the new sprint branch,
they deal with any actual or semantic merge issues at that time. That way, the
people most familiar with the changes are able to resolve the conflicts while
those changes are still fresh in their minds.</p>

<p>We use TeamCity to run our automated, continuous integration. TeamCity runs
tests whenever it detects changes to either the sprint branch or the
production branch. Additionally, we can easily clone the build configuration
and have it run against the branch for a particular feature. We don&#8217;t do so
for every feature, but we use that capability for larger features that need to
integrate the work of multiple pair-programming teams.</p>

<p>When the end of the sprint arrives, updating the production branch is as
simple as <code>git checkout production &amp;&amp; git merge sprint-N</code>. Since the sprint
branch was created directly from the production branch and only contains
accepted work, this is always a simple, fast-forward merge. We tag the
production branch with the release number and deploy that to our staging
environment for a final once-over before delivering to production.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Found: Old Posts]]></title>
    <link href="http://johnwilger.com/blog/2010/12/19/found-old-posts/"/>
    <updated>2010-12-19T03:08:00-08:00</updated>
    <id>http://johnwilger.com/blog/2010/12/19/found-old-posts</id>
    <content type="html"><![CDATA[<p>And in other exciting news, I found a bunch of my old blog posts archived in
Google Reader that go back to before I effed up and lost the repository that
this site used to be stored on. I&#8217;m going to add many of them back to the
archives. While I will go through and fix the egregious encoding errors, I&#8217;m
probably not going to restore old hyperlinks that are getting lost in the
cut-n-paste.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[What it Really Means to be "Agile"]]></title>
    <link href="http://johnwilger.com/blog/2010/12/15/what-it-really-means-to-be-agile/"/>
    <updated>2010-12-15T10:00:00-08:00</updated>
    <id>http://johnwilger.com/blog/2010/12/15/what-it-really-means-to-be-agile</id>
    <content type="html"><![CDATA[<p>Yesterday, Elizabeth Hendrickson posted her <a href="http://testobsessed.com/2010/12/14/the-agile-acid-test/">Agile Acid
Test</a> in which she asks
three questions to determine whether or not a team is truly &#8220;agile&#8221;. There is
also the <a href="http://agilemanifesto.org/">Agile Manifesto</a> which describes the
values that an agile team should adhere to. While there is nothing that I
disagree with in either Elizabeth&#8217;s post or the Agile Manifesto, there
are two simpler questions you can ask that get to the heart of whether or
not your team is agile: <em>Can you react immediately and without panic when
external constraints on your project are changed</em>, and <em>does your team regularly
and frequently review its processes to ensure the answer to the previous
question is always &#8220;yes&#8221;?</em></p>

<!-- more -->


<p>If you can answer yes to both questions, then your team is agile. Whether you
use XP, Scrum, Lean, Waterfall or any other process or mix of processes doesn&#8217;t
matter at all for the purpose of determining agility; these processes may help
you deliver software that meets stakeholder needs in a timely fashion (or they
may not), but no single one of them is &#8220;the right way&#8221;.</p>

<p>Note that I don&#8217;t ask about delivered value or sustainable pace. It&#8217;s not my
intent to discount the importance of either of these things <em>in general</em>; I do
not, however see them as a strict requirement of agility, per se. Granted, if a
team isn&#8217;t able to do both of these things, that team probably will not be
successful in the long run, but if the team asks itself the two questions I
propose, then the other things are likely to fall into place naturally. (When I
say team, I am talking about the whole organization—it is critical that the team
is empowered to make changes that can affect its answers to these questions, so
the management needs to be part of the process.) Both the Agile Manifesto and
Elizabeth&#8217;s questions address qualities that are typically evident in truly
agile teams, but the essence is that a team is able to <em>react quickly</em> to whatever
is thrown at it and is able to <em>react differently</em> to changing situations.</p>

<p>Most software development methodologies start out as experiments that worked for
one team, got introduced to others and managed to gain successes and proponents.
Then somebody puts a label on it and writes down the definition of what it means
to do, say, Scrum. Now we have a neat list of things that a consultant can point
to and say &#8220;yes, you are doing Scrum&#8221; or &#8220;no, that&#8217;s not Scrum&#8221;. This recipe for
Scrum is now ready to ship off to other development organizations, and if only
they perform the recipe just the way it&#8217;s written down, everything will be fine.</p>

<p>Right&#8230;</p>

<p>A tangent: My wife and I both love to cook. One of my favorite celebrity chefs
is Alton Brown—he is, in fact, singularly responsible for my move from viewing
cooking as &#8220;something you had to do occasionally if you wanted to eat&#8221; to being
something I actually enjoy doing. The reason for this is simple: he doesn&#8217;t just
give you a recipe, he gives you the tools you need to reflect on what you&#8217;ve
done and understand why a dish did or did not turn out the way you expected.
That way you know what to do differently next time as opposed to assuming you
can&#8217;t make that particular recipe work and giving up on it.</p>

<p>The promotion of various &#8220;agile&#8221; methodologies as connect-the-dots exercises is
the biggest failing of the agile software development movement. A methodology
gains enough popularity that an organization&#8217;s management (or often the
developers themselves) decide to adopt that methodology in order to take
advantage of the benefits of &#8220;agile&#8221;.  They follow the process to the letter for
one or two releases, but they don&#8217;t meet the goals of the organization, write
off &#8220;agile&#8221; as something that won&#8217;t work for them and go back to old patterns
that are perceived to work at least a little bit better for them. Meanwhile, the
consultants and trainers have moved on to greener pastures with the occasional
tweet about &#8220;#notscrum&#8221;.</p>

<p>I much prefer the approach of those like Diana Larsen of <a href="http://futureworksconsulting.com/">FutureWorks
Consulting</a> and co-author of the excellent
book <a href="http://pragprog.com/titles/dlret/agile-retrospectives">Agile
Retrospectives</a> who—while
promoting agile methodologies—stresses the importance of an organization
reflecting on what it has achieved, what it has failed at, and in both cases
<em>how and why</em> it has done so. She will then challenge that organization to find
the next steps it can take to get closer to meeting it&#8217;s goals.</p>

<p>With such an approach, a team that is new to agile software development may
start out with a by-the-book Scrum implementation, but after several iterations
of delivery, retrospective and process modification, that team may or may not
have a process that still resembles Scrum. As long as that team is able to
answer yes to my two questions, they may be &#8220;#notscrum&#8221;, but they can hardly be
called &#8220;#notagile&#8221;.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Kinda, Sorta Fixed It]]></title>
    <link href="http://johnwilger.com/blog/2010/12/04/kinda-sorta-fixed-it/"/>
    <updated>2010-12-04T21:18:00-08:00</updated>
    <id>http://johnwilger.com/blog/2010/12/04/kinda-sorta-fixed-it</id>
    <content type="html"><![CDATA[<p>I finally got fed up with the fact that the post dates were wrong (you know, for
the 3, pointless entries that were even here.) I also realized that I have no
desire to try to wedge my content into that stupid, liquid templates system. It
might be useful when you want non-programmers to edit a site&#8217;s layout, but it&#8217;s
too limiting when I could just use plain-old Ruby code.</p>

<p>So, I gave toto the boot and am hand-rolling something simple. Yes, I know there
are a few other weblog tools out there that would give me the simplicity of
editing locally in vim using a markdown-formatted file, but I guess I&#8217;m
suffering from a bit of not-invented-here at this point after trying a couple
and finding them severely flawed when it comes to the way I want to work with
them.</p>

<p>Frankly, I also needed an outlet for hacking on something that didn&#8217;t have to be
useful to anyone other than myself. The amount of time I&#8217;ve been able to spend
just writing code had decreased substantially since I took on management of the
<a href="http://projectdx.com">ProjectDX</a> team at the beginning of the year.</p>

<p>Now that posting isn&#8217;t a complete pain in the rear <em>and</em> the dates will show up
correctly, I&#8217;m hoping I might actually bother to write a blog post once in a
while. Based on historical evidence, I wouldn&#8217;t hold my breath if I were you.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Blog Dates]]></title>
    <link href="http://johnwilger.com/blog/2010/06/11/blog-dates/"/>
    <updated>2010-06-11T00:00:00-07:00</updated>
    <id>http://johnwilger.com/blog/2010/06/11/blog-dates</id>
    <content type="html"><![CDATA[<p>For whatever reason, the combination of Toto, Heroku and/or my implementation
seems to cause every post here to have it&#8217;s post-date updated to something
approximating the current date. Given that I haven&#8217;t exactly been creating a
lot of content on this site lately (and lost years worth of posts not too long
ago), I hadn&#8217;t noticed this problem until the other day. To be honest, I&#8217;m not
sure if I really feel like putting forth the effort to fix it given everything
else going on in my life these days.</p>

<p>Part of me wonders why I keep this site up and running at all. I tend to make
public statements in 140-character increments these days. Twitter has killed
the casual blog.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[New Job (Sort Of)]]></title>
    <link href="http://johnwilger.com/blog/2010/02/14/new-job-sort-of/"/>
    <updated>2010-02-14T00:00:00-08:00</updated>
    <id>http://johnwilger.com/blog/2010/02/14/new-job-sort-of</id>
    <content type="html"><![CDATA[<p>The big news in my life right now is that the company I work for just went
through a merger, so TSSI is no more, and <a href="http://projectdx.com">ProjectDX</a> is
now part of <a href="http://renewfund.com">Renewable Funding</a>. I decided to accept the
offer presented by the new owners&#8211;and it came with a bit of a promotion&#8211;so
I am now Software Development Manager and responsible for guiding and growing
the Portland development team.</p>

<!-- more -->


<p>Thankfully, even though Renewable Funding is based in Oakland, CA, there are
no plans to move our team down there. We&#8217;ll be staying in Portland and
continuing to work on the public-facing web application that provides
communities with tools to educate their residents about sustainability
programs and allow property owners to manage applications for
<a href="http://renewfund.com/pace/definition-history">PACE</a> financing
programs.</p>

<p>I&#8217;m looking forward to figuring out my new role as I step into a management
position. Although I&#8217;ve always been a natural leader&#8211;I&#8217;ve served as
technical lead on various teams and held a lot of influence over team and
process design in my consulting work&#8211;this is the first time I&#8217;ve been
responsible for personnel management and had people reporting to me in the
org-chart. I don&#8217;t pretend to know all there is to know about being a great
manager, but I have the benefit of some great mentors and a fantastic team to
start with. I&#8217;ve always done my best work when I&#8217;m thrown in just a bit over
my head, and this is definitely pushing my boundaries (especially when
combining the new responsibilities with navigating a merger).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Time for a Reset]]></title>
    <link href="http://johnwilger.com/blog/2010/02/06/time-for-a-reset/"/>
    <updated>2010-02-06T00:00:00-08:00</updated>
    <id>http://johnwilger.com/blog/2010/02/06/time-for-a-reset</id>
    <content type="html"><![CDATA[<p>Hello, World! (?)</p>

<p>I&#8217;ve had the decision to completely restart my website made for me. The
previous incarnation of my site was being generated via a post-commit hook in
a git repository that lived on a VM at Slicehost. I decided to shut down that
VM and move the website to a system that I didn&#8217;t have to maintain.
Unfortunately, I <em>thought</em> that I had the git repository mirrored on <a href="http://github.com/jwilger">my
GitHub account</a>, but apparently not.  I&#8217;m sure I
could come up with usable backups if I put forth enough effort, but let&#8217;s be
honest: thanks largely to <a href="http://twitter.com/jwilger">Twitter</a>, I had barely
updated the site in the last 2 years, and a lot of what was there was either
outdated or of no real value to anyone other than myself.</p>

<p>So here we go again. <strike>This time around, I&#8217;m just using <a href="http://pages.github.com">GitHub&#8217;s pages
feature</a> to publish the site. I don&#8217;t have to
maintain the server, and now I <em>know</em> that the repository is on my GitHub
account.</strike></p>

<p><strong>UPDATE</strong> I&#8217;m actually switching to using
<a href="http://github.com/cloudhead/toto">toto</a> with <a href="http://heroku.com">Heroku</a>. I
like toto better than jekyll, because I don&#8217;t have to put up with using the
Liquid page templating engine. Plain-old ERB FTW!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Retrospective Facilitation]]></title>
    <link href="http://johnwilger.com/blog/2009/01/13/retrospective-facilitation/"/>
    <updated>2009-01-13T00:00:00-08:00</updated>
    <id>http://johnwilger.com/blog/2009/01/13/retrospective-facilitation</id>
    <content type="html"><![CDATA[<p>I facilitated my second release retrospective with the ProjectDX team yesterday.
The first, back in October, went well enough given that I was asked to
facilitate at the start of the retrospective and had no time to prepare; but
yesterday&#8217;s retrospective went great since I knew ahead of time that I would be
facilitating.</p>

<!-- more -->


<p>The activities we used during the retrospective mainly came from Diana Larsen
and Esther Derby&#8217;s book, Agile Retrospectives. We started off with the &#8220;ESVP&#8221;
(Explorer, Shopper, Vacationer, Prisoner) activity to find out what the group&#8217;s
interest level was in relation to the work we were doing in the retrospective.
Nearly everyone in the group said they were an Explorer via anonymous vote. With
this group, I basically trust that outcome, although I did wonder if anyone may
have given the answer they thought they were &#8220;supposed&#8221; to give.</p>

<p>Next, I had the team build a time line of events from the past release. Prior to
the start of the retrospective, I drew the time line on our white board and
divided it into sections for each iteration (our cycle is 2 3-week sprints
followed by a 2-week, internal Alpha testing period and a 2-week customer Beta
testing period). The result looked something like:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>|----------|----------|-------|-------|
</span><span class='line'>| Sprint 1 | Sprint 2 | Alpha | Beta  |
</span><span class='line'>|          |          |       |       |
</span><span class='line'>|          |          |       |       |
</span><span class='line'>|          |          |       |       |
</span><span class='line'>|          |          |       |       |
</span><span class='line'>|          |          |       |       |
</span><span class='line'>|          |          |       |       |
</span><span class='line'>11/03 -----11/24 -----12/15 --12/29 --01/09
</span><span class='line'>|          |          |       |       |
</span><span class='line'>|          |          |       |       |
</span><span class='line'>|          |          |       |       |
</span><span class='line'>|----------|----------|-------|-------|</span></code></pre></td></tr></table></div></figure>


<p>During the retrospective, I had everyone take some time to think about any
events during that time period that were meaningful to them in any way, write
the event on a sticky note then stick the note on the time line in roughly the
right spot. We spent about 45 minutes generating events, during which time we
were free to look back at calendars and email as well as the commit logs from
our SCM. Having set the time box to 45 minutes, I said it was fine for people
to take a break if they felt like they couldn&#8217;t remember any more events and
asked everyone to simply be back on time for the next step.</p>

<p>Rather than specifying that people work in pairs, I opted to have the team
self-organize here. It was interesting to see how—at first—everyone seemed to
work on their own, but as the more obvious events were posted to the board,
people started working in groups to come up with more data. At the end of the
allotted time, we had a white board full of events.</p>

<p>The area below the time line was intended for a graph of energy/emotion levels,
which I&#8217;ll talk about in a moment, but JD Huntington had a great idea to also
add to that area a rough bar graph of our commit volume as reported by GitHub&#8217;s
activity graphs.</p>

<p>After everyone had a last opportunity to look at the board and add any
last-minute stickies, I asked everyone to take a turn at the board and use
markers to place a blue dot next to any event which they felt positive about and
a red dot next to any event that they felt negative about. Then, I asked them to
think about their positive and negative energy/emotion levels throughout the
release and draw a line graph in the bottom section to signify their ups and
downs throughout the release cycle. At this point, we looked at each iteration
in the cycle and I asked the team to make observations about the data. Using
bullet lists at the bottom of the white board, we captured the observations as
further data points for analysis.</p>

<p>After a break for lunch, we used the &#8220;Patterns &amp; Shifts&#8221; activity to generate
insights about the data on the time line. We gathered around the white board
where I asked each person to mark on the time line any point at which they felt
there was a shift or transition of some sort and to draw lines between any
events, graph points and observations that they felt were somehow related.</p>

<p>After no one was able to see any more connections, I asked the team to look for
any patterns among the connections and the shifts. The first thing we noticed
was that we felt like the real shift between iterations was constantly happening
about 3 days after the actual time box ended. Rather than get into a long
discussion about it when it was noticed, I asked the team to simply keep it in
mind as a possible concern during the next phase of the retrospective.</p>

<p>The next observation was that we had a number of connections with long lines
spanning two or more iterations. I asked everyone to focus on these connections
and look for those where we may have noticed an issue early on but it wasn&#8217;t
addressed until much later. In some cases it turned out that while that was the
issue, the length of the line just signified that either the work took that long
or there was a conscious decision not to address the issue right away.</p>

<p>Reflecting on the other cases led to an interesting discovery, however. Chris
noticed that where the lines crossed the bounds of the iterations it was likely
signifying a parallel cycle which we were attempting to force into our release
cycle: specifically, we have both an explicit product release cycle and an
inexplicit customer deployment cycle occurring at the same time.</p>

<p>After we were finished recognizing patterns in the data, it was time to discuss
these patterns (and anything else on our minds) and come up with a few action
items for the next release cycle. Here I ran the team through the &#8220;Circle of
Questions&#8221; activity. In this activity, the group sits in a circle, and each
person takes turns asking a question to the person on their immediate left. The
question can be about anything they like (barring anything offensive or
attacking), but it&#8217;s helpful to focus on the insights gained during the previous
stage of the retrospective. The person to the left answers the question to the
best of their ability, and then they ask the person to their left any other
question (or the same question if they feel they&#8217;d like a better answer). This
continues until the alloted time is up or you have gone around the entire circle
twice, whichever comes last. Make sure you go around the complete circle: if
some people in the group get more turns to ask or answer a question than others,
it can send the wrong message.</p>

<p>The thing that I really like about the Circle of Questions activity is that when
you have a mixed group of people—some of whom tend to dominate the conversation
while others tend to stay quiet—it gives everyone a chance to ask their
  questions and have their opinions heard without feeling like the most
  boisterous people have the only valuable input. We certainly have a mix like
  that in our case, and this activity worked wonderfully.</p>

<p>In the end, we came away with a number of things to change for the next release
cycle. It&#8217;s interesting to note that none of our action items were directly
related to the insights generated from the time line. I think the insights are
still valuable (and are contained in the notes which we post to our internal
wiki), so we may still come back to them in the near future; we were running
over on time and had to wrap up even though the discussion could have continued
longer.</p>

<p>Before we held this retrospective, I think some of the team members felt that we
would not gain much from doing a full-day retrospective this time around. We had
made good progress on our action items from the previous retrospective, and the
general feeling was that things were going basically well. What could we
possibly need to change?</p>

<p>People, please don&#8217;t hold retrospectives only when your team feels like there&#8217;s
a problem that needs to be dealt with. If you hold retrospectives on a regular
basis, whether you feel like you &#8220;need&#8221; to or not, you will uncover issues
before the become problems. In our case, we managed to uncover a number of
issues during our retrospective that could easily have grown into much larger
problems if we didn&#8217;t bother to think about them until the effect was obvious.</p>

<p>If you do have obvious issues, then you might choose a different set of
activities than what we did for this retrospective. The time line activity is
great for discovering potential improvements even when everything seems to be
going well, so I suggest giving it a try the next time your team is tempted to
skip a retrospective because no one thinks there&#8217;s any huge problems.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[2008 Year-End Review]]></title>
    <link href="http://johnwilger.com/blog/2009/01/01/2008-year-end-review/"/>
    <updated>2009-01-01T00:00:00-08:00</updated>
    <id>http://johnwilger.com/blog/2009/01/01/2008-year-end-review</id>
    <content type="html"><![CDATA[<p>Wow! Just&#8230;wow!</p>

<p>I can&#8217;t believe 2008 is already over. The older I get, the faster the years seem
to fly by; I&#8217;m not sure I like the trend. The effect mainly tells me that I need
to concentrate more on living my life intentionally, so that I have a better
memory of my everyday experiences.</p>

<!-- more -->


<p>That&#8217;s not to say that I don&#8217;t remember 2008—this has been a year of big changes
and lots of neat experiences. The year started off with a plan to take a job in
Dublin, Ireland and move the whole family over there with me. For various
reasons, that didn&#8217;t work out. We stayed in Portland where I opened up shop as
an independent consultant. Finally, after working with a number of wonderful
clients, I decided to accept a job offer from one of them; and I&#8217;m once again an
employee.</p>

<p>Probably my most important achievement of 2008 was to completely, 100% quit
smoking cigarettes. I had actually quit in the Fall of 2007, but I was using the
nicotine patch, and it took me longer than it should have to wean myself off of
it. But I did, and I&#8217;m now living completely nicotine-free.</p>

<p>I did not, unfortunately, stick to my exercise goals for the year. The new bike
I bought this summer with a plan to ride several time per week has only been out
of the garage a handful of times. In the Fall, I started the 100 Push-ups
program and added on sit-ups, leg curls and calf extensions. I was doing pretty
good for a few weeks, but then my schedule got thrown off when Misty went out of
town, and I never got back on track. Boo.</p>

<p>Of course, no 2008 year-end review would be complete without a record of the
Snowpocalypse which descended upon us during the last half of December. It
almost never snows on the valley floor in Hillsboro or Portland. This year it
not only snowed, but it stuck. We had well over a foot of accumulation by the
house along with a half inch of ice. Since we&#8217;ve no infrastructure for clearing
the roads, everything basically shut down. Of course, I enjoyed the hell out of
it, because it gave me a chance to put the Jeep in 4-lo once or twice.</p>

<p>This was definitely a prosperous year for our family, and we&#8217;ve been able to do
a number of fun extra things such as pay for my friend, Quentin Baker, to fly
out for a few days this fall and for my dad and his wife to come out for a week
during Christmas. We&#8217;re debt free except for two car payments, and we&#8217;re
hopefully in a good position to weather the current problems with our economy.</p>

<p>2009 looks like it could be another year of changes. It&#8217;s definitely going to be
a big change for our country as our new president takes office. Hopefully I&#8217;ll
be able to bring some more positive change to my individual life as well. I plan
to spend some time tomorrow thinking about my goals and resolutions for the next
year.</p>

<p>For now, good-bye 2008 and happy new-year!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Switched to Jekyll]]></title>
    <link href="http://johnwilger.com/blog/2008/12/21/switched-to-jekyll/"/>
    <updated>2008-12-21T00:00:00-08:00</updated>
    <id>http://johnwilger.com/blog/2008/12/21/switched-to-jekyll</id>
    <content type="html"><![CDATA[<p>If you&#8217;re seeing this, then you see that I&#8217;ve stopped hosting my blog on Blogger
and am now using a slightly modified Jekyll. Jekyll is the engine that powers
GitHub&#8217;s recently announced &#8220;pages&#8221; feature.</p>

<p>I&#8217;m not hosting on GitHub, though. I simply installed Jekyll on the cheapest VPS
from Slicehost, set up a git repository on that server to hold the contents of
the site and then slapped together a simple post-update hook script for git that
automatically publishes the site when I commit changes.</p>

<p>The changes also come with a new design.</p>

<p>Dragons are cool, so I am cool.</p>

<p>The stylesheets obviously aren&#8217;t fleshed out yet, so everything pretty much
looks like crap. I plan to have it fixed up real soon.</p>

<p>Also need to slap together a new Atom feed for the posts.</p>

<p>All worth it, since I can now easily compose my posts in Vim using markdown
syntax and have them stay editable in that format. Maybe now I&#8217;ll actually post
more than once every couple of months. :-)</p>
]]></content>
  </entry>
  
</feed>

