Skip to content

Instantly share code, notes, and snippets.

@darrencauthon
Created March 20, 2015 13:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darrencauthon/caec988d7c928f4ad602 to your computer and use it in GitHub Desktop.
Save darrencauthon/caec988d7c928f4ad602 to your computer and use it in GitHub Desktop.
Chess BDD with SpecFlow
[Binding]
class BoardSteps
{
[When("there is a chess board set up as")]
public void a(Table table)
{
rows = Table.ConvertToSet<BoardRow>();
board = Board.new();
// loop through the rows, load the board
// ...
// now load it for future steps
ScenarioContext.Current.Set(board);
}
public void c(Table table)
{
board = ScenarioContext.Current.Get<Board>();
moves = Table.ConvertToSet<Move>();
// loop through the moves, make them on the board
}
[Then("the (.*) at (.*) should have the following moves")]
public void b(string piece, string location, Table table)
{
expectedMoves = Table.ConvertToSet<Move>();
board = ScenarioContext.Current.Get<Board>();
moves = board.movesFor(location);
moves.CompareToSet(expectedMoves);
}
}
public class BoardRow
{
public string X { get; set; }
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
public string D { get; set; }
public string E { get; set; }
public string F { get; set; }
public string G { get; set; }
public string H { get; set; }
}
public class Move
{
public string Start { get; set; }
public string End { get; set; }
}
Feature: King movement
Scenario: A king in its beginning position
When there is a chess board set up as
| x | a | b | c | d | e | f | g | h |
| 1 | | | | BK | | | | |
| 2 | | | | | | | | |
| 3 | | | | | | | | |
| 4 | | | | | | | | |
| 5 | | | | | | | | |
| 6 | | | | | | | | |
| 7 | WP | WP | WP | WP | WP | WP | WP | WP |
| 8 | WR | WN | WB | WQ | WK | WB | WN | WR |
Then the WK at E8 should have the following moves
| Start | End |
Scenario: The pawn was moved up
When there is a chess board set up as
| x | a | b | c | d | e | f | g | h |
| 1 | | | | BK | | | | |
| 2 | | | | | | | | |
| 3 | | | | | | | | |
| 4 | | | | | | | | |
| 5 | | | | | | | | |
| 6 | | | | | WP | | | |
| 7 | WP | WP | WP | WP | | WP | WP | WP |
| 8 | WR | WN | WB | WQ | WK | WB | WN | WR |
Then the WK at E8 should have the following moves
| Start | End |
| E8 | E7 |
Scenario: Castling when the king hasn't moved
When there is a chess board set up as
| x | a | b | c | d | e | f | g | h |
| 1 | | | | BK | | | | |
| 2 | | | | | | | | |
| 3 | | | | | | | | |
| 4 | | | | | | | | |
| 5 | | | | | | | | |
| 6 | | | | | | | | |
| 7 | WP | WP | WP | WP | | WP | WP | WP |
| 8 | WR | WN | WB | WQ | WK | | | WR |
Then the WK at E8 should have the following moves
| Start | End |
| E8 | E7 |
| E8 | G8 |
Scenario: Castling when the king has moved
When there is a chess board set up as
| x | a | b | c | d | e | f | g | h |
| 1 | | | | BK | | | | |
| 2 | | | | | | | | |
| 3 | | | | | | | | |
| 4 | | | | | | | | |
| 5 | | | | | | | | |
| 6 | | | | | | | | |
| 7 | WP | WP | WP | WP | | WP | WP | WP |
| 8 | WR | WN | WB | WQ | WK | | | WR |
And the following moves have been made
| Start | End |
| E8 | E7 |
| E7 | E8 |
Then the WK at E8 should have the following moves
| Start | End |
| E8 | E7 |
Feature: Pawn movement
Scenario: A pawn in its beginning position
When there is a chess board set up as
| x | a | b | c | d | e | f | g | h |
| 1 | | | | BK | | | | |
| 2 | | | | | | | | |
| 3 | | | | | | | | |
| 4 | | | | | | | | |
| 5 | | | | | | | | |
| 6 | | | | | | | | |
| 7 | | | | WP | | | | |
| 8 | | | | WK | | | | |
Then the WP at D7 should have the following moves
| Start | End |
| D7 | D6 |
| D7 | D5 |
Scenario: A pawn has moved before
When there is a chess board set up as
| x | a | b | c | d | e | f | g | h |
| 1 | | | | BK | | | | |
| 2 | | | | | | | | |
| 3 | | | | | | | | |
| 4 | | | | | | | | |
| 5 | | | | | | | | |
| 6 | | | | WP | | | | |
| 7 | | | | | | | | |
| 8 | | | | WK | | | | |
And the following moves have been made
| Start | End |
| D5 | D6 |
Then the WP at D6 should have the following moves
| Start | End |
| D6 | D5 |
Scenario: A pawn has an enemy on the left attacking position
When there is a chess board set up as
| x | a | b | c | d | e | f | g | h |
| 1 | | | | BK | | | | |
| 2 | | | | | | | | |
| 3 | | | | | | | | |
| 4 | | | | | | | | |
| 5 | | | BP | | | | | |
| 6 | | | | WP | | | | |
| 7 | | | | | | | | |
| 8 | | | | WK | | | | |
Then the WP at D6 should have the following moves
| Start | End |
| D6 | D5 |
| D6 | C5 |
@erikdietrich
Copy link

Whoah, awesome! The flow (larger scope accpetance tests, micro red-green-refactors to get there) is definitely how I prefer to operate, but you've added an entire visual component to this that had never occurred to me in my initial sizing up of SpecFlow.

Have you implemented a chess game before in this fashion, or are you just operating off the top of your head with this? And, do you mind if I ping you to pick your brain a bit as I'm fleshing out my acceptance test suite for my Chess TDD series?

@darrencauthon
Copy link
Author

@erikdietrich I've never implemented Chess with BDD, but I've used SpecFlow and these sorts of tables in many solutions. In fact, I'm the one who contributed much of code in the the SpecFlow.Assist namespace, as the idea of leveraging the static type definitions of my classes to Gherkin tables came about after experiencing much pain in doing it manually.

So I've never done it with chess, but I have tried to implement my own chess app with TDD back when I was trying to learn TDD. Gherkin tables also happen to be a very close fit to a chess board (I do like to play chess online).

Feel free to contact me if you'd like to talk about what you're building. I'm pretty experienced in SpecFlow, and I bet I could offer some tips. I'm darrencauthon on github, gmail, Skype, Google hangout, twitter, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment