A week ago, I announced on Twitter new blogpost about CQRS. I’m still writing it but I needed a little break from it and to take something new, something that I wanted to learn, try from a long time. I did my first Kata.
Kata is a Japanese word and could mean “practicing move”. Programmers adapted that word and created a lot of Katas (exercises) to improve their skills. One of the most popular Kata is The Bowling Game described by Robert Cecil Martin (Uncle Bob). The clue is to create an algorithm which shows score using the rules in this sport’s discipline.
On Saturday, I took my MacBook Pro and went to a cafe. I ordered, as usually, a large cappuccino without sugar and with non-fat milk and I’ve started two hours coding session.
[toc]
The rules
As a person who grew in Poland, I didn’t know the rules in bowling, although I’ve played three times on it.
- There are 10 frames. In each frame, you have 2 moves, except the last frame when you could have 3 moves.
- When you knocked down 10 pins in 2 moves in 1 frame, you have “spare”. Then next move is doubled to score.
- When you knocked down 10 pins in 1 move in 1 frame, you have “strike”. Then next two moves are doubled to score.
- If in the last frame, you have “spare” or “strike” then you have one extra move in this frame.
- Maximum score you can achieve is 300.
The tools to TDD, BDD
The rules are plain and clear now, so I could practice my skills in TDD, especially using tools to specs and BDD. I’ve chosen phpspec for specs, and behat for BDD tests.
phpspec
Is a great tool if you want to create good code from the beginning. You are describing behaviour of your object which you will create. phpspec creates for you php code based on your specification, and after it, you add an only implementation.
behat
Behat allows you create scenarios (in natural language) which represent the behaviour from the business side. In this case, the “business side” are rules in a bowling game.
Installation phpspec and behat
I don’t want to describe here each line that I’ve written. I push everything to GitHub repository, but to make this blognote more useful, I will explain how to add phpspec and behat to your project.
First, what you need is Composer. If you don’t know what it is, let’s go to one of my previous notes. I’ve described what it is, how to install and how to use. Enjoy!
Installing and using behat
We need to run two commands, first get behat code from a repository, and second create needed files in your project:
composer require behat/behat # get behat code
vendor/bin/behat --init # create needed files
It creates new folder features
when you should storage your scenarios. You can watch how it looks in my project.
To run your scenarios, you need run only one command:
vendor/bin/behat
And this is it!
Installing and using phpspec
Installation phpspec is a bit difficult than behat but still easy. We have to start with getting a code from a repository, so let’s use composer.
composer require phpspec/phpspec
Then, you need edit your composer.json
file and add there following lines before last }
,
"autoload": {
"psr-0": {
"": "src/"
}
}
Using phpspec required the knowledge of two commands, it’s desc
and run
. About it, you can read in official documentation.
Last words
If you want to create your bowling code, you can use my scenarios that I’ve described for behat.
Make fun!
Feature: Score
Scenario: Two moves with each two shot pins
When In move user shot "2" pins
And In move user shot "2" pins
Then The score is "4"
Scenario: Two moves with two different shot pins
When In move user shot "2" pins
And In move user shot "3" pins
Then The score is "5"
Scenario: Four moves in two frame
When In move user shot "2" pins
And In move user shot "3" pins
And In move user shot "4" pins
And In move user shot "5" pins
Then The score is "14"
And The frame is "3"
Scenario: One move with shot all pins
When In one move user shot strike
Then The frame is "2"
Scenario: In first frame user shot 10 pins and do next move
When In two moves user shot spare
Then The frame is "2"
And In two moves user shot spare
Then The score is "25"
Scenario: In first frame user shot 10 pins in one move and do next move
When In one move user shot strike
Then The frame is "2"
And In move user shot "4" pins
And In move user shot "5" pins
Then The score is "28"
Scenario: In first frame user shot 10 pins in one move and do next moves in two frames
When In one move user shot strike
Then The frame is "2"
And In move user shot "4" pins
And In move user shot "5" pins
Then The score is "28"
And In move user shot "4" pins
And In move user shot "5" pins
Then The score is "37"
Scenario: In two frames user shot 10 pins in first move
When In one move user shot strike
Then The frame is "2"
And In one move user shot strike
Then The frame is "3"
And The score is "30"
Scenario: In all frames user shot all pins in first move
When In one move user shot strike
And In one move user shot strike
And In one move user shot strike
And In one move user shot strike
And In one move user shot strike
And In one move user shot strike
And In one move user shot strike
And In one move user shot strike
And In one move user shot strike
And In one move user shot strike
And In one move user shot strike
And In one move user shot strike
Then The score is "300"
Scenario: In two frame user shot all pins and do next move
When In two moves user shot spare
Then The frame is "2"
And In two moves user shot spare
Then The score is "25"
And In move user shot "4" pins
And In move user shot "5" pins
Then The score is "38"
Scenario: In two frame user shot all pins and do next move
When In one move user shot strike
Then The frame is "2"
And In two moves user shot spare
And In move user shot "2" pins
And In move user shot "4" pins
Then The score is "38"