Saturday, November 28, 2015

An Exploration of TDD Part 1

I've been squinting at TDD as a development concept for a while now. I'm coming from a background where all you did was testing after the fact (if you were lucky and had a patient boss), and I remember the pain of extending or changing code in such an environment. So TDD looked like a great concept to me, and now I've decided to put it to the test.

My plan is as follows: I'm going to create a project with only the vaguest of notions as to where it may be going, and see just how useful TDD is going to be in helping me create maintainable code. As an added obstacle I have to say that I don't know much about TDD other than the principle of red-green-refactor.

So this exercise should be interesting.

Here's the concept of the software I'm going to create: A piece of software that creates a world that a player can walk through and do stuff. How's that for a fuzzy brief?

If I'm going to have a world that a player can navigate, it stands to reason that I need locations, and that my locations have to connect to other locations. And in order for a player to get to other locations, each location needs exits, which shouldn't point anywhere before they've been assigned. I'll also need to be able to get and set the location that an exit leads to, and each location should have a unique ID, which can be assigned to an exit in another location.

Here are the tests I've come up with:

I'm not entirely sure about the second test because, strictly speaking, it tests two things at the same time (the constructor and the ExitInDirection method), but I don't want my method of storing exits to be public, so until I figure out how to access private variables in a unit test, this'll have to do.

I implement the constructor and ExitInDirection method to return hard-coded values other than the expected test results in order to get my first reds, then flesh them out as follows, which gives me green tests:

I don't think I want to keep the number of possible exits to be hard-coded in the Location class, but that's for later. For now I can't see any other tests that I could apply to the constructor, but the ExitInDirection method is another thing. I need to test that against a direction that's outside of the bounds of my array of exits.

With the current code, both those tests are red as they throw an out of bounds exception, so now I refactor to account for invalid directions:

And with that amendment, all my tests are now green. Looking good so far.

Another thing I need is a method to determine where each exit direction leads to. But so far I can't set the location for an exit, so that's my next goal.

First I'll create a method to link a location to an exit, which initially does nothing at all:

And some tests to check whether an exit links to the correct location after it's been created:

Running this against the blank method gives me my initial red, so now I'm good to flesh out my SetExitToLocation method:

At this point I have to ask myself again what should happen if the direction is outside of the bounds of the array. Right now I get an index out of bounds exception, which isn't all that bad, but I figure that an argument out of range exception would make more sense. So I add two more tests for that:

This gives me another red test until I amend my SetExitToLocation method to

And that has my whole range of tests green again, and completes my first draft for my location class.

P.S. Since I'm new to TDD, any constructive comments as to what could be improved in my process are very welcome.

No comments: