h

Being Agile

Pete Hodgson's blurgh

Tutorial Screencast on Frankifying Your App

| Comments

I maintain Frank, a tool which lets you write automated acceptance tests for your iOS app using Cucumber. I’ve been trying to reduce the hurdles in getting started with Frank. My latest attempt is to record a tutorial screencast showing how to take your existing app and ‘Frankify’ it.

‘Frankifying’ an app is the process of adding a separate Frank target to your app which has the Frank server embedded into it, allowing it to respond to automation commands. It can seem like a bit of an intimidating process at first glance, but it’s actually very simple. Hopefully running through the whole process in a 7 minute screencast demonstrates that.

Derek Longmuir has also contributed a nice in-depth tutorial writeup (which I was following along with when I recorded the screencast).

Working With Indirect Input and Output in Unit Tests

| Comments

Testing how a unit of code interacts with its environment

When testing a unit of code you need to both observe how the unit of code is interacting with the outside world and also control how the world interacts with it.

In a particuarly simple example, you might want to check that when an adder function is given a 2 and a 4 then it returns a 6. In this case you’re controlling what the System Under Test (SUT) pulls in from its environment (the 2 and the 4) and also observing what it pushes out (the 6). In a more sophisticated example you might be testing a method which talks to a remote service, verifying that if it receives an error code when trying to read from the network then it logs the appropriate error message to a logger. Note that we’re still doing essentially the same thing here - controlling what the SUT pulls in from the environment (an error code in this case) and observing what it pushes out (a call to a logger in this case).

These two examples both illustrate the same fundamental practice of controlling input and observing output, but they are dealing with different kinds of input and output. In the first example of the adder function we are controlling the Direct Input provided to the SUT, and observing the Direct Output. In the second example we are controlling Indirect Input and observing Indirect Output (these terms are courtesy of the quite great XUnit Test Patterns book).

Four categories of inputs and outputs

As you can see, direct input and output is so called because it is provided directly to the SUT by the unit test. On the other hand, Indirect Input and Output can only be controlled and observed indirectly, via the SUT’s dependencies (aka Depended Upon Components). In one of the previous examples we were testing some code which needed to talk to a remote service. In that case the SUT would have had a dependency on some sort of lower level network service. We used this dependency to inject Indirect Input in the form of an error code being returned when the network service was called. Our SUT also had a dependency on some sort of logging service. We used that dependency to observe Indirect Output by checking that a logging method was called with the logging information we expect in the circumstances we simulated using the Indirect Input of an error coming back from the network service.

How do we manage indirect input and output?

We control indirect input and measure indirect output within our Unit Tests by using Test Doubles. This term encompasses the test-specific doohickeys commonly referred to as Mocks and Stubs, as well as the more esoteric variants such as Spies, Dummies, Fakes, etc.

In my personal opinion the vocabulary for these things is pretty confusing, and the definitions do not appear to be universally agreed upon and consistent. Also, I don’t often find myself too concerned with the implementation-specific differences which for some definitions serve to distinguish between e.g. a Stub vs a Mock. To me a much more important distinction is in what role a specific Test Double is playing in the test at hand. Is it helping to inject Indirect Input, or is it helping to observe Indirect Output? Or is it simply there to replace a required dependency for which we don’t want to use a real implementation? In an ill-advised mixing of terminology, I categorize these roles as Mocking, Stubbing, or Faking. I know this aligns quite poorly with other definitions for these terms, but they’re the best I have for now.

Test Double Roles

Stubbing

This refers to using a Test Double to control your SUT by providing specific Indirect Input. For example, you might supply your SUT with a testing-specific implementation of a Car repository which you have pre-configured to return a specific Car instance. This Car instance would be the indirect input which you are providing to your SUT. Another classic example would be injecting a fake Clock into your SUT so that you can test how it behaves at 1 second before midnight, or on February 29, or on December 21 2012.

Mocking

This refers to using a Test Double to observe some piece of Indirect Output produced by your SUT. Perhaps you’re creating a system that lets people tweet messages to the Jumbotron at a baseball game, and you need to make sure that you filter the tweets for naughty words. You could supply your SUT with a mock implementation of a RudeWordFilter class, and check that its filtering methods are being called correctly.

