TDD and iPhone - NSTimer
by: eric | May 11th, 2009 | 1 comments »
TDD on the iPhone is a challenging experience, especially when you’ve been spoiled by Ruby like I have been, but it can be done. I have a tutorial in the works for getting started, but in the meantime I’ll be writing bits and pieces about my experience. The first was here and this is the second. Test cases are written using the Google Toolbox for Mac. This particular example is about the NSTimer.
It keeps going and going
The app to your right is a simple app for experimentation purposes that runs Conway’s Game of Life. It has two buttons: advance and start. Advance moves one generation ahead each time you press it, whereas Start keeps advancing generations until you touch Stop. To implement that we use an NSTimer object which is programmed to call advance on the game object. The design is simple, shown here:
The GameRunner creates an NSTimer, the NSTimer sends the message to Game. Great but how do we test it? The less I know about something the more I tend to test it, which means I tend to write smaller and smaller tests. Let’s look at my first few tests of the GameRunner object:
- -(void) testSetsAndGetsTimeInterval {
- runner.interval = 0.30;
- STAssertEquals(0.30, runner.interval, nil);
- }
- -(void) testCreatesNSTimerObject {
- [runner start];
- STAssertNotNil(runner.timer, @"The timer was not created");
- STAssertTrue([runner.timer isValid], nil);
- }
- -(void) testNSTimerFields {
- runner.interval = (NSTimeInterval) 0.26;
- [runner start];
- STAssertEquals([runner.timer timeInterval], 0.26, nil);
- }
We’ve got some basic tests of creation. At this point I was stumped. I couldn’t check the other parameters of the timer, because they weren’t public variables, so at this point the code that actually created the timer looked like this:
- -(void) start {
- timer = [[NSTimer timerWithTimeInterval: interval
- target:nil
- selector:nil
- userInfo:nil
- repeats:true] retain];
- }
That doesn’t really help me does it? I have a timer with an interval, but it won’t call anything when it’s triggered. This is about the time I got to pair with Jake Scruggs during the Craftsman Swap, which he’s written about here. It went badly, somewhat embarrassingly for me since I’m supposed to be the expert, however we learn from failure. Let’s look at some of the steps Jake and I took that didn’t quite get us there.
The first pass on the test was simple. We needed a mock game, and it needed to have its advanceGeneration method called (Ed. note: I realize they aren’t called methods in Obj-C, to which I say: bite me.) each turn. Let’s try the brute force approach:
- -(void) testTimerCallsGameAdvance {
- MockGame *mockGame = [[MockGame alloc] init];
- runner.game = mockGame;
- [runner start];
- sleep(.30);
- STAssertTrue([mockGame advanceGenerationCalled], nil);
- }
I’m writing the original tests from memory, so I make the occasional error here, but it doesn’t matter since we got this wrong. This test here seemed the most logical. We ran the test and it failed, yea! Then we updated the code:
- -(void) start {
- timer = [[NSTimer timerWithTimeInterval: interval
- target:game
- selector:@selector(advanceGeneration)
- userInfo:nil
- repeats:true] retain];
- }
Experienced Cocoa developer’s have already discovered our error, please don’t ruin it for the rest of the readers. So after changing the code we run the test and…we fail. So from here Jake and I figured it out. Sleep won’t work because it stops the entire application, including the run loop that calls our timer, so we’ll just have to get the info out of the timer another way. We’re interested in testing that we’ve setup the timer correctly, and can trust that the timer just works. After a loooong time browsing documentation we figured it out. We could call this:
- -(void) testTimerCallsGameAdvance {
- MockGame *mockGame = [[MockGame alloc] init];
- runner.game = mockGame;
- [runner start];
- [runner.timer fire];
- STAssertTrue([mockGame advanceGenerationCalled], nil);
- }
This will fire the timer and validate that it is setup correctly. So we did this, our test passed, we ran the app and it….failed. We knew the timer was executing because our test was passing, but when we ran the real app it just didn’t do it. Stumped and frustrated we stopped for the day. Then time passed…..
Yesterday I had a candidate in for an apprenticeship position, and we attempted to solve the same problem. We re-evaluated the test and decided calling fire directly was cheating. We looked into a half-dozen other ways to test this and learned about the NSRunLoop. Too much coding in Windows had rotted my brain, the run loop in Objective-C is not the same as the one in Windows. Specifically the current run loop is accessible as an object. We wrote a new test:
- -(void) testTimerCallsGameAdvance {
- MockGame *mockGame = [[MockGame alloc] init];
- runner.game = mockGame;
- [runner start];
- [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow: 0.30]];
- STAssertTrue([mockGame advanceGenerationCalled], nil);
- }
It’s not perfect - the 0.30 relies on the hard coded default interval of 0.25, and that is too long, but it failed! In the process of learning about NSRunLoop we also realized I used the wrong method. The working code is this:
- -(void) start {
- timer = [[NSTimer scheduledTimerWithTimeInterval: interval
- target:game
- selector:@selector(advanceGeneration)
- userInfo:nil
- repeats:true] retain];
- }
See the word “scheduled” in front of Timer? That actually adds the timer to the default run loop. Now we ran our spec, ran our actual code, and it works! The moral of the story? Well if you’re persistent enough you can get your code under test, and if your test is correct then your code will work.
Dependency Inversion Principle and iPhone
by: eric | April 16th, 2009 | 0 comments »
Vertical Dependency
While working on the slides for our upcoming* talk on TDD for iPhone I asked Eric Meyer why we need the Dependency Inversion Principle. He eagerly answered, “Testing!” which made me laugh because I wasn’t giving him a trivia quiz, and I love Eric’s enthusiasm. He’s right, but the answer is circular. TDD is great because it gives us better designs that correspond to the DIP which enables TDD. Ha! I win, would you like to buy my consulting services? I have plenty of three letter acronyms where those came from.
Fortunately this isn’t the case, as the DIP existed well before TDD was popularized, but recently there was a bit of a dust-up over the SOLID principles. Many developers don’t understand why dependency inversion is important, so let’s demonstrate the usefulness in the Objective-C language on the iPhone.
The Dependency Inversion Principle (DIP) reads as follows:
A. High level modules should not depend upon low level modules. Both should depend upon abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.
So your code should depend on interfaces not on concrete classes, but why? Let’s look at a useful example in the Objective-C built in classes.
- [NSString stringWithFormat:@"Object is: %@", object];
Do you see the DIP at work? It’s subtle here, but look at the method stringWithFormat, which takes a format string and then a list of parameters to fill in the format specifiers. The format specifier here is “%@” which takes any Objective-C object and calls descriptionWithLocale on it, or description otherwise. The object that is passed in here could be anything because all the stringWithFormat method cares about is that the object provides at least one of the two methods above. It’s depending on the interface, and not the concrete class. Let’s imagine a world where this didn’t exist, and the NSString method could only be composed of other strings. Suddenly you’d have something like:
- return [NSString stringWithFormat:@"Object is %s", [object toString]];
That’s not bad at all is it? Well what if there are different objects.
- return [NSString stringWithFormat:@"Object is %s %s %s", [object1 toString],
- [object2 toS],
- [object3 stringify]];
Are you starting to see the problem? Suddenly I can’t use this method without being cognizant of the specifics of the object I passed in. The minute one of these interfaces changes I have to change my code. I stole this method from some real code, so let’s look at it with some context. Once upon a time I was writing a mock object for an iPhone application. Now iPhone doesn’t have a good mock object framework, at least that I’m aware of, so I was rolling my own mock. The mock logged calls to it which I then queried. To construct the string I used this method:
- +(NSString *) createStringFrom: (id) cell at: (CGPoint) point
- sizeOf: (CGRect) rect
- {
- return [NSString stringWithFormat:@"%@ %f %f %f %f", cell,
- point.x,
- point.y,
- rect.size.width,
- rect.size.height];
- }
Don’t sweat the details right now, they’re not important. Instead look at how you can see the DIP succeeding and failing in the same code here. The first parameter to createStringFrom is a cell object, but it’s of type id, so it could really be anything. That’s good because I wasn’t sure when I wrote this mock what type the cell would be and I’d generally prefer that my mock object not have to know the details. In fact the cell did change type several times which is why insulating yourself from change is so important. There’s an assumption by many developers that you should only worry about the things you’ll be changing in the future, but the best gauge of future changes is present changes, and if you’re changing a module frequently during development as you get it right you’ve found a likely change point. Even if you haven’t, you’ll make your life simpler in the present by insulating yourself from that change, speeding up your development cycles. I digress.
The rest of this method isn’t so lucky. You see CGPoint and CGRect are C structures, and I am left to write these as floats in the string (%f). If I was to change the parameter types frequently I would probably introduce some way to insulate myself from that change as well, possibly by wrapping them in objects. Since those parameters have not changed I haven’t done that, although I’m thinking about it.
Our current apprentice Colin has given a first-hand account of refactoring to DIP here as well.
How do I do it?
Eric and I are working on a program to run Conway’s Game of Life. On the iPhone screen you see Rounded Rect Buttons that change color based on whether a cell is alive or dead. The problem is that we don’t really want to drag and drop 300+ tiny buttons on the screen with interface builder. Instead we want to create them programatically, when the GameOfLifeViewController is loaded. Again I don’t want to overload you with extraneous details, so just take my word for it that there is a GameOfLifeViewController, and it needs to generate buttons. Here’s what my first pass at a test looked like in rough pseudocode:
- for (int row = 0; row < 15; row++)
- {
- for (int column = 0; column < 15; column++)
- {
- button = GetButtonViewAt(row, column)
- STAssertEquals(expectedSize, button.size)
- STAssertEquals(expectedLocation, button.location)
- STAssertAction(expectedAction, button.action)
- }
- }
There’s a lot wrong with this test. The most obvious is the hard coded 15. What happens when we want to change the number of rows and columns? Now we have to change code in multiple places. Naturally we did in fact change this, so I would have paid for this decision quickly if I hadn’t already refactored it away. The second is that there’s going to be more than one test for creation, each of which will have to perform the same 15x15 loop. The annoyance of constantly changing this will reveal the root the problem, the GameOfLifeViewController should really only be in charge of GameOfLifeView and really doesn’t need to know the details of the creation of its subviews. It’s violating the Single Responsibility Principle. We can fix that with a factory object, and will do so, but that will violate the Dependency Inversion Principle. So we’ve got one DIP violation, an SRP violation, and a potential second DIP violation, all demonstrated in 6 lines of test code.
Fortunately we’re going to introduce some interfaces to clean that up. The first is an interface to the board object. Why the board? Well the board should know the number of rows and columns it has, and if we can inject a fake version of the board we can actually set those to be 1 and 1. That’s will make our test focus on what we are truly concerned about. The second thing we’re going to do is introduce the Abstract Factory pattern to create our button views. It’s a bit of a heavyweight solution but its going to pay off by cleaning up our client code dramatically. We’ll have a View Controller concerned with controlling the view, and a creation factory concerned with creation, as well as a board that keeps track of rows. Let’s take a look at the test now, again in rough pseudocode.
- -(void) setUp
- {
- controller = [[GameOfLifeViewController alloc] init];
- controller.board = [[MockBoard alloc] init];
- controller.buttonControllerFactory = [[MockButtonFactory alloc] init];
- }
- -(void) testCreationOfButtons
- {
- [controller viewDidLoad];
- bool called = [controller.board calledWith: params that: I want: true];
- STAssertTrue(called);
- }
So what’s going on here? In the setup we load up the board with a fake board, one that returns 1 for its rows and columns, and we load up its buttonControllerFactory with a fake buttonController Factory. In our test we call the viewDidLoad method, which is called on controllers after their view is loaded. Duh. That’s the method where we use the buttonControllerFactory. Then we call a method on the mock factory calledWith: that takes the parameters I expected the creation factory to receive. Finally we check that it was called with the assertion. So far I’ve only been showing test code, because I wanted to demonstrate just how much cleaner our tests have become. Now there’s no loop, no hard coded constants, and no testing the internals of the creation factory in the view controller. That isn’t to say we don’t test the creation, we just do that in a different test case, the one that corresponds to the ConcreteButtonFactory class. As a rule if our test code is cleaner, our implemenation code is cleaner, and that’s the case here as well.
Let’s now look at the real class, and how to enable Dependency Inversion on it. We have to start with Objective-C protocols. Protocols are very similar to Java interfaces, and just as useful, but are strangely underrepresented in XCode. As best I can tell** just create an NSObject subclass and remove the .m file and any imports from the .h. Here’s the protocol from the unfortunately named ButtonControllerFactoryProtocol.h:
- #import "ButtonController.h"
- @protocol ButtonControllerFactoryProtocol
- -(ButtonController*) createButtonControllerForCell: (id) cell
- at: (CGPoint) point
- sizeOf: (CGRect) rect;
- @end
As you can see the interface only defines one message, createButtonControllerForCell. It returns the ButtonController object, although it could return an object conforming to a protocol. Indeed one could argue it should, as that would streamline my mock object. Hmmm… I see a refactoring in my future. Now let’s look at the class definition for the ConcreteButtonControllerFactory, which is the object that is actually used when the real app is running.
- #import <uikit />
- #import "ButtonController.h"
- #import "ButtonControllerFactoryProtocol.h"
- @interface ConcreteButtonControllerFactory :
- NSObject<buttoncontrollerfactoryprotocol> {
- }
- @end
Not much here is there. The important part to look at is NSObject
- #import "ConcreteButtonControllerFactory.h"
- @implementation ConcreteButtonControllerFactory
- -(ButtonController*) createButtonControllerForCell: (id) cell
- at: (CGPoint) point
- sizeOf: (CGRect) rect;
- {
- ButtonController *controller =
- [[ButtonController alloc] initWithCell:cell];
- UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
- [button setFrame:rect];
- [button setCenter:point];
- [button setImage:[UIImage imageNamed:@"dead_cell.png"]
- forState:UIControlStateNormal];
- [button addTarget:controller
- action:@selector(bringToLife:)
- forControlEvents:UIControlEventTouchUpInside];
- controller.view = button;
- return controller;
- }
- @end
This isn’t an article on UIKit so I’m not going to get into the details of creating the button. You can see again that I’ve ignored the DIP for creating the UIButton and the ButtonController. Since this is a factory I’m okay with this violation. I could have created abstract factories for the UIButton and ButtonController and passed them in here but I don’t believe I’d gain any benefit from that implementation. That’s verified by my testing, as writing tests for the creation of these objects was hard before I introduced this factory but isn’t any longer. If it becomes difficult then I’ll consider making the change to two factories. Now we need to inject the concrete dependency. In a Java project you could do this in a main method or with a DI framework like Spring. We’re going to be using my favorite DI framework of all time: Interface Builder!*
It’s a common misconception that IB is just a GUI builder. What’s great about it is that it doesn’t just generate a bunch of code, but instead “freeze dries” real objects to be instantiated when the program loads the NIB file. Furthermore while the most common Outlets are UI elements there’s no reason other objects can’t be used. Let’s take a look at my NIB document window for the GameOfLifeViewController:
As you can see I’ve got objects for the Game, ConcreteButtonControllerFactory, and the Board. That’s because all three of the objects are injected at runtime, while the code depends on protocols. To add your own objects to a NIB file simply by selecting it from the Library:
It’s inspector window will have a class drop down, so set this object’s object to your class. Finally you need to connect the outlets to actual outlets in your code. Let’s look at the Outlets tab in IB for my controller (the File’s Owner):
Notice how the controller still thinks of them all as NSObject? So if I change the objects it doesn’t care, as long as I conform to the interface? Finally let’s take a peek at the controller interface file:
- #import "BoardProtocol.h"
- #import "ButtonControllerFactoryProtocol.h"
- #import "GameProtocol.h"
- @interface GameOfLifeViewController : UIViewController {
- IBOutlet NSObject<boardprotocol> *board;
- IBOutlet NSObject<buttoncontrollerfactoryprotocol> *buttonFactory;
- IBOutlet NSObject<gameprotocol> *game;
- }
- @property(nonatomic, retain) NSObject<boardprotocol> *board;
- @property(nonatomic, retain) NSObject<buttoncontrollerfactoryprotocol> *buttonFactory;
- @property(nonatomic, retain) NSObject<gameprotocol> *game;
See any dependencies on the actual objects? Nope - just protocols. There are properties for the objects so that I can inject the dependencies through the tests, all of which pass in fake versions as various times depending on how it suits the test. It may be unhealthy - but I find this incredibly cool.
Summary
What I love about Interface Builder is setting this up is extremely simple. Writing tests for the controller that is based on these dependencies is also extremely simple, far simpler than just depending on the concrete objects. It’s funny how developers often complain about the time wasted writing tests or “over-engineering” in this way, but once I broke these dependencies I got things done a lot faster. I’m writing working code without loading the actual simulator. I write my tests first, making progress, and when I’m done for the session I run the app once or twice just to verify I haven’t done anything like forgotten to inject the dependency. Compare that to running the simulator constantly, each time hoping your code is functional. Who’s wasting their time now?
FootNotes:
* Uh yeah we gave that talk already. These take a while!
** I’m 99% positive there’s a better way, and that I haven’t found it. Tell me if there is!
*** To be fair it’s the only one I’ve actually used.
Selenium on Rails Released
by: eric | March 7th, 2009 | 0 comments »
Quick announcement, Selenium on Rails has been released, now supporting Rails 2.2 and with the latest Selenium Core. Numerous bug fixes are in this release as well, thanks to commiters Marcos Tapajós, Nando Vieria, and Gordon McCreight.

