Rolling dice; another look into TDD

Emma Priester
4 min readMar 4, 2021

This morning we started with an intro to TDD. In my opinion, we could have done this at the start of the week rather than only now. We were working with RSpec throughout the week challenge already. Having this introduction at the end of the week rather than at the start had me expecting it to be a bit more challenging as well. At the end of the morning session, we got to write a small rolling dice game in pairs. Being paired with somebody who did struggle a bit more with Test-driven development. I saw this as an opportunity to see if I understand it well enough to teach somebody else this skill.
To get started, we looked at a few User Stories;

As a board game player,
So that I can play a game
I want to be able to roll a dice

As a board game player,
So that I know how many steps I should move
Rolling a dice should give me a number between 1 and 6

As a dice app developer,
So that I give players a good game experience
If it is not already random, I want the dice roll to be randomly picked

As a board game player,
So that I can play many types of games
I want to be able to roll any number of dice at the same time

As a board game player,
So that I can keep track of past and previous rolls
I want to record each dice roll

As a board game player,
So that I know what my score is after I have rolled several dice
I want to be able to get my current score

We began with the first user story, after setting up all of our files, and testing if it saw our defined class in the ruby file, we wrote our first simple test. This test simply checks if the spec sees our function.

describe “roll_dice” do
it “rolls dice” do
expect(subject).to respond_to :roll_dice
end

I am quite keen on these tests, the sheer simplicity in testing whether or not our test sees our function can easily be forgotten but tells a lot about the code if it ever fails. We defined our function called ‘roll_dice’, now we wanted a randomized output from this function.

it ‘gives a number between 1 and 6’ do
expect(subject.roll_dice).to be_between(1, 6)
end
end

I find spec to be a beautifully user-friendly script. Simply to be_between, allows us to test our random output, without having to write out every option! Now we wrote the code that would pass this test.

def roll_dice
(1..6).to_a.sample
end

On to the next user story. Quite simply, allow several rolls. We took the small step again, to simply see if our spec would read our function, and after defining the function, it did! Now we wanted to give it some input, to see if that would match out expected output.

describe “amount_of_dice” do
it “rolls multiple dice” do
expect(subject).to respond_to :amount_of_dice
end
it “rolls three dice” do
expect(subject.amount_of_dice).to eq 3
end
end

again, a simple test, with a random output. This does not expect us to combine any of these functions quite yet. To make it more user friendly, I added an attribute reader at the top of the class and for now, I initialized it with a default value of 3.

attr_reader :dice_amount

def initialize
@dice_amount = 3
End

def amount_of_dice
@dice_amount
End

Cool. All of these test pass. Now we want to roll the dice several times and see our score added up. We define a new function for that and see if the spec file reads it. And then we give it a value.

describe ‘number_of_rolls’ do
it ‘sees function number_of_rolls’ do
expect(subject).to respond_to :number_of_rolls
end
it ‘rolls three dice’ do
expect(subject.number_of_rolls).to be_between(3, 18)
end
end

the expected output has to be between 3 and 18 if 3 dice are rolled, considering all dice can be up to 6 points. To get this output, I wrote a function that combines the former two: rolls the dice the number of times as the amount of dice that we have.

def number_of_rolls
amount_of_dice * roll_dice
end

Lastly, we want to be able to save our score of dice. I defined a new function for this one again.

describe “save_dice” do
it ‘should see save_dice’ do
expect(subject).to respond_to :save_dice
end
end

to save the dice I initialized a global variable that I would call ‘rolled_dice’, to be an array. Now I want to store our rolled dice in this array.

def save_dice
@rolled_dice << roll_dice
End

This is where I called it quits with this simple code. I know I could make it more complicated, but I feel there is not too much use in putting more effort into this. Seeing what we have done I feel confident that I know how to work with simple TDD programs, and I was able to teach this to my pair partner.

--

--