Faking

A Faking Test Double is one which is just being used to satisfy the SUT’s dependencies, and which is not being used to provide Indirect Input or to observe Indirect Output. Maybe the method you’re testing writes entries to a logger as it goes about its business. Your current test doesn’t care about this behavior, so you provide a Null Object implementation of the Logger to the SUT. This Null logger will simply ignore any logging methods which are called on it. Note that I emphasized that the current test wasn’t interested in how the SUT uses the logger. Other tests likely would be, and in those tests the Test Double which provides the Logger dependency would likely play a Mocking role rather than a Faking role.

Test Double Roles vs Test Double Implementation

It’s important to note here that the way in which these Test Doubles are implemented is orthogonal to the role they are playing. You can use a ‘mocking framework’ (e.g. Mockito, JMock, Typemock, EasyMock) both to supply Indirect Input and to observe Indirect Output. On the other hand you could just as well use hand-written classes (sometimes referred to as stubs) to achieve both these goals. This orthogonality between the technique you’re using to create your Test Doubles and the role a Test Double is playing is an important but subtle point, and is part of why I’m really not happy with the confusing terminology I have been using.

Acknowledgements

Lots of the ideas in this post are inspired by the patterns in the wonderful, encyclopedic XUnit Test Patterns book. It’s not exactly a 5 minute read, but nevertheless I highly recommend it. Most of the patterns in the book are also covered in very high-level overview form on the accompanying website, xunitpatterns.com.

I think my categorization of the Mocking, Stubbing and Faking roles lines up pretty closely with what Roy Osherove describes in his book, The art of unit testing, but I haven’t read the book so I can’t say that with any confidence.

Creating and Publishing Your First Ruby Gem

| Comments

Introduction

In this post I’m going to cover the basics of creating and publishing a gem using the bundle gem command provided by Bundler. We’re going to use bundler to create a gem template for us. We’ll then take that skeleton gem, add some functionality to it, and publish it for all the world to use.

For the purposes of this tutorial I need a very simple example of something which you could conceivably want to release as a gem. How about a simple Sinatra web app which tells you the time? Sure, that’ll work. We’ll call it Didactic Clock. In order to make this server implementation need more a couple of lines of code we’ll add the requirement that the clock tells you the time in a verbose form like “34 minutes past 4 o’clock, AM”.

Preparing to create a gem

A great way to create and test gems in a clean environment is to use the awesome rvm and in particular rvm’s awesome gemset feature. I assume you’re already set up with rvm. If not go get set up now!

First off we’ll create a seperate gemset so that we can create and install our gem in a clean environment and be sure that someone installing our gem will have all the dependencies they need provided to them. We’re going to be creating a gem called didactic_clock, so we’ll name our gemset similarly. We’ll create the gemset and start using it by executing:

 rvm gemset create didactic_clock
 rvm gemset use didactic_clock

From now on I’ll assume we’re always using this clean-room gemset.

Creating the skeleton

First lets install bundler into our gemset:

gem install bundler

Now we’ll ask bundler to create the skeleton of a gem. In this tutorial we’re going to be creating a gem called didactic_clock. We’ll ask bundler to create a skeleton for a gem with that name by calling:

bundle gem didactic_clock

You should see some output like:

  create  didactic_clock/Gemfile
  create  didactic_clock/Rakefile
  create  didactic_clock/.gitignore
  create  didactic_clock/didactic_clock.gemspec
  create  didactic_clock/lib/didactic_clock.rb
  create  didactic_clock/lib/didactic_clock/version.rb
Initializating git repo in /Users/pete/git/didactic_clock

Modifying our gemspec

Bundler creates a basic .gemspec file which contains metadata about the gem you are creating. There are a few parts of that file which we need to modify. Let’s open it up and see what it looks like:

 
   # -*- encoding: utf-8 -*-
   $:.push File.expand_path("../lib", __FILE__)
   require "didactic_clock/version"
 
   Gem::Specification.new do |s|
    s.name        = "didactic_clock"
    s.version     = DidacticClock::VERSION
    s.platform    = Gem::Platform::RUBY
    s.authors     = ["TODO: Write your name"]
    s.email       = ["TODO: Write your email address"]
    s.homepage    = "http://rubygems.org/gems/didactic_clock"
    s.summary     = %q{TODO: Write a gem summary}
    s.description = %q{TODO: Write a gem description}
 
    s.rubyforge_project = "didactic_clock"
 
    s.files         = `git ls-files`.split("\n")
    s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
    s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
    s.require_paths = ["lib"]
   end

