TDD for Tic Tac Toe using Java (part 1)

 
Cheers everyone. These days I am working on a project which has lots of scientific stuff under the hood - finds best route between point A and point B depending on various circumstances. So what you need to do is to evaluate lots of possibilities, build graph, measure coefficients...And it is something certainly which is horrible thing for manual testing by definition.

And still we had some kind of disagreement about what approach we should take to ensure quality on this project with project tech lead - her suggestion was to do heavy manual testing cause "TDD is not applicable on such kind of projects", mine was that unit-testing may be the only way to create basis for a good QA on a project, and TDD is probably the only way to guarantee we do unit-testing properly.

 So, just for lulz, I decided to play with idea a little bit and chose some kind of similar application to work with - Tic Tac Toe game. One of the possible solutions to make computer play against you would be evaluate possible moves, build graph, measure coefficients (sounds kind of familiar, ah?).

So, I am creating empty project and adding Junit dependency and start doing as clean TDD as I possibly can. I am aiming to build full console based game. Here's what I start with in my pom.xml:


I create my first test, and I decided it to be test for PlayBoard, the very place where we will do all our gaming calculations. My first test going to be dummy test for constructor:


So, to make this code work we need only to add PlayBoard class. Then we need to be able to work with fields. Let's say, whenever we create board we want to be empty, so I am going to update testConstructor to something more reasonable. I am going to iterate through all fields we have in board and check if it is empty. First obstacle I will meet is that I don't have a method for getting field,  so I am going to add it. To do this, I need to add some place to store fields (I decided to make it array as simple abstraction. Here's what I came with:


This makes compiler happy, but spectacularly fails on test run. Shame on me - playField has nothing inside. So I am filling it with empty PlayFields in constructor in a simple nested loop, similar to one we used in unit test. This makes our unit test happy, so with next step I am going to check that field is empty. To make this happen I just decided that PlayField should probably be enum, and have only three possible options - EMPTY, X, O. Done!



Test and PlayBoard class were updated accordingly. Constructor and one method is ready, so far, so good, but we have lots of things to do ahead. Next thing I want to have - is the ability to change state of any field, leaving other fields unchanged. We can test this using several approaches - choose some x or y, hardcode it in test. Or, for instance, generate random value for each test run, and thus turn debugging into hell. The brute force approach would be to iterate through all fields (all nine! :) ), change state and see what happens. Choosing between these options I decided to go for simplest approach that may possibly work - use several hardcoded fields to change, and check others. To achieve this effectively data-driven approach I added junit-dataprovider dependency int my pom.xml:



With first line of test we notice that we didn't create a method for setting fields, so alt+Enther and we're adding this method.
So test code looks like:
Additionally, I will also check that we can update field value, that was already updated, and non other fields were changed. That is an overkill, and test going to pass without any code changes, but we're doing proper TDD here, aren't we?

Now we have fully functioning board, so something at least. Coverage for production lines (which we have as many as 11) is 100%, achieved by mere 63 lines of test class :). Anyway IDE did most of production "coding" for me and I only really worked on unit tests, so I consider this as a success. In next part we will extend our game to something more usable, for instance allow playing to humans with it.

To summarize, even though I haven even started to work on real algorithm yet, I had a lots of fun playing with this around, and again proved at least for myself that TDD (if not taken into extreme) is really viable and pleasant development approach once you get used to it. See you in next part coming sometime later.

Check the code at: https://github.com/senpay/tictactoe_tdd_java
(available by WTFPL license, https://en.wikipedia.org/wiki/WTFPL)

Comments

Popular posts from this blog

Test automation framework architecture. Part 2 - Layered architecture

Test automation framework architecture. Preface.

Test automation framework architecture. Part 1 - No architecture