To update to the latest version install the plugin from http://svn.openqa.org/svn/selenium-on-rails/stable/selenium-on-rails. This release is once again not compatible with previous versions of Rails, so check the website to install new revisions.
I also want to add a new patch policy. To patch/contribute to selenium on rails head to the http://github.com/paytonrules/selenium-on-rails and fork the repo, then just issue a pull request. I will not be taking patches that don’t have tests however, as it is just too much work for me to retrofit tests on to the patch.
For any questions or comments contact me at eric (at) 8thlight (dot) com. Look for me at SDWest and Scotland on Rails.
When is a Mock not a Mock
by: eric | January 10th, 2009 | 0 comments »
A couple of weeks ago I had to add a feature to some code that was written almost two years ago. It was a pretty simple web service client that constructed some XML, using Ruby’s REXML library, and made the web service call via another library. A quick inventory shows two dependencies, the web service call and REXML, so that’s what I expected to see when I came across the tests. But what did I see? Paraphrasing:
- @client_under_test = Client.new
- @client_under_test.stub!(:send_message)
- @client_under_test.stub!(:parse_response)
Of course the send_message call contained the construction of the XML so that there was no test that the XML being constructed was correct. Heck that was all that was being done in the class, and a closer inspection of the tests revealed that all they were doing was testing the error handling by changing the return value of parse_response. This is a classic sign that the developer at the time couldn’t figure out how to stub out the actual dependency, and so they did the next best thing, they stubbed out the caller.
I knew this was wrong, but I had an iteration meeting the next day and still had to update the .NET web service that this code was calling. So I started to just go ahead and make the untested change, but then my Clean Code wristband started burning until I couldn’t take it any more. I had to get the REXML library under test. So what to do? Well the REXML construction looked like this:
- doc = REXML::Document.new(create_schema)
- doc.elements["name1"].text = "thing 1"
- doc.elements["name2"].text = "thing 2"
- ...
Okay I know how to do this normally. The first test was simple:
- REXML::Document.should_receive(:new).with(schema)
It passed! What was so hard about testing this anyway? Okay let’s test that the elements are set:
- ....
- elements = mock(REXML::Document, :[] => mock_element)
- doc = mock(REXML::Document, :elements => elements)
- REXML::Document.stub!(:new).with(schema).and_return(doc)
- ...
Oh that sucks! Since the API doesn’t run entirely through the doc object I have to stub elements, then stub each individual element, then should_receive on text, and if I want to be perfect I can stub out the array accessor too. I have to should_receive for each element name, the tests will be hard to follow and fragile. Now I get why the original developer punted on this. There’s got to be a better way. I can start expecting actual XML, but from past experience I know that leads to very hard to read tests that give errors that aren’t easy to diagnose. What I really care about is that the elements in this hash-like structure have their text element set to the right data. After trying out several approaches I had a moment of inspiration, I want a struct! Must be my inner C programmer. If elements was a hash of structs, I could just check their text values are set. This way I’m testing that I’m using the REXML library right rather than testing the library itself. If only Ruby had a struct concept…..
I suppose you’ve already figured out that it does, haven’t you?
- MockElement = Struct.new("MockElement", :text)
What that does is setup a class named MockElement, with the accessor text. When is a Mock not a Mock? When it’s really a Fake. Instead of stubbing out elements to return yet another mock, elements will return a hash of the element names I know I’m using that point to these fake elements. Then after making the call in the client, I’ll just check that the text is set properly. This is best demonstrated with an example:
- before(:each) do
- @elements = initial_elements_hash
- @doc = mock(REXML::Document, :elements => @elements)
- REXML::Document.stub!(:new).with(schema).and_return(@doc)
- end
- def initial_elements_hash
- return {"element1" => MockElement.new,
- "element2" => MockElement.new}
- end
- it "should set the data in the xml doc" do
- @client.send_message
- @doc.elements["element1"].text.should == "Eric"
- @doc.elements["element2"].text.should == "Smith"
- end
Aha! Now I’ve tested that the XML was properly constructed without relying on looking at the actual XML text itself and without stubbing out the class itself. The code is cleaner, the tests are easier to understand, and I can implement my new feature. More importantly, my wristband stopped burning.
Selenium on Rails example
by: eric | September 20th, 2008 | 0 comments »
The files for the WindyCityRails talk here.
Selenium on Rails released
by: eric | September 14th, 2008 | 1 comments »
Remember when I used to post here? Not that I’ve ever been prolific but there is a reason I haven’t posted in 53 days, well at least the last 30, as I’ve been hard at work preparing for my Selenium on Rails talk at Windy City Rails. What work? Primarily releasing a new version, one that works on Rails 2.1. These are the newest features:
- Did I mention it works in Rails 2.1? (Thanks to Ryan Bates)
- Checkout/run tests is now possible. You DON’T have to put this in the vendor/rails directory of an existing project.
- Your config file is now stored in config/selenium.yml, so you can store it in source control. Thanks again to Ryan
During the last month I’ve taken the official repository at OpenQA and cloned it at git. While I’ll still be maintaining the OpenQA version because I like the association with the group, I find it’s hard to get help with contributions on the site through their subversion repository. Therefore I’ve created a github for it that will be periodically synchronized with the subversion repo. If you want to help by contribution features or patches, or you want the latest and greatest repo, head here: http://github.com/paytonrules/selenium-on-rails/tree/master. Otherwise it’s still hosted at its normal location here: http://selenium-on-rails.openqa.org/. There’s still an old version available for Rails users that haven’t upgraded, and the instructions for installation are available as well.
Please let me know if you got feature requests for Selenium On Rails, or patches ready to go. I’m looking forward to revitalizing that project.
Some Random RubyCocoa stuff
by: eric | July 23rd, 2008 | 7 comments »
I went to WWDC last week (1), and while I was there I got a chance to talk to a couple of their engineers and picked up a few things about RubyCocoa. Neither of them are really enough for a blog post on their own, hence the title of this article.
Running tests in XCode
When you’re writing RubyCocoa you may find you have three windows open. XCode to create your files, Interface Builder to design your interface, and Textmate to edit code and run tests. If not Textmate, then probably a command window. To put it politely - this sucks (2). While I’m no big fan of XCode’s text editor I pretty much have to have it open (3) while I’m developing RubyCocoa, so how do I run specs from within XCode? It’s simple. Open up or create a new RubyCocoa project. On the left you should see Targets, click the tree to open it:

