I’m about to TDD a Ruby class whose behaviour will involve the use of random numbers. I expect the algorithms within the class to evolve as I implement new stories, so I don’t want to design and build a testing mechanism that will be brittle when those changes occur. But before I can write the next example, I need to figure out how to control the random numbers needed by the code under test. Off the top of my head I can think of four options:

  1. One way would be to set a fixed seed just before each test and then simply let the random algorithm do its thing. But for each new behaviour I would need to guess the appropriate seed, which is likely to be time-consuming. Furthermore, the relationship between each magic seed and the specific behaviour tested is likely to be obscure, possibly requiring comments to document it for the future reader. And finally, if the algorithm later evolves in such a way as to consume random numbers in a different order or quantity, the seed may turn out to be inappropriate, leading to broken tests or, worse, tests that pass but which no longer test the planned behaviour.
  2. Alternatively I could redefine Kernel::rand — but that could potentially interfere with stuff I don’t know about elsewhere in the object space.
  3. Within the class under test I could self-encapsulate the call to Kernel::rand, and then override the encapsulating method in a subclass for the tests. But then I’m not testing the class itself.
  4. Finally, I could parameterize the class, passing to it an object that generates random numbers for it. This option appears to give me complete control, without being too brittle or trampling on anyone else in the object space.

So I’ll go with option 4. Right now, though, I’m not sure what interface the randomizer object should provide to the calling class. Looking ahead, I expect I’ll most likely want to select a random item from an array, which means selecting a random integer in the range 0...(array.length). And for this next example all I’ll need is a couple of different randomizers that return 0 or 1 on every request, so I’ll simply pass in a proc:

obj.randomize_using { |ceil| 0 }

And if ever I need to provide a specific sequence of varying random numbers, I can do it like this:

rands = [1, 0, 2]
obj.randomize_using { |ceil| rands.shift || 0 }

Later that same day…

The class I’m developing has evolved quite a lot and split into three. And suddenly, with the most recent change, three of the tests have begun failing. A little investigation reveals that the code is now consuming a random number when it didn’t need to in the past, and so some of my randomizer procs now provide inappropriate values. It turns out that two of the failing examples actually boil down to being a single test of a piece that has now been refactored out into another class; by refactoring the tests to match I can remove the dependency on random numbers altogether. And the last broken test is fixed by providing a randomizer that respects the ceiling passed to it (not an unreasonable request):

obj.randomize_using { |ceil| [2, ceil-1].min }

This works, and I get no more surprises during the session.

In The Cardinality of a Fluent Interface Michael Feathers posed a code kata in which one has to create a DSL in which constructs such as the following all provide the expected numeric value:

    one
    two
    twelve
    twelve.hundred
    one.hundred.thousand.and.fifteen
    twelve.hundred.and.one
    five.hundred.and.fifty.seven

My first pass at a solution in Ruby is listed below (and a copy with unit tests can be downloaded from my website). There’s still some duplication in there, and hopefully I’ll get around to removing it soon.

In his post, Mike asks whether the DSL’s “cardinality” — the number of classes required to implement the DSL — says anything about the DSL’s grammar. Well, my solution has 7 classes (although PartialValue exists only to remove a little duplication). I have no idea what that might mean in the DSL world.
Read the rest of this entry »

Dave Verwer at NWRUG has been crazykind enough to invite me to re-run a version of my hexagonal architecture workshop this month at the MDDA. This is the session that, two years ago, had seventy of the world’s leading agilists standing on one leg. If you’re in Manchester on the evening of November 20th, why not hop along?

Back in May’s Carnival of the Agilists I referenced a post by Clarke Ching in which he suggests we can learn a lot about variation in a complex process by simply flipping coins. When I tried the simulation a few times with Excel I found, as expected, that heads and tails don’t always occur in equal measure. But that was a pain to do, so I’ve made it easier. Over on my website I’ve posted a page that runs the simulation and shows the results as a sparkline graph. Every time you refresh that page it re-runs the simulation, with different random tosses of the imaginary coin.

(Disclaimer: The image is an SVG. It works fine in Firefox, but if you use IE you may need to install some kind of viewer.)

The sparkline itself is an SVG image generated by a Ruby script. If there’s enough interest I’ll turn it into a proper Ruby library and perhaps even gemify it. What features would you like to see if / when I do that?

My Watir tests for a particular application are grouped into three subclasses of Test::Unit::TestCase. To run them all I have a top-level test suite that looks like this:

require 'test/unit'

server.start

require 'test/first_tester'
require 'test/second_tester'
require 'test/third_tester'

server.stop

But this doesn’t work as intended, because the server.stop line at the end of the script is executed before the test suite is constructed and executed, which is obviously not what I want. The problem is in test/unit: the require causes this script to collect every test method in the ObjectSpace and then invoke the runner on the resulting suite.

What I would like is to have setup and teardown methods on TestSuite; but they aren’t there. I feel sure someone somewhere must have done this already (the closest I could find was this old post on ruby-talk), but I couldn’t find one quickly so I wrote my own:

require 'test/unit/testsuite'
require 'test/unit/ui/console/testrunner'