You can see that Bundler has set up some sensible defaults for pretty much everything. Note how your gem version information is pulled out of a constant which Bundler was nice enough to define for you within a file called version.rb. You should be sure to update that version whenever you publish any changes to your gem. Follow the principles of Semantic Versioning.

Also note that there are some TODOs in the authors, email, summary, and description fields. You should update those as appropriate. Everything else can be left as is for the time being.

Adding a class to our lib

We’ll start by creating a TimeKeeper class which will report the current time in the verbose format we want the Didactic Clock server to use. To avoid polluting the client code’s namespace it is important to put all the classes within your gem in an enclosing namespace module. In our case the namespace module would be DidacticClock, so we’re creating a class called DidacticClock::TimeKeeper. Another convention which is important to follow when creating gems is to keep all your library classes inside a folder named after your gem. This avoids polluting your client’s load path when your gem’s lib path is added to it by rubygems. So taking both of these conventions together we’ll be creating a DidacticClock::TimeKeeper class in a file located at lib/didactic_clock/time_keeper.rb. Here’s what that file looks like:

 
    module DidacticClock
    class TimeKeeper
     def verbose_time
      time = Time.now
      minute = time.min
      hour = time.hour % 12
      meridian_indicator = time.hour < 12 ? 'AM' : 'PM'
 
      "#{minute} minutes past #{hour} o'clock, #{meridian_indicator}"
     end
    end
   end

Adding a script to our bin

We want users of our gem to be able to launch our web app in sinatra’s default http server by just typing didactic_clock_server at the command line. In order to achieve that we’ll add a script to our gem’s bin directory. When the user installs our gem the rubygems system will do whatever magic is required such that the user can execute the script from the command line. This is the same magic that adds the spec command when you install the rspec gem, for example.

So we’ll save the following to bin/didactic_clock_server

 
   #!/usr/bin/env ruby
 
   require 'sinatra'
   require 'didactic_clock/time_keeper'
 
   # otherwise sinatra won't always automagically launch its embedded 
   # http server when this script is executed
   set :run, true
 
   get '/' do
    time_keeper = DidacticClock::TimeKeeper.new
    return time_keeper.verbose_time
   end

Note that we require in other gems as normal, we don’t require rubygems, and that we don’t do any tricks with relative paths or File.dirname(__FILE__) or anything like that when requiring in our TimeKeeper class. Rubygems handles all that for us by setting up the load path correctly.

Adding a dependency

Our little web app uses Sinatra to serve up the time, so obviously we need the Sinatra gem installed in order for our own gem to work. We can easily express that dependency by adding the following line to our .gemspec:

s.add_dependency "sinatra"

Now Rubygems will ensure that sinatra is installed whenever anyone installs our didactic_clock gem.

Building the gem and testing it locally

At this point we’re done writing code. Bundler created a git repo as part of the bundle gem command. Let’s check in our changes to the git repo. git commit -a should do the trick, but obviously feel free to use whatever git-fu you prefer.

Now we’re ready to build the gem and try it out. Make sure you’re still in the clean-room gemset we created earlier, and then run:

rake install

to build our didactic_clock gem and install it into our system (which in our case means installing it into our didactic_clock gemset). If we run gem list at this point we should see didactic_clock in our list of gems, along with sinatra (which will have been installed as a dependency).

Now we’re ready to run our app by calling didactic_clock_server from the command line. We should see sinatra start up, and if we visit http://localhost:4567/ we should see our app reporting the time in our verbose format. Victory!

Publishing our gem

The last step is to share our creation with the world. Before we do that you’ll need to set up rubygems in your system to publish gems. The instructions at rubygems.org are easy to follow.

