Sit back, relax, and enjoy the code.

TDD Makes Software Go Faster

Posted: August 24th, 2009 | Author: Brad | Filed under: Programming, Testing, tdd | Tags: | No Comments »

One of the gripes I hear about TDD is that it takes too much time. People look at the idea of it and think, “So I have to write code and tests and update the tests when the code changes? WTF?”

My message to you is: TDD takes less time, not more.

Today’s example: I’m writing some code that uses a parsing library written by a cow-orker. He’s a sharp guy, and the library generally works well, but it has a couple of undocumented behaviors – they’re mostly benign, and probably work for other users of the library, but for me it’s stuff that would result in misbehavior way up the call stack, or in another module entirely.

While I’m test-driving the code that uses this library, I notice the library itself does not have automated tests. The natural-feeling thing for me to do here is to test some sample calls to the lib to make sure it does what I expect. I know it’s not exactly canonical behavior to test outside libs that are assumed to be functioning, but it is good form to write tests that teach you about the system you’re building, and I needed to learn whether this library was going to parse my input in the way that I expected. The documentation wasn’t there, I wasn’t going to figure it out by inspecting the code (which is relatively complex), so tests it was.

Surprise, surprise – I found out that the library did NOT behave as I expected in every case. Had I not taken twenty minutes to write tests to introduce confidence in the parts of the system I didn’t know well, I’d probably have spent a couple hours debugging and looking in the wrong places for the problems I was having downstream. It also led me to a relatively simple solution where I extended the library class and just overrode the elements related to my handful of problematic cases, without changing his library or breaking code that depends on it.

As an added bonus, not only do I know what the documentation does not tell me, but I’ll also know if and when my colleague makes changes to his library that break the expectations of my code.

So I’ve reduced debugging time, increased my confidence in my code, and protected myself against future changes. I see it time and again – the time saved by writing the extra test code is well out of proportion to the time spent writing it.

There’s an exception here for developers or shops that are fetishistic about 100% test coverage, and do not judiciously use automated testing to learn about the system, drive design, and catch regressions. Writing tests to cover trivial/obvious code (i.e., writing tests that do not teach you about the system) is a time-suck. I’d avoid it, if I were you.

As long as I’m raving about TDD, I have to recommend the work of Kent Beck. I follow him on Twitter, I read his blog, and his book on TDD changed how I write software – I count it among the indispensible books on my shelf, with the GoF Design Patterns and Knuth. Check him out if you’re interested in deep thought about how software gets made.

  • Share/Bookmark

Quick Hits: Unit Testing iPhone Apps

Posted: July 5th, 2009 | Author: Brad | Filed under: Programming, Testing, iPhone | Tags: , , , , | 8 Comments »

I have a few things to add to the woefully incomplete official documentation on setting up automated tests in your iPhone apps:

  1. You need to add your main application executable target as a direct dependency of the test target, so that you’re always testing against your latest build. Do this by double-clicking on the test target, going to the “General” pane in the properties dialog, and adding your app under “Direct Dependencies”. (This was actually mentioned in the OCUnit tutorial for Cocoa, but not the one about iPhone testing.)
  2. Your linker needs to know about the objects you’re testing. An easy way to do this is to add the .m files for those classes to the “Compile Sources” group in your test target. You’ll also have to make sure you link against any frameworks used by these objects. (You could also tell your app target to export all symbols, then link your test target to it as you would a library.) (Thanks to Chris Hanson for pointing out this procedural improvement in comments.) You need to explicitly link the object files of the classes you’re testing. These are the “.o” files in your build folder. To do this: Double-click on the test target, go to the “General” pane, add a new item under “Linked Libraries”. In the dialog that pops up, choose “Add Other…” and add your class’s .o file.
  3. When you run your tests, one failure looks like two: Failed tests show up in Xcode as errors (just like compile errors, &c). Any test failure triggers a second error, and you’ll see something like “Failed tests for architecture ‘i386′ (GC OFF)”. The docs never say so, but this appears to be normal. Fix the failing test, and it goes away.

Anything else to add? Drop us a comment!

  • Share/Bookmark

UINavigationController Tricks

Posted: July 3rd, 2009 | Author: Brad | Filed under: Programming, iPhone | Tags: , , , , | 4 Comments »