You can see the process for building your application here. We’re going to add running specs as a last step, so that our build will fail when our specs do. Right click on the target, and add a new Run Script phase:

Then just add this to the script.

It’s just that simple! I put all my specs in a spec directory, don’t add them to the target of course, and they get run on each build. Here’s an example from a project I’m working on with a failing test:

This shows up in the Build Results window in XCode which you’ll see when you click the worlds tiniest red x in the corner of the screen.

Congrats, now you can code in XCode and not Textmate. Okay it’s text editor is poor, but Interface Builder and XCode are built to work together. For example when you have XCode and Interface Builder open you don’t have to constantly drag-and-drop from finder to IB, it just detects your code changes. This is extremely handy when adding actions or outlets. In fact the two apps are so intertwined Interface Builder just plain doesn’t work that well stand-alone. That’s yet another reason to keep using XCode, no matter how much I dislike it.
Opening a File or Directory in RubyCocoa
My first two tutorials use simple “selectors,” Objective-C’s fancy name for a method. Actually that’s Smalltalk’s name for a method, and Objective-C steals it. To use Smalltalk terms there are unary messages, which are the kind that only take one or 0 parameters, and keyword messages. Keyword messages have named parameters, and ruby doesn’t have named parameters, so how do we send multiple arguments to a method in RubyCocoa? This simple example of opening a directory will demonstrate.
Start by creating a new RubyCocoa project. For directions on the basics go here. We’ll be doing BDD again so I expect you’ll be able to run tests. Call your new project OpenDirectory or something similar, then use the directions above to add a run specs phase to your build process. Now open the MainMenu.nib, and create a window that looks like this:

That’s a lovely dialog. Let’s get started running code. Click on the build and go button. What’s this?