Bundler provides a rake publish task which automates the steps you would typically take when publishing a version of your gem, but it’s fairly opinionated in how it does so. The task will tag your current git commit, push from your local git repo to some upstream repo (most likely in github), and then finally build your gem and publish your .gem to rubygems.org. If you don’t have an upstream repo configured then you’ll probably get an error like:

   rake aborted!
   Couldn't git push. `git push  2>&1' failed with the following output:
 
   fatal: No destination configured to push to.

So, now would be the time to set up an upstream repo. Doing that with github is really straightforward. Once you have your local git repo configured with an upstream repo you can finally publish your gem with rake publish.

Now anyone who wants to install your gem can do so with a simple gem install command. Congratulations! Fame and fortune await you!

Conclusion

Hopefully I’ve shown that creating and publishing a well-behaved gem is pretty simple. The didactic_clock sample I created is up on github, and of course the gem is published on rubygems.org and can be installed with gem install didactic_clock.

Timestamped-scenarios, a Custom Cucumber Formatter

| Comments

I just published a new Ruby gem called timestamped-scenarios. As usual the code is also available on github.

What’s this gem for?

This gem provides custom cucumber formatters which append a test run timestamp to each scenario name as it is generated. a Timestamped::PrettyFormatter and Timestamped::HtmlFormatter are supplied already, but you can use the AddsTimestamp module to dynamically add timestamping to pretty much any Cucumber formatter.


You might wonder why I created these formatters. I’m currently working on an iOS project where we are using Frank and Cucumber to run automated acceptance tests against the application. We have integrated these acceptance tests into our CI build, and as part of that integration we record a screen capture movie of each test run. By adding timestamps to each scenario name we can easily skip to the part of the movie which shows that scenario executing. This is useful when trying to figure out the context around why a
specific scenario failed.


How do you use it?

As with my other cucumber formatter gem (slowhandcuke), getting set up with timestamped-scenarios is super easy. just install the gem with

gem install timestamped-scenarios
and you’re ready to use them by executing cucumber with something like
cucumber --format 'Timestamped::HtmlFormatter' --out cucumber.html
You can also add these parameters to your rake cucumber task, or to your cucumber.yml config file. There’s also a little sample project in the timestamped-scenarios repo on github which shows how to use the formatters.


What’s it look like?

Here’s an example of what the Timestamped::PrettyFormatter output looks like:


∴  cucumber 
Using the default profile...
Feature: demonstration

  Scenario: The First [0:00]      # the.feature:3
    Given I wait 5 seconds # step_definitions/steps.rb:1

  Scenario: The Second [0:05]       # the.feature:6
    Given I wait 0.7 seconds # step_definitions/steps.rb:1
    Given I wait 3 seconds   # step_definitions/steps.rb:1

  Scenario: The Third [0:09] # the.feature:10

3 scenarios (3 passed)
3 steps (3 passed)
0m8.709s

Objective C Memory Errors Pt II - Dangling Pointers

| Comments

In my last post I talked about memory leaks in Objective C. In this post I’ll take about the converse - dangling pointers. In iOS a dangling pointer happens when you maintain a reference to an object which has been deallocated. I’d say the most common cause is failure to take ownership of an object you intend to maintain a reference to. Another common cause is when an object is accidently released multiple times by the same owner, leading to its retain count dropping to 0 and the object being deallocated before all the objects which hold references to the object release those references.


I’m going to illustrate this first type of dangling pointer bug (failing to take ownership of a reference) and try to explain in detail the cause of the error and its effects. We’ll use a pedagogical Duck class similar to the one in my previous post:


@interface Duck : NSObject {
  NSArray *_feathers;
}
@end

We have a Duck which holds a reference to an array of feathers. We’d like to ensure that our Duck’s feathers array always points to a valid NSArray instance, so we set the reference to an empty array during construction:


- (id) init
{
  self = [super init];
  if (self != nil) {
    _feathers = [NSArray array];
  }
  return self;
}