For an iPhone UI I’m developing, I need to have one UINavigationController nested inside another, and to have the inner UINavigationController’s events push a view on to the outer one’s stack. CocoaTouch didn’t give this to me for free, but there was a simple solution.

This post assumes that you’re familiar with the fundamentals of iPhone programming, including view controllers, UINavigationController, and delegates. There is sample code for this post, which is released under version 2 of the WTFPL.

The Problem

I’m working on a multi-step UI for a game. Expressing these steps as a regular drill-down table-style UI on the iPhone felt cumbersome, and games can’t afford for processes to feel cumbersome; people will stop playing. One solution that occurred to me was batching related sets of steps in a smaller navigation table – so in Step 1 you’d drill through substeps 1A, 1B, and 1C before moving to Step 2. The fact that the whole view wouldn’t be replaced with every choice seemed like it would be less destructive of the user’s mental context, and the chunking of substeps should make it easier for the users to wrap their heads around the process. (No word yet on whether this solves my UI problem, but I like it so far.)

My UI solution contained its own technical problem, though: If I’m expressing the process steps in a UINavigationController, and expressing the substeps in a nested UINavigationController, how does the inner navigation controller notify the outer one that the user’s last substep choice completes that step and it’s time to move to the next step – or in programmatic terms, how does the inner UINavigationController tell the outer one to push a new view onto the outer one’s stack?

Or, putting it more visually, how do I get from here:

navcontricks1

…to here:

navcontricks2

In the non-nested situation when you wanted to push a new view onto a UINavigationController’s stack, you’d do the following in the current view:

[self.navigationController pushViewController:nextViewController animated:YES];

So in my nested case, I need to do that, but pushing onto the outer navigation controller’s stack from a view controller on the inner navigation controller’s stack. I tried a number of naive (but sensible-seeming) targets for the pushViewController:animated: action, such as:

self.navigationController.navigationController
self.navigationController.parentViewController.navigationController

Nothing worked. I set a breakpoint and drilled down through the members of self.navigationController, and no path to that outer UINavigationController was apparent.

The Solution

While investigating the innards of UINavigationController, I stumbled upon a writable property that looked like it might help: The delegate. When creating the inner UINavigationController, I added one line of code:

innerNavCntlr.delegate = self; // THIS IS THE MAGIC, PART 1

Keep in mind that this is called in the view controller on top of the outer navigation controller’s stack, so “self” has access to the outer navigation controller.

When the view on top of my inner navigation controller’s stack is ready to signal the outer navigation controller, I do the following:

// THIS IS THE MAGIC PART 2
UIViewController *topVC = (UIViewController *)self.navigationController.delegate;
[topVC.navigationController pushViewController:nextCntlr animated:YES];

A couple of notes: First, the view controller that creates the inner UINavigationController must implement UINavigationControllerDelegate, or you’ll get a compiler warning – but you can just declare that it does so in the header file, as none of the methods in that interface are required.

Secondly: If you’re like me, this feels like an abuse of the delegate property. Now there’s no reason that you couldn’t actually use that object productively as the inner navigation controller’s delegate – I just haven’t done so here. And the fact that the delegate property has to be casted to be used this way says to me that it wasn’t meant for this – explicit casts are always a code smell. (Anal-retentive types might want to put in some type-checking around that cast for safety.)

That said, it works, and I haven’t run into a maintainability problem yet, as this code doesn’t really get re-used in many places. Were I expecting to use this trick often, I might package up a subclass of UINavigationController (call it NestedNavigationController) that actually took an outer UIViewController or UINavigationController property. Then again I’m finding that in Cocoa, subclassing is often a code smell…

Got a better solution? I’m interested – please leave a comment below!

Update: Whoops. Comments are enabled now.

  • Share/Bookmark

Google Maps events in Mobile Safari and PhoneGap for iPhone

Posted: April 29th, 2009 | Author: Brad | Filed under: Google Maps, HTML, Javascript, Programming, hacks, iPhone | Tags: , , , , | 3 Comments »

Having trouble getting your Google Maps div to respond to events like you want in Mobile Safari or a PhoneGap app for iPhone? So was I. Disabling pinch-zoom is simple enough, but getting a finger drag to (a) not move the map and (b) draw something on the map was a major pain. I share my solution below: Proxying events through a transparent div overlaid on the Google Maps div.