Our build doesn’t work! We don’t have a directory called spec, or any specs in it. Create a spec directory under Create a spec in the spec directory called choose_directory_spec.rb. Remember not to add it to the target, and make sure it is in the specs directory. Here’s our first spec:
require 'choose_directory'
describe ChooseDirectory do
it "should be an NSObject" do
directoryController = ChooseDirectory.new
directoryController.is_a?(OSX::NSObject)
end
end
I know pretty simple. I’m not going to go baby steps through this because at the moment I lack the patience. If you see an error that your build failed because you don’t have a file choose_directory then you’re on the right track. Create the ChooseDirectory class, this time in the root directory and add it to the target. I choose to group my specs in an XCode group called Specs and my classes in the Classes group that’s already provided for you, but those are just groups and you can feel free to do this any way you please. Now let’s look at the next few tests.
def OSX._ignore_ns_override; true; end
before(:each) do
@mock_panel = mock(OSX::NSOpenPanel, :canChooseDirectories= => nil, :canChooseFiles= => nil)
OSX::NSOpenPanel.stub!(:openPanel).and_return(@mock_panel)
@directoryController = ChooseDirectory.new
end
it "should have an action open directory" do
@directoryController.open_directory
end
it "should open a panel" do
OSX::NSOpenPanel.should_receive(:openPanel).and_return(@mock_panel)
@directoryController.open_directory
end
it "should configure it to select directories" do
@mock_panel.should_receive(:canChooseDirectories=).with(true)
@directoryController.open_directory
end
it "should configure it so it can't select files" do
@mock_panel.should_receive(:canChooseFiles=).with(false)
@directoryController.open_directory
end
One thing probably jumps out at you, that big strange command def OSX._ignore_ns_override; true; end If you don’t include this you’ll get warnings that you can’t override the methods in OSX::NSOpenPanel because the arguments don’t match. We didn’t override them of course, we stubbed and mocked them with RSpec, but from Cocoa’s perspective that’s the same thing. We remove the error by monkey-patching _ignore_ns_override to return true. Rucola (4) apparently has this problem licked, otherwise you’ve got to put this before your mocks get loaded. Looking down the specs you can see I’m calling NSOpenPanel class methods, and configuring it. The method openPanel creates an NSOpenPanel object and returns it, the other two methods should be self explanatory. Isn’t it interesting how you can figure out the intent of the code from these tests? It’s almost like a specification. Here’s the code that makes this pass:
ib_action :open_directory
def open_directory
panel = OSX::NSOpenPanel.openPanel
panel.canChooseDirectories = true
panel.canChooseFiles = false
end
One action, open_directory, that sets up the panel. We haven’t displayed the panel yet. Remember what I said about selectors with named parameters? Well here’s where it comes into play. We need to call the beginSheetForDirectory method on that panel. This will display a standard dialog box for opening directories. Here’s the full method signature, from the Objective-C documentation:
- (void)beginSheetForDirectory:(NSString *)absoluteDirectoryPath file:(NSString *)filename types:(NSArray *)fileTypes modalForWindow:(NSWindow *)docWindow modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo
This is a keyword message. The syntax works like this:
[method name]: [first parameter] [first keyword]: [second parameter]…..forever
So for beginSheetForDirectory that’s one, two, three…oh man that’s a lot of parameters. Here’s what my first attempt at doing this in RubyCocoa looked like (in another application):
beginSheetForDirectory_file_types_modalForWindow_modalDelegate_didEndSelector_contextInfo(nil, nil, nil, nil, self, "open_panel_did_end", nil)
Now that is a method name! Fortunately I found a slightly (5) better way to do it. It looks an awful lot like sending a hash of parameters, something that should be familiar to Rails users. Here comes our next test:
it "should call beginSheetForDirectory" do
@mock_panel.should_receive(:beginSheetForDirectory).with(nil,
:file, nil,
:types, nil,
:modalForWindow, nil,
:modalDelegate, @controller,
:didEndSelector, "open_panel_did_end",
:contextInfo, nil)
@directoryController.open_directory
end
This is closer to the named parameters convention of Objective-C. The panel will call beginSheetForDirectory with nil as the name of the initial directory. The first parameter isn’t named, it’s specified by saying “ForDirectory”. By passing nil we say “open this directory to the same directory I did last time.” Works fine for most situations. Only two of the parameters are really interesting. The first is the modalDelegate, which I’ve specified will be the controller. A message will be sent to the modalDelegate when the panel operation ends. I just want it to send it back to the controller. The second is the didEndSelector which I’ve specified to be the method open_panel_did_end. We’ll come to that method in a minute.
Let’s make that spec pass:
def open_directory
panel = OSX::NSOpenPanel.openPanel
panel.canChooseDirectories = true
panel.canChooseFiles = false
panel.beginSheetForDirectory(nil,
:file, nil,
:types, nil,
:modalForWindow, nil,
:modalDelegate, @directoryController,
:didEndSelector, "open_panel_did_end",
:contextInfo, nil)
end
Pretty simple. That command will display an Open Directory screen. What do we want to do with it when we’re done? That’s where open_panel_did_end comes in. It will be called by Cocoa when the panel is closed. I want to take the directory that was selected by the user, and display it in the text box in our interface.
it "should set the directory name outlet on open_panel_did_end to the directory selected" do
@directory = mock(OSX::NSTextField)
@directoryController.directory = @directory
@mock_panel.stub!(:directory).and_return("Directory")
@directory.should_receive(:stringValue=).with("Directory")
@directoryController.open_panel_did_end(@mock_panel, 0, nil)
end
This is a kind of big test. What I’m doing is setting up the controller with the directory outlet, and making sure it gets set with the directory that panel will have set to it when this method is called. You notice that open_panel_did_end takes three parameters. This is a rule of Cocoa, but I don’t care about the second and third parameters, so we just pass 0 and nil.
Let’s make this guy pass:
def open_panel_did_end(panel, return_code, context=nil)
@directory.stringValue = panel.directory
end
You can see why I was reluctant to write more than one test. The method is done. Finally let’s build and run our app. It … doesn’t work. Aw heck we haven’t connected our outlets. We haven’t even created an object. This is where InterfaceBuilder starts to shine. In the library get an Object and drag it over to the Application window.

Open its Inspector and go to the information tab. That’s the one with with places for the Class, Actions and Outlets. It has a drop-down menu next to class - use it to select ChooseDirectory. Notice how we didn’t have to drag-and-drop the file into the app? Look at the Actions and Outlets, they just filled right in!

That’s fantastic. Now we can just draw our connections and build the app. Just do it already and run it. If you’ve done all the steps, and I haven’t messed this up, you should have an application that selects a directory and displays it in a text box. It’s not very exciting, but you now know two different ways to translate Objective-C’s methods into Ruby methods. Soon you will take over the world!
- Sometimes it takes a while for me to write a blog post.
- Doug would not find this polite. Jim would claim I’m being too nice.
- Real footnote this time - there is a gem called Rucola that can apparently free you from XCode. I haven’t had much luck getting it’s dependencies installed and can’t vouch for it.
- There’s that name again. I promise Eloy I’ll get it working one of these days.
- After beginning this blog post I discovered this method is deprecated. That said I strongly prefer it to the long method name, so I decided to leave it, and will do a little research as to the “why” it’s been deprecated. In the meantime you can use either, or objc_send. That third way is another blog post.
No Tag Backs
by: eric | July 3rd, 2008 | -2 comments »
Well Micah tagged me, and if I look at these XML request/responses for another hour without a break I’m going to pass out into my keyboard. Here goes.
How old were you when you started programming.
I had a Texas Instruments computer thingy that I got for my 6th or 7th birthday, somewhere in there. It played these educational games, but I noticed one day that if I didn’t put a cartridge in it a blue screen came up with a cursor. It had an instruction book and I would basically type in the programs verbatim, then do little things with it like change a color or a line. Later I had an Atari XE and it did the same thing, so I made the same little guessing game in it just like the one I made on the TI. Realistically I didn’t write anything of use until high school though.
Interestingly, perhaps only to me, my version of Hello World for the iPhone SDK was a guessing game.
How did you get started programming.
I guess that was the real answer. I played with my dad’s computers all the time but didn’t consider it as a career until I was about 16 or 17, when I realized I could probably get paid for it. Up until then I wanted to be a sports journalist. So I went to school so I could found my own game company.
What was the first real program you wrote?
What counts as “real”? The guessing game? Making horizontal lines appear on the screen? I wrote a bunch in Basic and Pascal for homework assignments, and like Micah had one of those TI calculators. The first specific one I can recall was a text-based adventure game I made for a homework assignment my freshman year. It was based on the Haymarket Bombing
What languages have you used since you started programming?
Pascal, C, C++, C#, COBOL, Assembly, Perl (but I won’t admit it), Java, Objective-C, Ruby, Javascript, Lisp, VB, Erlang, and I just wrote Hello World in Smalltalk (Squeak).
I too doubt I could write Hello World in most of those languages, and wouldn’t put them all on my resume. It’s funny because I probably would have when I came out of school, since I didn’t know the difference between “familiar with” and “able to write some code with”.
What was your first professional programming gig?
I started a web design company in college, which employed me and myself. I had two clients, one of whom paid me in Kung Fu lessons.
If there is one thing you learned along the way that you would tell new developers, what would it be?
Find great people to work with. If you’re the smartest person in the room, you need a new room, because if you’re not growing you’re dying. This is tricky when you’re new, since you don’t know a great developer from a tree stump, but take a look at Micah’s tag list. It looks like the list of authors in my library.
I would also tell them they should come to work for me as my apprentice, unless they weren’t any good. Then they can work for Jim.
What’s the most fun you’ve ever had programming?
Working with the team I work with now is fantastic. I also had a great time working Agile 2007 as part of RailsFest, and I’m looking forward to doing the same thing on the Live Aid stage this year.
Up Next
Sadly I don’t know many developer’s who keep blogs, so I’ll just echo Micah’s list and tell Paul, Jim, Doug and Matt they’re next.
Erlang and the OCP
by: eric | May 24th, 2008 | 0 comments »
OCP was defined in 1988 in Bertrand Meyer’s book “Object Oriented Software Construction” as follows:
Modules should be both open (for extension and adaptation) and closed (to avoid modification that affect clients)
Recently we had an issue in my office with our system which uses Rinda (a Ruby implentation of Linda) as a blackboard architecture. The architecture looks a little like this crude drawing.