Once again we have a memory bug here, but this time it’s the flip side of the memory management coin from a memory leak - a dangling pointer. Instead of failing to relinquish ownership of a reference we’re failing to take ownership. We are asking NSArray to create an instance using the [NSArray array] factory method, which does NOT transfer any ownership to the caller. This is explained quite clearly in Apple’s Memory Management Rules - if a method does not start with alloc, new or copy then the caller is not automatically granted ownership of the object, and should take that ownership explicitly by calling retain if it intends to maintain a reference to that object.


I’ll illustrate one scenario of how this bug could manifest itself:




1) In our init method we call [NSArray array] which creates an NSArray instance. The creator of the array inside the implementation of [NSArray array] has to keep ownership of the instance for a certain period of time, otherwise its retain count would drop to 0 and it would immediately be deallocated.


2) still in the init method, we update _feathers to refer to the array, but neglect to take any ownership of the array.


3) at some later point while Duck is still alive the creator (and sole owner) of the array instance relinquishes its ownership of the array instance, dropping the array’s retain count down to 0. This might be because it has been deallocated, or maybe it is replacing its reference to the array with something else, or some other reason.


4) The array’s retain count has dropped to 0, so it is immediately deallocated and its memory reclaimed for future use by the memory management system. Our Duck instance has no way of knowing this, and is still holding a reference to where the array used to be. This is the dangling pointer.


Subsequently when the Duck instance attempts to talk to that array it is going to find itself talking to some random object, or just to arbitrary junk data. Crashes will ensue… eventually.


Note that the sole owner of the array as shown in the diagrams would in a lot of cases be an autorelease pool. This is because the easiest way to handle memory management when implementing factory methods like [NSArray array] is to create the object to be returned using alloc, and then transfer ownership to the autorelease pool before returning the object, like so:


+ (NSArray *) array {
  return [[[NSArray alloc]init]autorelease];
}

What makes this kind of dangling pointer error particularly tricky is that in certain use cases it will not manifest at all. If the usage of Duck is such that it always goes out of scope before the NSArray instance is deallocated then no issues will be detected. This could happen if the Duck instance and the NSArray instance it references are both owned by the same autorelease pool, for instance. However, when the usage patterns of Duck change you could suddenly see errors - even if you haven’t changed the (buggy) implementation of the Duck class itself in months!


What should we have done?


Use an object creation method which implicitly grants ownership to the caller

- (id) init
{
  self = [super init];
  if (self != nil) {
    _feathers = [[NSArray alloc]init];
  }
  return self;
}

Use retain to explicitly take ownership


- (id) init
{
  self = [super init];
  if (self != nil) {
    _feathers = [[NSArray array] retain];
  }
  return self;
}

Common Objective-C Memory Management Errors, Part I

| Comments

I would say that the steepest learning curve for someone new to iOS development is having to manage your own memory using reference counting. Knowing when to retain and when to autorelease can seem like a black art until you understand the conventions which is used (extremely consistently, I might add) within Objective C libraries. Let’s examine one very common mistake, which I will call the Property Assignment Memory Leak. I’ve seen this a few times, and indeed committed this error myself during my first weeks of iOS development.

The code


Imagine we have a simple Duck class, which holds a feathers array:


@interface Duck : NSObject {
  NSArray *_feathers;
}
@property (nonatomic,retain) NSArray *feathers;
@end

@implementation Duck
@synthesize feathers=_feathers;
@end

during construction we’d like to initialize this array, so we create an init method as follows:
- (id) init
{
  self = [super init];
  if (self != nil) {
    self.feathers = [[NSArray alloc] init];
  }
  return self;
}
Of course, we need to make sure we release our ownership of the feather array during deallocation, so we’ll add a dealloc method like so:
- (void)dealloc {
  self.feathers = nil;
}

The Leak

So we’re good here, right? The observant reader will note that no, we’re not. the feathers array which we created in our init method will never be released. This will be a little easier to explain if I refactor the init method a little, making it more verbose by introducing a local variable to hold the array we are about to assign to the self.feathers property:

- (id) init
{
  self = [super init];
  if (self != nil) {
    // alloc will always create an object with a retain count already set to 1. In other 
    // words, tempArray has ownership of the object.
    NSArray *tempArray = [[NSArray alloc] init]; 

    // assigning to self.feathers bumps the array's retain count up to 2. In other words, 
    // now the feathers property also has ownership of the object.
    self.feathers = tempArray; 
  }

  // when we return tempArray goes out of scope without ever releasing ownership of the object it created. Memory leak!
  return self;
}

