Skip to content
Ben Forrest edited this page Aug 11, 2015 · 20 revisions

Not testing all of the game logic in unit tests

As there is a discrete number of possible outcomes, your tests should test them all. This may seem like overkill, but how else will you know that your game logic is correct in all circumstances?

Testing game logic in feature tests

Your feature test should not need to test all of the rock/paper/scissors(/lizard/spock) possibilities - this is the responsibility of your unit tests.

Not testing all game outcomes in feature tests

Although you do not need to test all possible combinations, your feature tests should test every possible outcome - i.e.:

  • a win
  • a loss
  • and a draw. to ensure the user interface logic is correct.

Including presentation strings in business logic layer

Your Game class (or similar) should not return presentation strings like "Congratulations - you won!". This is a presentation concern and should be handled in another layer of code (separation of concerns). Instead, return representative codes, such as :win and :draw from the Game class which can be translated by the presentation layer.

This approach makes it possible to change the presentation layer (e.g. to add support for a different language) without changing the lower-level code (open/closed principle).

Use of if/elsif conditionals for business logic

Long if and elsif trees are very difficult to read and nested if statements require too much working memory for a reader to quickly scan.

There are a number of approaches to the game logic of Rock Paper Scissors, e.g.:

  • Use a hash to map the rules: rules = { rock: scissors, paper: :rock, scissors: :paper } or for RPSLS: rules = { rock: [scissors, lizard], paper: [:rock, :spock], scissors: [:paper, :lizard], lizard: [:paper, :spock], spock: [:rock, :scissors}
  • Use individual classes for each weapon (i.e. Rock, 'Paperetc.) with abeats?` or similar method that takes another weapon as a parameter.
Clone this wiki locally