Unit testing in Python Pygame for key.get_pressed()

Viewed 1211

I am new to python coding and need some help with unit testing. I want to test my modules that move the images location in Pygame based on what the user has pressed. Here are my modules:

def moveRight(self):
    self.x = self.x + self.speed

def moveLeft(self):
    self.x = self.x - self.speed

Here is where i call these modules:

def on_execute(self):

    # While game is running
    while( self._running ):
        pygame.event.pump()

        keys = pygame.key.get_pressed() 

        if (keys[K_RIGHT]):
            self.player.moveRight()

        if (keys[K_LEFT]):
            self.player.moveLeft()

        # Use class players function moveUp to move up
        if (keys[K_UP]):
            self.player.moveUp()

        self.on_render()

How do i go about testing these? is unit testing different when working with Pygame?

1 Answers

One way is to abstract pygame.key.get_pressed() away, so you can replace it during your tests with something else that returns the fake input we want to test (let's call it mocking).

def on_execute(self, key_state_function):

    # While game is running
    while( self._running ):
        pygame.event.pump()

        keys = key_state_function() 

        if (keys[K_RIGHT]):
            self.player.moveRight()

        if (keys[K_LEFT]):
            self.player.moveLeft()

        # Use class players function moveUp to move up
        if (keys[K_UP]):
            self.player.moveUp()

        self.on_render()

When running your game, you would pass pygame.event.get as argument to on_execute, and in your tests, you pass a function that returns whatever you want (a mock).

But since we're using python where, we can also monkey patch pygame.event.get (replacing the entire function at runtime).

So in the test we would do something like this:

def create_key_mock(pressed_key):
    def helper():
        tmp = [0] * 300
        tmp[pressed_key] = 1
        return tmp
    return helper

pygame.key.get_pressed = create_key_mock(K_RIGHT)

and behold, now pygame.key.get_pressed() will always tell use the right arrow key is pressed.

Now that you know about this, take a look at the build-in mock module.

Related