To make this clearer, I’ll try and illustrate what happens as we move through the Duck object’s lifecycle.

1) Here an instance of Duck has just been alloced, and we’re about to execute init.


2) We create an array, and assign it to the local tempArray variable. Note that any objects created with alloc will already have a retain count of +1 when alloc returns.


3) We assign the array to the feathers property. Because the property has retain semantics it will take ownership of the array, incrementing its retain count to +2.


4) We’ve now left the init method, and so the local tempArray variable has gone out of scope. However, it never released ownership of the array before it went out of scope, so the retain count is still +2.


5) After using our Duck instance for some time it is eventually deallocated, at which point its dealloc method is called. We do the right thing and set its feather property to nil during dealloc. Again, the feather property has retain semantics and therefore it will release ownership of whatever it is currently pointing to just before taking ownership of whatever it is being asked to point to. It was pointing to our array, and is now pointing to nil, so it releases ownership of the array (dropping its retain count down to +1), and takes ownership of nil (which has no effect whatsoever).


6) Finally, our Duck instance is fully deallocated, and disappears. But our array instance still has a retain count of +1, even thought nothing is referencing it. Memory leak!



While I showed the entire lifecycle for a Duck instance here I should note that the bug is in the init method, and once that method returns the damage has been done. The fact that after init returns the array instance only has 1 reference pointing to it but has a retain count of 2 is indicative of that. I wanted to show the entire lifecycle to demonstrate that the point at which a memory leak is introduced will likely be quite far away from the point where the leak is detected. This is important to know when using Instruments or some other tool to try and detect leaks at runtime.

I think that the most common cause of this particular memory leak bug is an unclear understanding of how properties work. It is hard at first glance to see how assigning an object pointer to self.foo is different than assigning that pointer to a local variable. Once you grok that that property assignment also assigns ownership, and that you already have an implied ownership by the act of calling alloc then things start to fall into place. At least, that’s what happened for me.

What should we have done?


We have a range of options for correctly implementing our init method:

Use autorelease

- (id) init
{
  self = [super init];
  if (self != nil) {
    self.feathers = [[[NSArray alloc] init] autorelease];
  }
  return self;
}

Explicitly release ownership after assignment

- (id) init
{
self = [super init];
  if (self != nil) {
    NSArray *tempArray = [[NSArray alloc] init]; 
    self.feathers = tempArray;
    [tempArray release];
  }
  return self;
}

Create an array without implicitly taking ownership

- (id) init
{
  self = [super init];
  if (self != nil) {
    self.feathers = [NSArray array];
  }
  return self;
}

The first two approaches are the most common. I often see advice to use the more verbose explicit release approach, rather than autorelease, because it is more performant. Personally, I tend to optimize for developer performance at the sake of a bit of CPU performance, and prefer the autorelease approach. It’s a lot less typing and more importantly I feel it makes the code a bit easier to scan through, particularly if you have a block of code with lots of property assignments.


UPDATE

After posting this I remembered there’s another way we could solve this memory leak:

Assign directly to the member variable

- (id) init
{
  self = [super init];
  if (self != nil) {
    _feathers = [[NSArray alloc] init];
  }
  return self;
}

I don’t really like this approach, because there’s a lack of symmetry in sometimes accessing a member variable directly, but at other times via a property. Also, it encourages folk to use this approach outside of init methods. This greatly increases the likelihood of another memory management error - not releasing ownership from an existing reference before replacing that reference. Hmm, I should cover that one in a future post…

Podcast About Frank and Test Automation on iOS

| Comments

Some colleagues at Thoughtworks and I recently recorded a 30 minute podcast about Frank, our UI automation tool for iPhone/iPad testing which I introduced in this post.

