5 people want to do this.

try behavior-driven development


 

People doing this:

  • Provo
  • Punta Del Diablo
  • Cebu City

  • Entries

    The RSpec Book 8 months ago

    I just picked up a beta copy of Pragmatic Programmers’ The RSpec Book, so I’m ready to get started on this one.



    Loving teh BDD 2 years ago

    Great video to get you hyped on BDD with some basic pointers.

    http://www.railsenvy.com/2007/10/4/how-i-learned-to-love-testing-presentation



    Ruby, why donchu drop dem pants... 3 years ago

    RSpec’sAPI for verifying collection behavior (not testing!) reads so well I just had to share with a fellow professional .NET coder (albeit a Ruby enthusiast also). Low-brow hilarity ensued…

    zerokarmaleft: damn, i just love reading code that looks like this:
    specify “all Players’ hands should have 2 cards” do
      @game.players.each { |player| player.hand.should_have( 2 ).cards }
    end

    zerokarmaleft: instead of:
    [Test]
    public void TestAllHandsAfterDealing() {
      foreach(Player player in game.Players) {
        Assert.AreEqual( 2, player.Hand.Cards );
      }
    }

    jm: yeah thats pretty nice code

    jm: i’d stick my dick in that code

    zerokarmaleft: rofl

    jm: its puuuurdy

    If you haven’t figured it out already, I started writing a generic card game (buzzword warning) framework to get my feet wet with BDD. Even after my limited foray, I feel that RSpec encourages thinking from a high-level abstraction standpoint and finding descriptive names. Both very good things in my book. To get this particular specification to read naturally, I had to extract an Array attribute out of a class and wrap it in a new class.

    class Player
      attr_reader :hand
      def initialize; @hand = Array.new; end
    end
    became
    class Player
      attr_reader :hand
      def initialize; @hand = Hand.new; end
    end
    class Hand
      attr_reader :cards
      def initialize; @cards = Array.new; end
    end

    In this minimal form, Hand is fairly worthless, but I wasn’t sure what kind of functionality it needed. So I added some more Player specs to see what would surface. In a card game like Uno, there are many times you have several cards that are the same and playing one is equivalent to playing any other. But Players shouldn’t be concerned with selecting a specific Card instance and deleting it from his/her Hand. They should just be able to say, “I want to play a Skip card, and I don’t care which one.”

    class Player
    [snip]
      def play( klass_of_card, discard_pile )
        cards = @hand.cards.select { |c| c.is_a? klass_of_card }
        raise CardNotInHandError if cards.empty?
        discard_pile << @hand.cards.delete( cards.first )
      end
    end
    class Card; end
    class Skip < Card; end
    @edward = Player.new
    @edward.play Skip

    Since I want to pass a Card’s class as a parameter instead of an instance I can’t use Array#include? to cleanly test for inclusion. I wanted a similar one-liner with Hand.

    class Player
    [snip]
      def play( card, discard_pile )
        raise CardNotInHandError unless @hand.has_this? card
        discard_pile << @hand.discard( card )
      end
    end
    class Hand
    [snip]
      def has_this?( klass_of_card )
        @cards.select { |card| card.is_a? klass_of_card }
        @cards.empty?
      end
      def discard( klass_of_card )
        @cards.delete { |card| card.is_a? klass_of_card }
      end
    end

    Still doesn’t look like much but I think the clarity in Player is increased by isolating class-handling logic in Hand. As far as the Player is concerned, he/she is playing a Card…not a Card.class.

    My experience with RSpec has been pretty positive so far. I’ll get back to my humble chess variant project in a bit and see how well test2spec executes Test::Unit migration.



    Untitled 3 years ago

    I’ll hold off on this until I start programming again.




     

    I want to:
    43 Things Login