This hides the OCP violation. The “rindlet,” our informal name for these subprocesses, actually removes the message from the blackboard. So if you send a message that looked like this [1, 2, 3] and one rindlet took it then no other rindlets can receive it. To repeat myself, this meant all messages had to have as their first data member the name of the rindlet they were sending the message too. This is bad. Adding another rindlet meant changing the client sending the message. Now to quote Agile Software Development: Principles, Patterns, and Practices [Martin 2003] An axis of change is an axis of change only if the changes actually occur. That is to say if only one rindlet cared about a message than this wouldn’t be an issue. When this became a problem was when more than one rindlet wanted the same message. Suddenly we have to send many otherwise identical messages to different rindlets. This is the heart of the OCP, the Server (in this case the one sending the messages), should be closed for implementation, but is not. In our case we changed the architecture to shield the server from those changes, and fixed the issue.
This brings me to Erlang and its message passing system. Last year I began playing with it, but lost interest as the difficulty of the syntax simply ruined the fun for me. I do know enough about it that when this issue came up in our ruby system, I was immediately reminded of Erlang’s message passing system. Specifically it has three methods [Armstrong 2007 pg. 134]:
spawn - Create a new concurrent process that evaluates a passed in Fun. The new process runs in parallel with the creating process.
Pid ! Message - Send a message to a Pid - returned by the previous spawn.
receive…end Receives a message that has been sent to a process.
On a cursory glance it appears we have the same issue since you must know the Pid of the process. Aha, but the command sending a message to the process actually created the process, and therein lies the difference. The blackboard architecture deliberately decouples the constantly running processes from messages, the messages are sent to the blackboard. The sender has no right to know about the constantly running process, and should not need to change to add another one. Erlang on the other hand spawns processes as if they were objects, and sends them messages. Sending messages, heck that’s what you do with an object too isn’t it? I don’t think creating an object and sending it messages is a violation of OCP, and neither is this. The sender can be extended without effecting clients. It turns out that Erlang does not intrinsically violate the OPC like I’d originally surmised, although like any other system I could easily create an architecture that did.
Promises Promises
by: eric | May 17th, 2008 | 0 comments »
“Under Promise, Over Deliver” (origin unknown)
“How are you going to get a reputation as a miracle worker if you tell the Captain the actual amount of time it will take?!?!” Scotty on Star Trek
I used to think the first statement was a just a more cynical restatement of the second, which is just a con job. Tell the boss you can’t have it done until Tuesday, finish on Friday, play golf Monday morning and deliver Monday afternoon. Everybody wins right? Except it’s fundamentally dishonest. Lately I’ve come to realize I do the first one every day, and I hope never do the second.
I have three step-children and I rarely promise them anything. It’s not because I’m a horrible father, but because a promise is a fundamentally special thing. I promised my wife I’d stay with her until the end of time, now that’s a promise. If I promise I know damn well I will do what I said, and I can’t have excuses. Now I’m naturally a very busy and easily distracted person so I know that if I promise too much, I’ll deliver a lot of disappointment. Instead I say “maybe” because it’s the honest answer. There is a huge difference between “I promise” and “I’ll try”, and I doubt “I’ll do my best” would have been an acceptable answer on my wedding day.
So what the heck does this have to do with development? I was thinking about iterations, and how the stories taken on are really a promise to the customer, but we don’t always treat them that way. A lot of teams, including at times our own unfortunately, instead Over Promise and Under Deliver. It’s usually done with the best of intentions because the customer wants more stuff done. You know what? My kids want to go to Dunkin Dounuts tomorrow, but I don’t know if I can take them so I won’t make a promise. We should look at our iterations the same way. I’m not talking about padding estimates like Scotty does, but what I’m talking about is avoid the traps of wishful-thinking when estimating stories. Specifically three things I see all the time.
- The Talk Down
The talk down usually happens when one or two team-members are out of sync with the rest of the group on the high side, but can also happen when the team’s points cover a range from small to large. Higher estimates mean higher risk and yet the lower estimates usually win this “battle.” There are two kinds of ways team members (and sometimes customers) encourage other developers down from their estimates, one good and one bad. I’ll illustrate with two stories where I was out of step with the group.
Right after I joined 8th Light we had a store that involved converting text to base64. I was inexperienced with Ruby and hadn’t done this before, so my estimate was higher than the others. At some point somebody said, “Eric that’s a method that’s built into ruby, it’s one method” and I sheepishly shrank my estimate. Hey I used to be a C++ programmer, cut me some slack! The point is this time being talked down made perfect sense. I didn’t know something, somebody told me the answer, and we fixed it.
Much more recently we had a story that involved showing the difference between two objects in the database. In this case I was again much higher than the group. I explained I had no idea how we would do this in a way that would satisfy the customer, but the team thought using the Unix diff tool on the already existing XML Output would be fine. With something feeling wrong in my gut I reluctantly brought down my estimate. A few minutes later Micah and I started on development, and discovered the problem. A few small changes to a product resulted in four pages of indecipherable XML differences. The story was scrapped, fortunately quickly before any time was invested in it.
Now what was different between the two times? In the first there was a concrete and clear way that my estimate was wrong. Yea! In the second there was still an icky feeling in my gut, yet I budged. Why? Because I don’t want to hold up my team, I don’t want to look stupid, and most importantly I failed to articulate my concerns with the approach given. You see for years I worked with InstallShield Developer, and for a while now they’ve saved their file format for projects as XML. But when two people attempted to work on the same file, then merge, it was almost always a nightmare, and this was with tools that just did diffing like Araxis Merge. Our quickly done tool to solve an immediate business need had little chance of success, but I was uncomfortable saying so. The moral: Don’t let yourself be talked down unless you really feel talked down. The team wasn’t wrong for stating how they felt, I was wrong for failing to articulate the issues I had.
- The extra points
Occasionally as a team you really want to impress the customer, and they’re in a hurry. So maybe you take on a few extra points. I don’t feel this needs much explanation, don’t “hope” you can get it all done. Use your velocity, trust your estimates, and KNOW you’ll get it all done.
- The “Ambitious” Iteration
Sometimes your iteration feels just…off. You’ve taken on the same number of points as the previous iteration, but it feels in your gut like it’s too much. Now this is where the promise kicks in. Would you promise your loved ones something that in your gut you just didn’t feel like you could deilver? Than don’t do it to your customer. When the iteration feels ambitious try to put it in concrete terms, maybe you’ve been the victim of the “talk down.”
Remember a promise is a very important, even sacred, thing. It should not be taken on unless you are absolutely sure you can do it. Try saying to yourself before an iteration, “We promise to get all this done.” If that causes a shiver to go down your spine there’s a good chance you really hope you’ll get it all done, and maybe should take a bit off the board rather than be proven right later.
Chirb Presentation
by: eric | May 6th, 2008 | 0 comments »
I gave a Chirb presentation last night on RubyCocoa, which went reasonably well. The slides, the working versions, are here. Unfortunately the images do not show in Safari, so you may want to use Firefox.
Bowled Over by RubyCocoa
by: eric | April 20th, 2008 | 28 comments »
Last year I wrote a RubyCocoa tutorial that’s been aggregated in a few places and referenced a couple times*. By my standards it was an overwhelming response. A few things have changed since then, most notably Mac has embraced Ruby. It’s installed with Leopard, RubyCocoa has been put on it as well, all of which is great news. The drawback is that my tutorial has gone out of date, as XCode has changed too. Guess I’m gonna have to write a new one.
Naturally my first thought was to update the original tutorial, with new pictures, but I’ve got two problems with that. One, it’s boring. Not for you - for me! Large portions of it haven’t changed aside from some differences in the screenshots and installation. Why should I explain what Cocoa is again? I just couldn’t get motivated. The second is that I have an issue with the way programming APIs are taught. Why is it that developers, such as myself, who have embraced testing abandon it in example code? This is especially true in GUI code, where often the simple examples have more complicated tests. Unit testing is so important we should be able to teach APIs Test-First, and in that spirit we’re going to a classic example of TDD using RubyCocoa. This should teach you how to get up and running and well as make the tutorial a heck of a lot more interesting. For me anyway.
Bowling
If you’d like to see about 4000000 examples of the bowling game head over to Ron Jefferies website at xprogramming.com. It’s a typical example of solving an algorithmic problem using TDD, and often used as a kata or practice session. We’ll do this following Uncle Bob’s three rules of TDD:
- You are not allowed to write any production code unless it is to make a failing unit test pass.
- You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
- You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
We’ll use RSpec for this exercise.
Basics
If you aren’t familiar with Cocoa at all, take a peek at the “What the Heck is Cocoa” section here.
Installation
If we want to make an awesome bowling game using RubyCocoa we’re going to need to install RubyCocoa. This tutorial is assuming you’re using Leopard, which means you have two steps. The first is to install XCode from the disc that came with the operating system. I’m not going to explain that here, I assume you can open a disc and click an installation. For adding RubyCocoa so we can write this slick Mac App you have three options:
- Install from source. A big part of the reason you haven’t seen this doc earlier is because I’ve repeatedly attempted to install from source, and failed miserably before getting it right.
- Install from the latest binary release. That’s found here.
- Do absolutely nothing, say it again. If you’re on Leopard, it’s already there for you.
Step three sounds tempting but there’s a catch. If you’ve used MacPorts to update ruby, you may find that your Ruby and RubyCocoa installations don’t match up. See Verifying your installation below. Because of this I highly recommend the “do nothing” choice if you can get away with it. The latest Apple Software Update even updated the bridge, so you won’t be very behind anyway.
We also need RSpec as we’ll be using it for our unit testing.
sudo gem install rspec.
The great thing about RSpec is it reads extremely well to the uninitiated, so I won’t be explaining RSpec as I go.
Verifying your installation
After installing however you want to install, go to irb and type require ‘osx/cocoa’. If you get true then your system is setup properly for rubycocoa development. If not you may need to tweak some environment variables, or worse install from source. I’ll have a blog post on that soon.
Your first project
We’ll need to create a new RubyCocoa project. Start up XCode and create a new Cocoa-Ruby project.

