More TDD: Chipping Away

Over the past few days I have been using chunks of free time to figure out which tests to write next. In the last post, I was a little frustrated with the process, but almost immediately I found a groove and a style of writing tests that has been pretty productive. One of the biggest steps forward was to stop worrying about everything so much. The important thing is that I am trying, and I am moving forward. With that mental block out of the way, I got busy.

With setting up a shoe and dealing hands out of the way, I knew I needed a way to score the hands, so I built a test for a scoreHand function. Usually each test block, wrapped in an ‘it’, will have a couple of tests. Sometimes it will have more. They don’t start this way, I try to start each one with one test case, like this:

describe('scoreHand', function(){
    it('should check the dealerHand score', function(){
        assert.equal(scoreHand([5,5]), 10);
});

Eventually they grow larger. I try to encompass edge cases if I can think of them and both pass and fail cases where applicable. Currently, the scoreHand test is a medium sized test (for me) and it looks like this:

describe('scoreHand', function(){
    it('should check the dealerHand score', function(){
        assert.equal(scoreHand([5,5]), 10);
        assert.equal(scoreHand([10,8]), 18);
        assert.equal(scoreHand([3,5,8,2]), 18);
        var testHand = [6,5,10];
        assert.equal(scoreHand(testHand), 21);
    });
});

An example of a simpler test case is the very next test, testForBlackjack. I envision using this test just after the initial deal to determine if anyone has a blackjack. Simple function, simple test:

describe('testForBlackjack', function(){
    it('should check for 21', function(){
        assert.equal(testForBlackjack(scoreHand([10,11])), true);
        assert.equal(testForBlackjack(scoreHand([5,5])), false);
    })
});

Occasionally a test gets longer, and sometimes more complicated. I am learning to take this as a warning sign. It tells me that either I am trying to do too much with one test or too much with one function (or both). It can also start to feel brittle, too reliant on some not-quite-hashed-out syntax. A great example of that is my dealCard test and function:

describe('dealCard', function(){
    it('should deal one card to the correct player', function(){
        dealCard("player");
        assert.equal(playerHand.length, 3);
        assert.equal(shuffledShoe.length, 47);
        dealCard("player");
        assert.equal(playerHand.length, 4);
        assert.equal(shuffledShoe.length, 46);
        dealCard("dealer");
        assert.equal(dealerHand.length, 3);
        assert.equal(shuffledShoe.length, 45);
    })
});

I do not like the parameter I am passing, and I know I will have to rewrite the test when I clean up (redesign vs. refactor) the function. In fact, looking at the function again, I hate it even more. I will have to give that part of the code some attention soon.

Along the way, I did have an “ah-ha” moment with TDD, especially about the “Driven” part, so I made a little screencast about it for my YouTube channel. The video is up here, and I will talk about that in more detail in a later post, along with a neat bit of coding I learned thanks to WebStorm. As always, I try to keep my code up to date in my GitHub repositories, so if you want to look at the guts, blackjack is right here. Comments, questions and criticism welcome!