In the podcast we cover:
  • an overview of Frank, what it is and where it came from.
  • How our testers and developers use Frank and cucumber at our current client (and how we’d ideally like to be using it).
  • Alternatives to Frank, such as iCuke and brominet.
  • Some waffling by me about some of the reasoning that drove my design decisions with Frank. For example, avoiding XML and XPath for UI element selection.
  • Symbiote, the little web app that we embed inside Frank which allows a test creator to inspect and play with the live iOS app as it’s running.
  • Writing cucumber feature files per-story versus per-feature.
  • Handling the stateful nature of an iOS app in UI-level tests, and including Frank testing into a Continuous Integration system.
  • The challenges of testing an app which integrates with large back-end systems.
  • What’s next for Frank.

Many thanks to Chris Stephenson for organizing and facilitating, and to Derek and Hiyasmin for tolerating my hogging of the mike!

You can get more information on the podcast and give it a listen here.

Frank: Automated Acceptance Tests for iPhone and iPad

| Comments

Recently I joined a team developing an iPad application. The application had no existing automated tests, and the team was under a tight deadline to deliver on promised functionality. Faced with similar circumstances in the past I have advocated introducing automated UI-driven acceptance tests to establish a loose but broad test coverage net. After a brief investigation we decided that the available tools weren’t quite what we needed, so we built our own ‘Frankenstein’s Monster’ by plumbing together several existing open source libraries to create a light-weight UI automation framework for iPhone and iPad applications, called Frank.


How does Frank work?

In use Frank consists of two main parts. There is a small objective-C server which is compiled into the iOS application you want to automate. You then use a remote driver from within your automated testing framework of choice to send automation commands to the Frank server and interpret the responses sent back.

Frank Architecture Overview

Currently the project includes a Cucumber driver. Creating additional drivers (for RSpec, NUnit or JBehave perhaps) is a pretty trivial task, as the Frank server provides just a few key commands.


I don’t get it. Show me moving pictures!

Here is a brief screencast which demonstrates a Cucumber test suite exercising the functionality of a simple iPhone app via Frank. [Click Here to watch the screencast in a larger window]


You can see the Cucumber scenarios and then watch as the Frank driver automates the application in the iPhone simulator, restarting the application between each scenario.


Anything else?

Frank has additional functionality which I haven’t gone into here. There is a javascript web app called Symbiote which is embedded within your iOS app itself. This allows you to interact with your iOS application as it’s running, testing UI selection paths and inspecting the application’s DOM in realtime. We also provide Cucumber steps for utility tasks such as recording a test run to video (great for debugging a failing acceptance test within a CI system), rotating the simulated device, and restarting the application between scenarios to ensure independent tests.


Where can I get it?

Frank (plus some more documentation) can be found on github right here.

What’s coming?

The next important step is including our automated acceptance tests within a Continuous Integration build. We intend to run Frank tests upon every checkin, much as you would run Selenium tests for a web application. A failing test will break the build, emailing the team with a video showing the failing test.

I’m also planning to blog about specific aspects of Frank in greater depth in coming weeks.

Please do check Frank out, and get in touch if you have any feedback, feature requests, bug reports, or anything else!

TDD, Emergent Design, and Punctuated Equilibrium

| Comments

In my experience good TDD designs tend to have evolved (and hopefully continue to evolve) in a sort of punctuated equilibrium. There are long periods of small incremental changes to a code base, punctuated by infrequent bursts of large design-level refactorings. While the TDD mantra is “Red, Green, Refactor”, I think a more accurate version would be “Red, Green, Red, Green, Red, Green, Refactor”. Less catchy, I know.

Letting tests drive your design is great, but if you’re not careful you will end up with a design which is the result of a simple accreation of functionality. This of course is the reason for the “Refactor” part of RGR. However, in my experience the refactoring part does not occur in a steady flow. Rather there will be periods of time where only small implementation-level refactorings take place during the RGR cycle as new functionality is implemented. Then at some point something will give. Someone may have a design breakthrough, realizing a more expressive/elegant/clean way to express some functionality. Alternatively some niggling annoyance in a subsystem’s design will pass the team’s tolerance threshold such that they decide they need to clean up the design to remove the annoyance. Both events will lead to a brief flurry of larger design-level refactorings.

