GitHub recently announced Scientist! and it allows you to refactor a piece of code that’s critical to your application so you can better “test” the change in production. I think it’s a great idea for those of us who are supporting legacy applications that need better tests.

The example on the GitHub projects page is a change in the permission system:

1
2
3
4
5
6
7
8
9
10
11
require "scientist"

class MyWidget
  def allows?(user)
    experiment = Scientist::Default.new "widget-permissions"
    experiment.use { model.check_user?(user).valid? } # old way
    experiment.try { user.can?(:read, model) } # new way

    experiment.run
  end
end

The important pieces of this are:

  • line 5 - defines the experiment’s name
  • line 6 - executes the old (control) way
  • line 7 - executes the new (experiment) way

It’s amazing how simple it is in it’s execution.

What about PHP?

I know what you’re saying, isn’t this in Ruby? Don’t you work in PHP? I do it just so happens the PHP community has created at LEAST two forks:

  1. daylerees/scientist
  2. aaronbieber/edison

daylerees/scientist seems to be the better maintained (based on # of commits, contributers, forks, etc.) so I would highly recommend you look at that project. I personally think edison is a great name for this but I’ll have to move past that. :-)

It’s example is much more generic but still helpful:

// We need a Laboratory to do science.
$experiment = (new Scientist\Laboratory)

    // Define an experiment with a name.
    ->experiment('experiment title')

    // Set a callback containing our control code.
    ->control($controlCallback)

    // Set a callback containing our trial code.
    ->trial('trial name', $trialCallback);

// Run the experiment, receiving the control return value.
$value = $experiment->run();

I have a project at work that requires me to refactor large sections of legacy (non-unit tested) code so I’ll be experimenting with this in the very near future.