To play along at home, you’ll need your own Google Maps key or you can just aim your mobile browser to my example code at http://kickasslabs.com/examples/gmap_events.html. (Note that this will not work in a regular desktop browser.) Besides a <script> tag importing the GMaps JavaScript, you should not need any other libraries or tools besides Mobile Safari to view and use the example page. If the page is zoomed way out when you start, just double-tap the map tile in the upper-left corner – it should zoom to fill your viewport.

What you should see is a map tile with a line painted on it. If you touch the screen, you should see one end of the line follow your finger.

It looks simple but I had a bit of trouble getting it to work, because touch events are not like mouse events (curious as to why?), and GMaps doesn’t respond to touch events by default.

Step by Step

First, you need 2 divs:

    <!-- This div holds our map -->
    <div id="map" style="width: 320; height: 320px"></div>
 
    <!-- This div lies on top of the map and acts as an event proxy -->
    <div id="mapoverlay" style="height:320px; width: 320px; position: absolute;"></div>

And you need to position one div over the other:

    mapDiv = document.getElementById('map');
    mapOverlayDiv = document.getElementById('mapoverlay');
    mapOverlayDiv.style.top = (mapDiv.offsetTop + 0) + 'px';
    mapOverlayDiv.style.left = (mapDiv.offsetLeft + 0) + 'px';

You set up the map div like you would for any other GMaps-enabled page:

    // the map
    _map = new GMap2(document.getElementById("map"));
 
    // coordinates for home base
    _lat = 37;
    _lng = -95;
    mapCenter = new GLatLng(_lat, _lng);
    _map.setCenter(mapCenter, 15);

Set up the overlay div to respond to touch events by firing a custom event for your map, e.g.:

    mapOverlayDiv.ontouchstart = function(e) {
      GEvent.trigger(_map, 'customTouchStart',
        (e.touches[0].pageX - mapDiv.offsetLeft),
        (e.touches[0].pageY - mapDiv.offsetTop));
    }

Now have your map respond to that event:

    GEvent.addListener(_map, 'customTouchStart', mapTouchStart);

…where mapTouchStart is a callback function that does something useful in response to a touch:

    function mapTouchStart(xPixel, yPixel) {
      redrawLine(xPixel, yPixel);
    }

And… well, then you’re done. My example also responds to the touchMove event and has a little code for drawing lines, but you’ve seen all you need to know to get event proxying up and running for your app.

Got a question? Got working code for an easier way? Drop me a line in the comments!

  • Share/Bookmark

Quick Hits: Setting the User Agent Header in Webrat

Posted: March 31st, 2009 | Author: Brad | Filed under: Rails, Testing, ruby | Tags: , , , , | 1 Comment »

If you’ve read the new PragProg beta e-book on RSpec, you may have read that you can set HTTP headers for your Webrat request like so:

Given /^I am browsing the site using Safari$/ do
  header "User-Agent" , "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us)"
end

Like me, you may have found out the hard way that this doesn’t work. Webrat does not automagically apply these new HTTP headers to your request – they certainly don’t make it to my controller. What worked for me:

Given /^I am browsing the site using Safari$/ do
  headers["User-Agent"] = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us)"
end
 
When /^I visit my precious site$/ do
  get '/my/precious/path', my_query_string, headers
end

In the code above, headers is a method call that returns all the HTTP headers for your request. Just tack headers on as the third argument of your request, and you’re good to go.

  • Share/Bookmark

Ruby/Hadoop talk on Tuesday

Posted: March 8th, 2009 | Author: Brad | Filed under: Events, hadoop, ruby | Comments Off

A note for interested parties: I (Brad) will be giving a short (10-15 minute) talk on using Ruby with Hadoop for distributed computing. The plan is to give an ultra-brief description of the MapReduce algorithm and Hadoop, show 2 examples of working code (including one with Wukong, Flip Kromers Hadoop Streaming wrapper), and closing notes on my attempts to use JRuby to create Hadoop jobs.

The talk will be on Tuesday at the NYC.rb meeting, 7:00 at Bway.net’s offices. Get there early for a seat, the last one was packed.

  • Share/Bookmark