require 'test/first_tester'
require 'test/second_tester'
require 'test/third_tester'

class TS_MyTestSuite < Test::Unit::TestSuite
  def self.suite
    result = self.new(self.class.name)
    result << FirstTester.suite
    result << SecondTester.suite
    result << ThirdTester.suite
    return result
  end

  def setup
    server.start
  end

  def teardown
    server.stop
  end

  def run(*args)
    setup
    super
    teardown
  end
end

Test::Unit::UI::Console::TestRunner.run(TS_MyTestSuite)

Please let me know if this solution - or anything equivalent - is already published elsewhere, because I hate re-inventing wheels…

ruby is fast maturing

May 23, 2007

Here’s a quote from RailsConf2007 that I find astonishing:

“There seems an excellent chance that Ruby and Rails could become a significant platform for IT develop over the next few years. We’re already seeing signs of this at ThoughtWorks - 40% of our new business this year in the US is Ruby work.” — Martin Fowler

Forty percent?! That’s amazing.

I do now find myself using Ruby freely as the main scripting and general project automation tool, but always with a hint of nervousness. Because it isn’t yet sufficiently mainstream that I can expect my scripts to run everywhere. There’s still some way to go before I can expect to be able to ship Ruby-enabled stuff to end-user sites, for example. And even within development shops I find the spread of all the bits n bobs (eg. the copious numbers of gems required in order to do anything unusual) is still very sparse. Maybe JRuby will help.

The rest of Martin’s conference report is well worth a read, as are the many others appearing in our aggregators this week. I’m not sure Ruby will help us end world poverty, but that figure of 40% is possibly a (startling) sign of things to come.

Eighteen months ago I posted a Ruby version of Bill Wake’s Amazing maze refactoring challenge. I looked at it again this week and discovered that it is rubbish: the transliteration from Java is not very literal, and one of the test examples is broken. So I’ve re-created it and uploaded a revised version. My apologies if you tried working from the original version.

win32-process quirks

March 5, 2007

I had occasion to install the win32-process gem today, because my Watir tests needed to start a background agent. On my laptop the cookbook example in the gem’s documentation doesn’t work; I found:

  • The package to require is ‘win32/process’;
  • the block version of fork() causes the child process to execute the block and then continue with the parent code;
  • the module names in the examples are incorrect (and not needed); and
  • the return value from Process.create() is not a process ID, but a structure that contains a process ID.

Nothing major, but it wasted twenty minutes. Anyway, for completeness here are a couple of corrected example scripts showing the behaviour of win32-process. First, mimicking the old Unix API:

require "win32/process"

pid = Process.fork
if pid.nil?
  3.times {
    puts "In the child"
    sleep 1
  }
  exit
end

2.times {
  puts "In the parent"
  sleep 1
}

Process.wait

As expected, this produces

In the parent
In the child
In the parent
In the child
In the child

Now try passing a block to the child:

require "win32/process"

Process.fork do
  3.times {
    puts "In the child"
    sleep 1
  }
  exit
end

2.times {
  puts "In the parent"
  sleep 1
}

Process.wait

On my PC this produces:

In the parent
In the child
In the parent
In the child
In the child
In the parent
In the parent

Those extra prints from the parent show that the child process continued after completing the block!

I’m starting out on two new Rails projects this week, so I’ve been investing some time in getting Eclipse configured nicely. There are dozens of helpful websites containing helpful advice, and after much trial and error I found a couple of these that worked really well for me.

For setting up RDT (the Ruby Development Tools) I found Brian Hogan’s Setting up a Rails Development Environment on Windows Using Eclipse to be the most complete and accurate resource. However, it doesn’t cover RadRails. For that, I recommend Victor Kane’s RadRails Tutorials. Both of these sites provided complete and correct advice that worked straight out of the box.

But only after I had spent much of last week struggling with the Cygwin version of ruby. I’ve been an old Unix hand since before I could walk (I wrote some small parts of the System V kernel, would you believe). So when I work on a Windows box, one of my first actions has always been to install Cygwin and make it seem a little more like “home”. But not any more. It’s just too hard to get Cygwin, Ruby, gems, Eclipse, Rails, Apache, MySQL and Subversion all working together. Either the DLL versions are in conflict with each other, or something coredumps regularly, or something needs to be compiled with one in order to work with the other. At every turn I came up against stuff that was known not to work. So in the end I have reluctantly decided that I must be congruent, and not try to pretend that Windows is Unix. It was a painful decision, but so far it has paid off.

Now, to get on with some development…

I have a little toy in development, and I’m looking for a different hosting service, because my current lot don’t seem in the least inclined to support Ruby, let alone Rails. So can you recommend a great host? Here’s what I’m looking for:

  • full support for Ruby and Rails
  • install my own gems as required
  • Perl
  • CGI
  • reasonable control over .htaccess files
  • huge MySQL databases
  • shell access
  • ftp access
  • domain hosting, preferably with control over DNS entries
  • friendly, honest and transparent support
  • business accounts permitted
  • upto 1GB disk space
  • crontabs
  • must be secure, and have high availability
  • preferably UK based

Oh, and it must be cheap! Thanks for any recommendations.