A somewhat minor example of the ‘niggling annoyance’ case would be when someone is adding a 4th optional parameter to a method call and finally decides to bite the bullet and pull all the optional parameters out into a single options hash. An example of the ‘design breakthrough’ case might be the third time someone adds a subclass in order to specialize some aspect of a base classes functionality. They might realize that really what’s going on here is that each subclass represents a Strategy, which can be plugged into the base class. Now both of these examples are rather small-scale, but hopefully they illustrate the concept. It’s hard to come up with examples of larger refactorings which are easy to succinctly describe without a bunch of background information.

A key observation here is that principles like YAGNI and ‘do the simplest thing that will work’ will not work well in isolation. Rather they must live alongside principles like DRY, seperation of concerns, do one thing and do it well, etc. If your sole focus is on doing the minimum amount to get your tests passing you will not end up with a supple code base which is amenable to change. That requires dilligent attention on your part.

Does this mean that TDD leads to bad design? No. TDD does not lead to good design on its own, but it does set the stage for good design to emerge. A team with the safety net of a strong test suite has the courage to follow through and realize these design-level refactorings. A team without that safety net may know exactly what needs to be done but will lack the courage to do so, because they know that any changes will lead to unknown breakages. Thus, the team will be reluctant to undertake these design improvements, as much as they would like to do so.

Finally, this idea of punctuated design equilibrium may sound familiar to folks who’ve read Eric Evan’s Domain Driven Design. He talks about how good teams who are really working to understand a domain will occasionally find themselves up against a breakthrough which requires them to stop forward momentum on features in order to realize a more elegant expression of their core domain. That small section of his really excellent book was certainly in my mind as I started writing this post.

Introducing Noguchi

| Comments

Generating HTML tables in ruby has always seemed like more of a hassle than it should be. Most of the times that I’ve had to do it I’ve been a little frustrated with how, well, ugly the view code looks. So, I decided I’d try and create a nicer way to build tables. The end result is a small table creation library called Noguchi. Given a set of data and some optional configuration it will render a table as HTML or CSV.

Show me!

Here are some quick examples of the kind of things you can do with Noguchi. There are more features than I will show here; for more details check out the README in the library’s github repo

Creating a simple table from ActiveRecord model instances

table = Noguchi.table_for(users)
table.render

generates

NameAgeSex
Jenny24F
Dave32M
Hank27M

Rendering CSV

table = Noguchi.table_for(users)
table.render_as_csv

generates

name,age,sex
Jenny,24,F
Dave,32,M
Hank,27,M

Rendering collections of hashes

fruits = [
  { :name => 'banana', :color => 'yellow' },
  { :name => 'apple', :color => 'green' },
  { :name => 'orange', :color => 'orange' } 
]
table = Noguchi.table_for(fruits)

generates

namecolor
bananayellow
applegreen
orangeorange

Adding arbitrary custom-rendered columns

table = Noguchi.table_for(users)
table.add_field(:edit)
table.to_render_body_cell_for(:edit) do |context,cell|
  cell.raw_content = link_to( "Edit this user", edit_user_path(context.datum) )
end

generates

NameAgeSexEdit
Jenny24FEdit this user
Dave32MEdit this user
Hank27MEdit this user

The approach

I decided that since the goal of this library was to make table creation code look less ugly I would let the design of the API drive the process. So I started off by thinking about how I’d like table creation code to look like, basically just writing some rough ruby code that used the as-yet-unwritten library to render a basic table. The idea here was to get a simple core API which would render a basic table with very few lines of code, but to make the table rendering customizable by adding various tweaks to that basic table. Once I was happy with how the core API looked I started writing more complex examples, letting that drive out more advanced features in the API. These features were optional configurations which aimed to handle the most common kinds of customization I seem to end up doing to a table. Things like customizing a column header, adding an extra column to contain an edit link, things like that.

Once I had a rough idea of the API in my head, I started writing tests that described the functionality, implementing just enough of the library at each step to make the tests pass. I was plesantly surprised at how well this worked; the entire implementation was driven out by these tests. While I do tend to TDD most of the time, I’ve seldom done so exclusively. I tend to find myself spending some small amount of time outside of the Red-Green-Refactor loop, usually while exploring a new design approach or a brand new subsystem. I’m quite pleased with how this exclusively TDD approach played out in this case, although I wonder whether it would work quite as well in different circumstances.