Tuesday, June 28, 2011

Learning Python: #4 - UnitTesting - Second Test

Now that I have the first test completed, I can move on to adding some actual functionality to the Game class. My next step was to have it keep track of the number of pins rolled. Here is my second test:
def testGameHasScoreOfOneWithFirstRollOfOnePin(self):
    game = Game()
    game.roll(1)
    assert game.score == 1
At this point the tests no longer pass because the Game class does not have a roll method. My first attempt to add the roll method to my Game class failed:
def roll(pins):
        score += pins
Here is the error that was printed:

E.
======================================================================
ERROR: testGameHasScoreOfOneWithFirstRollOfOnePin (__main__.TestGame)
----------------------------------------------------------------------
Traceback (most recent call last):
File "TestGame.py", line 13, in testGameHasScoreOfOneWithFirstRollOfOnePin
game.roll(1)
TypeError: roll() takes exactly 1 positional argument (2 given)

----------------------------------------------------------------------
Ran 2 tests in 0.002s

FAILED (errors=1)

This is a very confusing error when you are unfamiliar with the language. Clearly I am passing in one argument to a method that takes one argument. What in the world?? The way that methods work in Python is that the object is passed as the first argument of the function. So essentially, the method call acts like game.roll(game, 1) though it is not actually called this way. What is needed is to change the method definition. My updated roll method:
def roll(self, pins):
    self.score += pins
Both of my tests now pass:
..
----------------------------------------------------------------------
Ran 2 tests in 0.002s

OK

No comments:

Post a Comment