Playing with JRuby, Part 1A

Posted: February 18th, 2009 | Author: Brad | Filed under: Programming | Tags: , , | Comments Off

First, thanks to Lopex, Charles/Headius, and Thomas for their well-coordinated effort to alleviate some of my JRuby ignorance in my earlier post. And for not going out of their way to make fun of my janky “benchmarks” – like I said, those weren’t meant to be real benchmarks, just something to give me an idea of relative performance with some operations I care about.

In that same spirit, I took Lopex’s advice and turned on the –server flag; performance gain went from almost 2-to-1 to almost 3-to-1, with no other changes or optimizations.

Before:

[~/project/jrubytest/primes]> ruby ./primes.rb
FINDING first 100000 PRIMES
1299709
Time: 57.716853s
[~/project/jrubytest/primes]> jruby ./primes.rb
FINDING first 100000 PRIMES
1299709
Time: 33.885273s

After:

[~/project/jrubytest/primes]> ruby primes.rb
FINDING first 100000 PRIMES
1299709
Time: 57.204178s
[~/project/jrubytest/primes]> jruby --server primes.rb
FINDING first 100000 PRIMES
1299709
Time: 21.067204s

Thanks to the JRuby crew for stopping by here, and for being so helpful generally.

  • Share/Bookmark

Playing with JRuby, Part 1

Posted: February 16th, 2009 | Author: Brad | Filed under: Programming | Tags: , , | 8 Comments »

As part of a new project, I’m experimenting with JRuby, to see (a) if the alleged performance gains are all that and (b) see how far the Java integration – especially interface implementation – can be pushed.

On the performance front, I did a quick-and-dirty test with a CPU-expensive script that finds prime numbers – not a real benchmark, but something to give me an idea of how JRuby held up under a steady load of basic math operations. Details follow.

Read the rest of this entry »

  • Share/Bookmark

Hadoop Streaming for Rapid Prototyping of Distributed Algorithms

Posted: January 4th, 2009 | Author: Brad | Filed under: Programming | Tags: , , , , , , , , | 13 Comments »

Note: This article assumes that you know a little about MapReduce, or that if you don’t, you might skim the enclosed links so you know what I’m talking about when I get to the examples, or check out the Hadoop Tutorial. It also assumes that you have Hadoop set up – either clustered or pseudo-clustered – if you’re going to run the examples. Or you can just read along.

Hadoop is a framework (written in Java) that supports distributed computing – specifically Google’s MapReduce algorithm. It also comprises HDFS (the Hadoop Distrubuted File System), which allows you to redundantly store large quantities of data across multiple disconnected disks as if they were a single storage unit. I’ve used Hadoop at two jobs and at home, and it rocks.

It comes with a problem, though, which you may spot in the first paragraph: It’s written in Java. Now, don’t get me wrong – Java’s a great language. But developing software in Java with the most commonly used tools (Eclipse, Ant/Maven, &c) is a monumental pain (and you’re hearing this from an old Visual C++ hand). I’m the first to admit that I should shore up my skills with the Java tools, but even if I were better at it, getting a non-trivial Java project from zero to first runnable build is still about as complex as the invasion of Normandy, and the proliferation of XML config files is just inhumane.

Still, the performance and solidity of Java make it the right choice for a production Hadoop project. But what if you just want to kick around an idea or test an algorithm? Wouldn’t it be nice if you could do that in 2 hours instead of a day and a half? Wouldn’t it be nicer still if you could do it in your language of choice?

Read the rest of this entry »

  • Share/Bookmark

Quick and Dirty Messaging

Posted: November 22nd, 2008 | Author: Brad | Filed under: Great Minds, Javascript, Programming, Rails | Tags: , , , , , , , , , , | 1 Comment »

Our Rails Rumble 2008 entry, Great Minds (you can have a look at the latest version or the original Rumble version), required a messaging system. Such systems are easy to do wrong, and we knew we’d need something that would stay solid under unknown load during Rumble judging.

The solution was quick & dirty (as most solutions are during Rails Rumble), but the results worked, and allowed us to qualify for judging and reach a respectable 28th place finish in the “Completeness” category.

Check out the details after the fold.

Read the rest of this entry »

  • Share/Bookmark