Your screen will probably look different, unless you have the iPhone development kit installed too. The important thing is that you select Cocoa-Ruby application. Create the project with whatever name you like, as long as you call it bowling. This will generate an application skeleton in XCode. Let’s create our super slick bowling game interface in Interface Builder. Double Click Main Menu.nib in your XCode project file. From there you should get windows like the following (I’ve arranged them to fit the window better):

Your Window won’t be there yet. In the Nib Document window, that’s the one with MainMenu.nib on top, double-click the Window icon. That Window represents your dialog box. You can see it on the screen in the picture above. Now select the Window icon again and hit Apple-Shift-I to bring up the Inspector for that window.

This shows the properties for the Window at the moment, but will change whenever you select a different object. Change the name of the window to bowling now. Our bowling game is on the honor system. You enter your score, press roll, and it tells you the running tally of your current score and your current frame. This is a little different than the typical implementation, since those simply spit out a total score after all your rolls. First you need a button so lets select a push button from the Library and drag it to the window. The easiest thing to do is in the bottom spotlight window type Push Button and it will find that button for you.

Drag the push button onto your window. You can rename it to roll simply by double-clicking on the button and changing the text. Let’s make a dialog that looks like this:

I admit not my best work as designs go, but the focus of this tutorial is test-driven GUI code not Interface Builder. This dialog is made up of one Text Field and five Labels. You should be able to search for them just like you did for the Push Button. The important thing to remember is that there are four labels on the bottom. Two for the headings (Score and Frame) and two for the actual totals (currently 0 and 0). Congratulations we have our dialog box. If you go back to the XCode view and click Build and Go you’ll see the exact same view. Of course nothing does…anything. That’s why we need to write some code…er tests. Remember rule #1:
- You are not allowed to write any production code unless it is to make a failing unit test pass.
Normally at this point we’d start making outlets, actions, and connections but we’re not going to do that here. The reason? We don’t have tests. Have I said that enough yet? To get up and running with RSpec it’s really best to open up your project in something like Textmate but since this is a tutorial and I can’t make you use my machine I’m going to assume you’ll be creating your files in XCode and running the specs with the terminal. Given that we have a view I think it’s safe to assume we’ll have a controller. Create a file called bowling_controller_spec.rb in the root of your project. As a rule you’ll want have a separate location for your specs, but this will work just fine for our project. If you’re using the XCode interface you can use the Ruby test case class, we’ll be removing all the code anyway so it doesn’t really matter, the important thing is to create the file. Do not add it to the Bowling target, this isn’t shipped as part of the product. Our first spec is going to have well - nothing. Remove any generated code in that spec and replace it with this:
describe BowlingController do end
To run it you can use the terminal and type spec bowling_controller_spec in your Bowling directory. You should see this:
$ spec bowling_controller_spec.rb
./bowling_controller_spec.rb:9: uninitialized constant BowlingController (NameError)
from /opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.3/lib/spec/runner/example_group_runner.rb:14:in `load'
from /opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.3/lib/spec/runner/example_group_runner.rb:14:in `load_files'
from /opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.3/lib/spec/runner/example_group_runner.rb:13:in `each'
from /opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.3/lib/spec/runner/example_group_runner.rb:13:in `load_files'
from /opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.3/lib/spec/runner/options.rb:85:in `run_examples'
from /opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.3/lib/spec/runner/command_line.rb:19:in `run'
from /opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.3/bin/spec:4
from /opt/local/bin/spec:16:in `load'
from /opt/local/bin/spec:16
Congrats! You’ve got a failing test. What do we need to do to make that pass? We need a controller of course. Create a new class and call it BowlingController (bowling_controller.rb). You need to use XCode this time and make sure you add it to the Bowling Target, otherwise it won’t be executed later.


The class should look like this:
class BowlingController end
Run the test - we …still don’t pass. We’ll need to require that bowling controller in our spec.
require 'bowling_controller' describe BowlingController do end
Well man we’re cooking with gas now. What does a BowlingController do? Well let’s go over some Cocoa concepts. In Cocoa objects have actions and outlets. An action is a method in your object that can be triggered by another Cocoa object. An outlet is a reference to another object that was instantiated by Cocoa. Put more simply actions are methods, objects are things. So let’s look back at our glorious UI design.

Ahhhh. I could look at it all day. There is one action here, the pushing of the roll button. There’s three outlets: the score, the frame, and the number of pins. Can you see the difference yet? Since we’re test driving the app we’re going to start with the action. First let’s write a test. Put this between the describe … end block in your spec:
before(:each) do @controller = BowlingController.new end it "should roll a ball" do @controller.roll end
There’s a couple things worth paying attention to here. The before(:each) block will create the controller for each test. I think it’s a safe assumption we’ll have more than one. Second notice that our it block isn’t a coherent test yet. So why do we stop? Because when we run that test it fails - roll is not a method. That’s enough to make us write some code to make the test pass. These cycles should typically take less time than it does for me to explain them. Now I know this seems stupid, and I almost certainly wouldn’t write my tests at this granular a level if this wasn’t an example, but when I write my tests this small a few things happen. Firstly my code is almost always better. The larger my tests the more room for error. The second is my tests tell a story, which can be followed by the next guy through my code to see what I was doing. Finally whenever I mess up (quite frequently) I can always go back with a couple undos. Now quit you’re whining and let’s make the test pass.
class BowlingController def roll end end
See that wasn’t so hard. Now let’s make that test more useful. When we roll a ball we get the value from the Text Field on the screen. We use outlets to reference other Cocoa objects, so we’ll need an outlet that references that Text Field. Let’s call it pins. To get a value from a Text Field we can call one of many methods on the NSTextField class, in this case we know it is going to be an integer so let’s use the intValue method. This is demonstrated with a mock object, which is built into RSpec, and we’ll be adding this to our test.
it "should roll a ball and get the value from the pins outlet" do
mock_text_field = mock('Pins')
@controller.pins = mock_text_field
mock_text_field.should_receive(:intValue).and_return(0)
@controller.roll
end
I’m using the same test I did before, only I’ve extended it. I’ve said I should have a mock that receives the value intValue when the roll method has been called. What I love about this test is that it explains just how data is retrieved from the pins outlet, in an executable way. Now lets run it…kaboom! There’s no pins= method. Broke my own rule didn’t I? We don’t have a method pins=, but we also know that mock object is going to fail. That’s two failures not one.
class BowlingController attr_accessor :pins def roll end end
Okay we’ve got a new error: ‘Pins’ expected :intValue with (any args) once, but received it 0 times. This is great, let’s call it and get it to pass.
class BowlingController
attr_accessor :pins
def roll
@pins.intValue
end
end
Okay we’ve got a passing test, but do we have a useful controller? I should say not. None of this code is aware of Cocoa, and we can fake this out all day but at some point we have to make this accessor a true outlet. The question is how do we make this object cocoa aware?
A quick lesson on the Cocoa class hierarchy. The base class is NSObject, which is represented in RubyCocoa as OSX::NSObject. In order to know about outlets, actions, and any grand Cocoa thing we’ll need to make our class a Cocoa object. So before continuing to make roll more useful, let’s write a test for that.
it "should be an OSX::NSObject" do @controller.is_a?(OSX::NSObject).should == true end
Run that spec and you get…hmm, uninitialized constant OSX. We’re going to need to require the files because even though when you’re running a RubyCocoa application everything is included for you we’re running our tests independent of the application. Require ‘osx/cocoa’ at the top of bowling controller. Ah here it is:
'BowlingController should be an OSX::NSObject' FAILED
expected: true,
got: false (using ==)
./bowling_controller_spec.rb:18:
Make it inherit from OSX::NSObject and we’re good to go. See that? We just made a Ruby object inherit from a Cocoa object. Pretty cool eh? Now about that accessor - pins. I mentioned earlier that Cocoa uses outlets to communicate with the other objects in it’s world. An accessor may make our test pass, but it won’t make our application work. We need it to be an outlet, and there we’ve got ourselves a problem. You see outlets aren’t really anything special at all from a programmatic perspective. We wire those parts together in Interface Builder, save it to the Nib file, and when the Cocoa application starts up it figures out everything it needs to instantiate. In fact in Objective-C they are declared with an empty macro, in RubyCocoa we use the command ib_outlets which just makes a writer attribute on the class. So how do we test this? Unfortunately, we don’t, breaking rule #3. You see we could write everything without the tags, but Interface Builder wouldn’t magically find the attributes so we’d have to add them manually. Since tagging these objects as outlets doesn’t actually change behavior you can grind your teeth to tiny nubs and change the pins to an outlet:
class BowlingController < OSX::NSObject
ib_outlets :pins
def roll
@pins.intValue
end
end
We’ve got one other issue here, roll isn’t marked as an action. In the same vein as ib_outlets we’re going to mark this as an action with the ib_action delcaration.
ib_action :roll def roll @pins.intValue end
Also worth noting is that every Cocoa action has a sender, sent as a parameter, but I’ve omitted that here as we won’t be using it so it’s not necessary. The typical Cocoa style is to keep it in as a parameter, because standard Objective-C Cocoa needs it, but I don’t understand why we need the clutter. From this point forward we need to implement the rest of the controller. This blog is getting exceedingly long, so I’m going to just put the tests and the code, one at a time, until our controller is implemented.
Note I’ve added the mocks to the before(:each) because I’ll need them more than once.
test
before(:each) do
@controller = BowlingController.new
@bowling = mock('Bowling')
@text_field = mock('Pins')
@text_field.stub!(:intValue).and_return(10)
@controller.pins = @text_field
end
...
it "should have an outlet to a bowling object" do
@controller.bowling = @bowling
end
code
class BowlingController < OSX::NSObject ib_outlets :pins, :bowling
test
it "should send the pin value to the bowling object" do @bowling.should_receive(:roll).with(10) @controller.roll end
code
ib_action :roll def roll @bowling.roll(@pins.intValue) end
OOPS! Better setup the bowling object in the before each.
test
before(:each) do
@controller = BowlingController.new
@bowling = mock('Bowling')
@text_field = mock('Pins')
@text_field.stub!(:intValue).and_return(10)
@controller.pins = @text_field
@controller.bowling = @bowling
@bowling.stub!(:roll)
end
it "should have an outlet to the score" do
@score = mock('Score')
@controller.score = @score
end
code
class BowlingController < OSX::NSObject ib_outlets :pins, :bowling, :score
test
before(:each) do
...
@bowling.stub!(:roll)
@bowling.stub!(:score).and_return(100)
@score = mock('Score')
@controller.score = @score
@score.stub!(:setIntValue)
end
...
it "should update the score with the new score from the roll" do
@bowling.should_receive(:roll).ordered
@bowling.should_receive(:score).ordered.and_return(100)
@score.should_receive(:setIntValue).ordered.with(100)
@controller.roll
end
I want to pause and point out we’ve got a new method here. This is where our tests come in handy. We can see just from looking at the tests that setIntValue and intValue are called on outlets to get and set values from them. We’re using mocks to demonstrate how we use that API, and by the way we’re building our tests we can see our tests tell the story of how this controller was built. You should also see I’ve made a bowling object, the Model in the MVC setup, that is also an outlet. I’ve done that because once we’ve setup this controller and that object in Interface Builder, the Cocoa framework will properly handle the creation of the objects if they are outlets. Back to the code….
code
ib_action :roll def roll @bowling.roll(@pins.intValue) @score.setIntValue @bowling.score end
test
it "should have an outlet to the frame" do
@frame = mock('Frame')
@controller.frame = @frame
end
code
class BowlingController < OSX::NSObject ib_outlets :pins, :bowling, :score, :frame
test
before(:each) do
...
@frame = mock('Frame')
@controller.frame = @frame
@frame.stub!(:setIntValue)
@bowling.stub!(:frame).and_return(9)
end
...
it "should update the current frame with the frame from the bowling object" do
@bowling.should_receive(:roll).ordered
@bowling.should_receive(:frame).ordered.and_return(9)
@frame.should_receive(:setIntValue).ordered.with(9)
@controller.roll
end
code
def roll @bowling.roll(@pins.intValue) @score.setIntValue @bowling.score @frame.setIntValue @bowling.frame end
Great! We’ve done it. We’ve implemented a controller that plays bowling. Unfortunately since it uses a bowling object we haven’t created it doesn’t actually …do … anything yet. This blog post is really about RubyCocoa and not about bowling, which is an article on it’s own. So I’m going to just write a copy of bowling here and if you want to use it just save it into the same directory as your controller, although I recommend writing your own.
So we’ve got a controller and a model, now we must make Interface Builder aware of it and build our wicked awesome application. That’s right, it’s wicked awesome. Open up Interface Builder and make sure you’ve got the Library window open. Go to Objects & Controllers and choose the an NSObject.

You’ll need to create two of these, one for each class in your application. Remember how they inherited from OSX::NSObject? Well drag the first NSObject over to the Nib Document window. Using the inspector name it BowlingController. Then, and this is the cool part, open finder and drag the bowling_controller.rb file into the Nib Document window. There will be a brief pause then open the Inspector again. You should see something like this:

See those outlets and actions? Previously we had to do all that in Interface Builder, and get it right the first time, otherwise regenerate it. There were ways around it, but I much prefer this way. Anytime you’ve changed the outlets and actions you simply drag the new class. Now do the same thing with the bowling class. The outlets and actions are are in the Nib File, along with their associated implementation, but your Cocoa application still doesn’t know how are they connected. Pause and take a minute to think about this, how does BowlingController know what pins points to? How about bowling? The answer is it doesn’t, we’ll be embedding that information into the Nib file here. To do that you drag from the item that needs to know something to the item it needs to know about. Let’s try this with our famous action, the Roll button. Hold the ctrl key and drag to the bowling controller. Unfortunately I can’t get a screenshot since I can’t ctrl-drag and take the nice shot at the same time, but what you should see is a blue line from the Roll button that you’ll drag to the bowling controller. When you let go the screen should flash Received Actions roll:, click the roll. To verify completeness open BowlingController in the inspector and click the Connections tab, that’s the blue circle with the error in it, and you should see something like this:

Under received actions it shows that roll: is connected to Push Button (Roll). Embedded in the Nib file is the information Cocoa needs to send the message roll to BowlingController when the button is pushed. Now we need to connect the rest of the conections. Connect from the BowlingController to the pins Text Field, the score, and the frame. Finally connect from BowlingController to the Bowling object. Remember you’re going from BowlingController to the other objects because BowlingController is using those outlets. Each time you’ll be asked to pick the proper outlet, and if you named your outlet properly this should be obvious. You should see this in your inspector for BowlingController when you are done.

Well build that puppy. Holy cow it works!
Well it should. If it doesn’t you may have made one of the classic blunders:
- Did you make sure that bowling_controller.rb and bowling.rb are in your build target?
- Do all your tests pass?
- Did you save your Nib file?
- Are all you connections drawn?
Well that about does it for me, I hope this helped you learn a bit about TDD and a bit about RubyCocoa. Here’s a quick review:
- What is Cocoa? What is RubyCocoa? (check my earlier blog)
- Installing RubyCocoa.
- Test-Driving your first controller.
- Basics of Outlets.
- Basics of Actions.
- Connecting Outlets and Actions.
- Instantiating Cocoa Outlets.
- Importing Ruby classes into a Nib file.
- Inheriting from NSObject
- Getting a value from an outlet.
Here’s hoping this helped put to bed the myth that GUIs can’t be tested as well.
* RubyInside thanks for the cite of my original tutorial. For future reference my last name is Smith, which is actually more anonymous than “X”.
Lessons of a Craftsman: Are you Test Driving, or just writing tests?
by: eric | January 7th, 2008 | 0 comments »
Recently I wrote the beginnings of a blackjack game in Java, and I found myself making what I believe is a common error. The Java gameplay mechanic uses a state machine to manipulate the deck. As I was implementing the state machine I found I needed a Card object, in addition to my Card3DObject which actually drew the card, a look-up table for the 3D cards, an interface for the Deck and an object representing the Deck (so I could mock it out), and when I came across the situation for an Ace I decided a needed an object responsible for computing a Total in order to handle the situation of an Ace being a 1 or 11.
Apparently an if statement would cause an irreversible hand cramp, ending my programming career.
If you’ve ever done the bowling game, and really why haven’t you, there’s more than a few ways to skin that particular cat. Ron Jefferies has done it about [four thousand different ways] (http://www.xprogramming.com/xpmag/index.htm), whereas Bob Martin typically teaches a simple one. While none of them are wrong, I’m partial to the Martin version because it’s a simple problem, and it deserves a simple solution. I can give that version to a college student, and he can understand it. Furthermore in that version the tests drive the design. Let’s go back and look at my blackjack game to see what I mean.
When writing the game I decided blackjack would be a FSM. I drew a couple of diagrams, then used the Java state machine generator to make my state machine. The problem, as I see it, is that I did this without writing a line of code. Furthermore as I was coding I was thinking two steps ahead, and making design decisions before I needed to. I did a mini-version of the BDUF, and it’s something I see people do all the time. I was writing test first but I wasn’t always letting tests drive that design. Frankly that’s not necessarily a bad thing, and virtually all large systems need some design as a sort of guide, but what I should have done is wait until the code forced me into the state machine, forced me into other objects, etc. It’s not the end of the world, and in the end I may even have made the same decisions I would have anyway, but given that I didn’t let my tests drive my design I probably won’t end up with the simplest thing that could possibly work. That’s a shame.
Want clean code? Stop using the editor.
by: eric | December 21st, 2007 | 3 comments »
Recently I was adding some accessors to a ruby class on the fly, and I kept getting confused by this block:
eval <<-eof def>
The code isn’t particularly complicated, just creating a quick accessor to get at the underlying hash. Yet I had a couple bugs simply because without the editor to give me hints, the code was that much harder to follow. This turns out to be a blessing in disguise, as I am forced to write extremely clean code just to keep from confusing myself. Opening up the String class cleans this up a bit, and removes duplication:
eval <<-eof def>
There much better. So the next time you think your code isn’t as clear as it could be, or maybe if you think it’s perfect, try reading it without any syntax highlighting. If you can still follow it quickly and easily, then maybe it doesn’t entirely suck.
Test Driven Debugging
by: eric | October 11th, 2007 | 0 comments »
I hate debugging. Loathe it, despise it, pick your synonym and I’ll use it. Computer programming is building something out of nothing, making the computer do things it didn’t know how to do, until I told it. I absolutely love code refactoring, moving code around, organizing it better, cleaning it up and watching tests pass. But stepping through code looking for the place where I accidentally typed quesiton instead of question? Shoot me in the head. In addition to the frustration of debugging, a bug can only be explained by one thing: I screwed up. I hate screwing up even more than I hate debugging. My hatred of debugging is one of the reasons I started practicing TDD. After all Test Driven Design means I never debug right?
Of course we all debug some of the time, usually as a deadline hangs over our heads. This tends to be where practices break down. You hack and slash, desperately trying to make the program JUST WORK only to watch it fail and fail again. Eventually you get the bug fixed, probably with an ugly hack right before (or right after) a customer demo. I won’t claim that “Test Driven Debugging” is a solution, but it certainly helps me in times of need.
Let me take an example from real life. As our last iteration ended I was on a roll. I had a TODO list of items and everything kept clicking into place. I’d implement a feature, and it work the way I wanted to the first time. There was just one last part of the story, moving the items on the screen. I wrote a test, it passed. I wrote another, made it pass. I got everything working the way I wanted too - then tried the actual application, and it went boom. Moving just wasn’t working the way I expected. Items would jump around the screen seemingly at random. I realized what the bug was - items retrieved from the database were not coming back in the right order. So how do I go about fixing it?
Well I don’t always practice what I preach, so I started hacking and slashing. I threw order_by and find statements around, and even wrote a method that wasn’t tested in a desperate effort to make the demo. Of course I didn’t make the demo, and then sat down and calmly did what I should have done. I wrote some tests. Well first I wept quietly, but that’s none of your business.
In our application there’s an ActiveRecord called Design, and it has Widgets which use acts_as_list to keep track of themselves within the Design with a position. Don’t worry about the details if you aren’t familiar with Ruby on Rails, the important thing is the steps. First I wrote a test in the Design.
it "should order widgets by position" do widget1 = Admin::Widget.create(:design => @design) widget2 = Admin::Widget.create(:design => @design) widget3 = Admin::Widget.create(:design => @design) widget3.insert_at(0) widget3.save @design.reload @design.widgets[0].id.should eql(widget3.id) @design.widgets[1].id.should eql(widget1.id) @design.widgets[2].id.should eql(widget2.id) widget3.position.should eql(0) widget1.position.should eql(1) widget2.position.should eql(2) end
Hmmm… it passed. That’s interesting. It’s coming back correct from the model. I guess it’s time to write a test in the controller:
it "should have the widgets ordered by position - requires real data" do question = Admin::Question.create(:name => "question") design = Admin::Design.create widget_pos2 = Admin::Widget.create(:question => question, :design => design) widget_pos1 = Admin::Widget.create(:question => question, :design => design) widget_pos2.position.should eql(1) widget_pos1.position.should eql(2) widget_pos2.insert_at 2 widget_pos2.save! widget_pos1.reload widget_pos2.reload widget_pos2.position.should eql(2) widget_pos1.position.should eql(1) get :edit, :id => design.id assigns[:design].should be_instance_of(Admin::Design) assigns[:design].widgets[0].position.should eql(1) assigns[:design].widgets[1].position.should eql(2) end
There’s a couple things worth noting in this test. I used real data instead of mocks, although RSpec style would typically use mocks. The reason I didn’t use mocks is that while they are great at decoupling data just like this, in the case of a bug I could very well pass my mock, only to discover that I’ve been calling the wrong methods all the time. I want the real data here. Some would argue this doesn’t make it a Unit Test, and I’d be hard pressed to disagree, but it still is a valuable test. The second is that I’m doing should eql before I call get, which is the method under test. The reason for that is I want to test my assumptions. Often times when you have a bug it’s because you made a mistake in your assumptions, such as thinking the widgets were always being returned in position order, and I want to tease out any issues in mine. The last thing I need is a test that passes by coincidence.
So I ran the test - and it passed! Then I started the application again, and it worked! Did tests have a magical power that fixed the bug? Of course not. I had fixed the bug during my hacking and slashing, but I was frantic so I hadn’t calmly restarted my server and had a passing test. Had I done this from the get go I would have recognized the bug ( which was using an explicit design.widgets.find(:all) instead of design.widgets, thereby retrieving the data from the DB in id order ) and likely passed the demo. Once again lesson learned, sometimes I have to learn more than once. I’ll clean up the test above to remove the now unneeded extra checking, but I’ll leave it in the code, so that this bug never shows itself again. Thou art commanded - never ever reintroduce a bug. Now go forth and program my son.
#




