Reading and noting observations for tests written in the Ruby Warrior game

27 Sep 2019

I have been really struggling to test-drive my own projects, because coming up with tests is difficult. So I'm going to try it from a different angle.

I'm going to attempt to reverse engineer someone else's program from their tests.

Step 1. Find a program to reverse engineer

I went onto GitHub and entered 'Ruby' into the search bar to find Ruby projects. I clicked in and out of a few of them and had a quick look to see if they contained tests, and whether I thought I would be able to reverse engineer any of them. Even just a couple tests would be enough to try this out.

The project I chose was Ruby Warrior. It's fun, and the code all seems to be very well written. Every part of the system is written in small chunks where everything appears to do one thing well and is easy to read (it's okay to glance at the source code to see how you feel about working with it). The tests are similarly well-written.

Step 2. Explore and note test code observations

The Ruby Warrior tests are written in RSpec, which is a Ruby testing framework. All of the tests for Ruby Warrior are contained in a folder called 'spec'.

The spec folder contains a folder called 'fixtures' and a folder called 'ruby_warrior'. It also contains a file called 'spec_helper.rb'. The spec helper is for customising the test reporter which is what tells you which of your tests have passed or failed in the command line.

Fixtures folder

The fixtures folder stores sample data that are used to test against. In this case, there is a file called 'walking_player.rb', which contains a Player class with a 'play_turn' method that accepts a Warrior object as an argument and makes it walk. I don't know enough about fixtures right now to explain what this is for.

The fixtures folder also contains a folder called 'short-tower' which contains two files: 'level_001.rb' and 'level_002.rb'. These files contain a level description and variables used in the program, as well as a method.

According to Better Specs, it is better te use factories (a design pattern) that fixtures because they are easier to control and help you reduce the verbosity of creating new data. I'll keep that in mind for when I attempt to refactor the code after passing a test that relies on the fixtures.

Ruby Warrior folder

The Ruby Warrior folder contains the main tests for the program. There is a lot going on here. There are two folders 'abilities' and 'units' inside this folder, as well as a number of test files. I will list the files below as well as a quick description of what I think they tell you about the programs capabilities based on a quick read-through of the tests. I have ommitted the '_spec.rb' extension from the file names below.

Thoughts after test observations

While there are a lot of tests, they don't feel right. They focus too much on the implementation details and not so much on the behaviours associated with the program. However, these tests are a great starting point. After passing them, I can decide whether or not I would do them differently. I can see myself rebuilding this whole program from scratch after doing this because I'll have a lot more ideas for what I'd want to do differently.

However, I'm not sure if I'll be able to recreate the program based on these tests alone. My feeling is that the TDD style is a little off so it's possible that some critical parts of the game are not captured in the tests. But it'll be useful to do this anyway.

Setting up empty starter project

Now that I have read through the tests, I'm going to set up a simple starter project with one file that I can start writing tests in. This project is going to be grown from the ground up. I'll record what I do below, it'll be handy to be able to look back on it.

Choosing which test file to start with

Looking at the tests I outlined earlier. I realised that all of them contain dependencies on other classes. So I had a look at the units file and saw that it contained classes for characters, whilst the abilities folder contained abilities for those characters.

I'm going to focus on the Warrior spec because the game is called Ruby Warrior to start with. I'll probably try out an abilities class after that.

Let's go!

Player Tests

The first thing I did was create a test file in my Specs folder called "player_spec.rb".

Ah, I read the tests in the player_spec.rb and I'm choosing not to try and build this program from the tests. I think the tests were written after the program was made, and potentially before TDD was a thing.

Reading this code has really boosted my confidence. I have been thinking that I'm not a very good programmer of the last few weeks because I don't really 'get' tdd. The fact that most of my observations triggered things I wanted to change has made me think that I know more than I think, so just need to try.

I'm going to try and build my own game inspired by The Legend of Zelda. It doesn't have to be perfect.