Deprecated: Assigning the return value of new by reference is deprecated in /home/melaloui/public_html/ueckerman/wp-settings.php on line 520

Deprecated: Assigning the return value of new by reference is deprecated in /home/melaloui/public_html/ueckerman/wp-settings.php on line 535

Deprecated: Assigning the return value of new by reference is deprecated in /home/melaloui/public_html/ueckerman/wp-settings.php on line 542

Deprecated: Assigning the return value of new by reference is deprecated in /home/melaloui/public_html/ueckerman/wp-settings.php on line 578

Deprecated: Function set_magic_quotes_runtime() is deprecated in /home/melaloui/public_html/ueckerman/wp-settings.php on line 18

Strict Standards: Declaration of Walker_Page::start_lvl() should be compatible with Walker::start_lvl(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_Page::end_lvl() should be compatible with Walker::end_lvl(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_Page::start_el() should be compatible with Walker::start_el(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_Page::end_el() should be compatible with Walker::end_el(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_PageDropdown::start_el() should be compatible with Walker::start_el(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/classes.php on line 1244

Strict Standards: Declaration of Walker_Category::start_lvl() should be compatible with Walker::start_lvl(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_Category::end_lvl() should be compatible with Walker::end_lvl(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_Category::start_el() should be compatible with Walker::start_el(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_Category::end_el() should be compatible with Walker::end_el(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_CategoryDropdown::start_el() should be compatible with Walker::start_el(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/classes.php on line 1442

Strict Standards: Redefining already defined constructor for class wpdb in /home/melaloui/public_html/ueckerman/wp-includes/wp-db.php on line 306

Strict Standards: Redefining already defined constructor for class WP_Object_Cache in /home/melaloui/public_html/ueckerman/wp-includes/cache.php on line 431

Strict Standards: Declaration of Walker_Comment::start_lvl() should be compatible with Walker::start_lvl(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/comment-template.php on line 1128

Strict Standards: Declaration of Walker_Comment::end_lvl() should be compatible with Walker::end_lvl(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/comment-template.php on line 1128

Strict Standards: Declaration of Walker_Comment::start_el() should be compatible with Walker::start_el(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/comment-template.php on line 1128

Strict Standards: Declaration of Walker_Comment::end_el() should be compatible with Walker::end_el(&$output) in /home/melaloui/public_html/ueckerman/wp-includes/comment-template.php on line 1128

Strict Standards: Redefining already defined constructor for class WP_Dependencies in /home/melaloui/public_html/ueckerman/wp-includes/class.wp-dependencies.php on line 31

Strict Standards: Redefining already defined constructor for class WP_Http in /home/melaloui/public_html/ueckerman/wp-includes/http.php on line 61
ueckerman.net » 2007

Archive for 2007

Equality: 4 times the charm

{Thursday, August 9th, 2007}

Ruby’s equality options have baffled me in recent times. No surprise that JRuby has encountered related problems.

Melbourne RUG Plug

{Thursday, May 31st, 2007}

Attended the Melbourne Ruby User Group tonight. I was impressed by the turn out, openness and quality of the discussion.

As much as I’m for gathering knowledge in a variety of languages, come along, learn something and share your experiences.

ReSpect RSpec

{Monday, May 21st, 2007}

What is Behavior Driven Development (BDD)?

According to behaviour-driven.org BDD was born from NLP experiments (astonishingly, nlp.com mention NLP and hypnosis in the one sentence!).
It is a combination of TDD and DDD. Here are some of my attempts at describing BDD:

A process for describing the behavior of a system that is understood by both technologists and non-technologists.

DDD applied to the domain of TDD.

The concept of a ‘vocabulary for describing behavior’ is at its core, but interestingly the behavior-driven site falls short of defining the vocabulary (note the incomplete links at the base of this page).
BDD is strongly linked to TDD as tests are often used to describe the features, or behaviors, of a system. Consequently, part of BDD involves writing tests using the vocabulary.

Enter RSpec

That’s the driving principle behind RSpec. Test::Unit is perfectly fine for defining tests, but it doesn’t employ a BDD vocabulary.
RSpec does, and it throws in a side order of Mock and Stub support often needed for TDD. As it happens this support is virtually identical to that provided by Mocha.
Take your pick, the support both provide is particularly cool as you can Mock and Stub methods of any object, sure you can create Mock and Stub objects (in a fashion that I’ve been used to with EasyMock and JMock) but the object doesn’t have to be a Mock or Stub in order to Mock or Stub a method invocation.
To highlight this here’s an RSpec demonstration applied to a banking model;

  describe Account do

    before(:all) do
     @@amount = 100
    end    

    before(:each) do
      @account = Account.new
    end

    it 'should withdraw cash via a Transaction' do
      Transaction.should_receive(:deduct).with(@account, @@amount)

      @account.withdraw @@amount
    end

    it 'should log unsuccessful operation when withdraw is unsuccessful' do
      Transaction.should_receive(:deduct).with(@account, @@amount).and_raise(InsufficientFundsException)

      @account.should_receive(:log_outcome).with(:unsuccessful)      

      @account.withdraw(@@amount).should_raise(InsufficientFundsException)
    end

  end

Pretty cool huh?! This mocks two methods in a manner that can’t be easily repeated with Java:

  • A class method, Transaction.deduct
  • An instance method of a real object, @account.log_outcome

Take a look at the recently tweaked documentation on the RSpec site for info on it’s other features (like partial argument matches), and more generally its implementation of a BDD vocabulary.

Why use RSpec?

One of my initial encounters with RSpec was via a blog critising BDD that goes so far as to suggest RSpec is pronounced ‘arse peck’, so I’ve been skeptical from early on. I have been particularly cosy with XUnit tests, a mock framework and consistent test method naming conventions as a way of specifying behaviors, so I didn’t feel the urge to change. Test::Unit and Mocha can pretty much yield the same result - what did I have to gain?

Still, this ol’ school approach requires some discipline and custromizations to read like a BDD vocabulary. RSpec, on the other hand, encourages codification of tests in a consistent BDD vocabulary. But hey, if you don’t intend on using the vocabulary for communications between roles (and that’s a substantial change) your missing the major benefits of BDD - so why bother?

Nonetheless, it’s worthy of consideration.

With its subtle shift in the XUnit language I believe it produces more readable tests. That coupled with its nice mock and stub support and the potential benefits of a shared language for describing behavior - the pro’s start outweighing the con’s.

Parting Thoughts

I’ve read some BDD proponents claim they sought out BDD as a solution to tests that are tightly coupled to source, hindering refactoring and causing a maintenance burden.
I fail to see how BDD helps here; this is a natural consequence of writing unit tests. For tests to do their thing, an API under test must be invoked - you can’t avoid that. If you change that API; surprise, you’ve got to change your unit tests! If you’re suffering this affliction maybe you should test against an API few layers up, like HTTP. Personally though I’d be blind without my unit tests, at a minimum they aid design and verify correctness.