Clue Players More TDD
Failing then Passing Tests • Failing tests should be written first • BUT, creating all these failing tests, then implementing them all, is not really good practice • Typical practice: write failing tests, make them pass, write more failing tests, make them pass, etc. • SO, you will only be submitting passing tests. BUT, we will use git logs to show your failing/passing process.
Configuration Files • Rooms (done) • Board (done) • Players – to do, you determine format • Weapons – to do, you determine format
Test Setup • Loading the configuration files • Dealing the cards • 5-minute Quick Exercise with your partner: • How can you test a correct configuration? • How can you test a correct deal?
Load Tests • How do you know if you loaded the people correctly? • Do I have the right # of people in my player’s list? • tests for common load errors, like skipping lines, missing the last line etc. • Do I have the correct data? • TDD: what data do I need? what class(es) will contain the data? How will it be stored/accessed? What’s the format of the data file? • tests for common errors when parsing data (e.g., order of the data on each line) • tests that your code correctly stores the data (e.g., person’s name is stored in a name field) similar but less complex for weapons
Deal Tests • How will you know if the deal is correct? • All cards should be dealt • All players should have roughly the same number of cards • The same card should not be given to >1 player
TDD - classes Some design decisions I’ve made for you • We’ll have a Card class to hold cards. We’ll use an enumerated type for card type. Cards also need a name. • We’ll have a Player class with two children, ComputerPlayer and HumanPlayer. Must have a list of cards. Must have a name. Must have a location. May be more… but this is what we have so far.
Test Game Actions • Test selecting a target location • Test disproving a suggestion • Test creating a suggestion • Making an accusation • Reminder: • A suggestionis a guess that’s used in the process of elimination… if I’m in the Ballroom and I say “Mrs Peacock with the Knife” then other players will try to “disprove” the suggestion by showing one card of those 3 cards (if someone has Mrs Peacock, she clearly is not the murderer). • An accusationis done by a player who thinks they know the answer. In this case, the Clue Game says yes or no (but if “no” the player can continue) • You may want to re-read the specs in the Clue Layout assignment. Yes it’s long – but it’s short compared to specs for a real system! It also contains sample games from prior semesters – so no one should say “I’ve never played Clue” – try it!
Test selecting a target location • Should only choose a valid target (calculating targets already tested – yay) • If no rooms in list, choose a target randomly • If the list includes a room, it should be chosen – unless player was just in that room. In that case, the room has the same chance of being chosen as any other square.
Test selecting a target – test design This is not a trivial test! • Issue: how to test for random behavior (e.g., ensure room is chosen randomly). • Approach: run the method multiple times, ensure that all desired behaviors are seen. Write up includes example code. • Issue: how to ensure behavior happens consistently (e.g., ensure if a room is in the list, it will be chosen) • Approach: run the method multiple times, ensure that only that behavior is seen.
With your Partner • Read the rest of the slides • Plan the failing tests • Plan when/how you’ll get the work done • Part I due Wed Mar 19 • Part II due Fri Mar 21 • Control GUI due Mon Mar 24 • Clue Board GUI due Mon Mar 25 • Swap Partners: Mar 25 • Refactor: Mar 27 - code must be ready!
Test selecting target Design decisions for you to make: • What data to pass in to pickLocation. Board cells? Integers? Pass in the Board and call startTargets inside pickLocation? • How will you ensure the player doesn’t just keep returning to the same room? • These tests are a lot of effort, are they worth it? Consider the alternative: playing the game over and over to see what the computer player is doing.
Test disproving a suggestion • If a player (human or computer) has a card that's suggested, that card is "shown" (i.e., returned). • If the player has multiple cards that match, the card to be returned is selected randomly. • Once a player has shown a card, no other players are queried. • The player making the suggestion should not be queried. • If none of the other players has any relevant cards, the error value (null) is returned • In the board game, disproving a suggestion starts with a player to the left of the person making the suggestion. Our game doesn’t have the concept of right/left, so we’ll start with the next player in the list (human must be included somehow). NOTE: The sample games don’t match this exactly, as my game specs have changed slightly from year to year.
Test disproving – test design First test the behavior of a single player • If a player has one matching card, return it. Simple way to test: create a player with known cards, call the disprove method, ensure desired card is returned. • If the player has multiple cards that match, return should be random. How to test? Set up player, use a loop, ensure that all matching cards are returned some number of times.
Test disproving – test design Testing the overall behavior to disprove a suggestion is more complex. • Setup: Create a small number of players with known cards. Be sure to include the human. • Players are queried in order. Some ways to test: • Do a query that no players can disprove, ensure null. • Do a query that only the accusing player can disprove, ensure null. • Do a query that only the human can disprove, human is not accuser, verify return. • Do a query that only the human can disprove, human is not the accuser, ensure null • Players are queried in order. Do several queries with player 0 as accuser. Do a query that player 1 and 2 can disprove, ensure player 1 disproves (ensures players are not asked after one can disprove). Do a query that human and another player can disprove, ensure correct response.
Test disproving – design decisions • How is this task assigned to the classes? • THINK: we don’t want to “reach into the pocket” of another class… so the Player should search it’s list of cards. Is this different for human than computer? No – the human player doesn’t decide what card to show. • Deciding which player to query is not done by the Player class… this should be a method of… the board? the game? • Should the parameters to disproveSuggestion be Cards or Strings? • How do we know which player is the accusing player?
Test creating a suggestion • Suggestion should not include any cards that are in the players “hand” or that have been “seen” (when other suggestions have been disproved) • Suggestion should choose randomly from the “unseen” cards
Test create suggestion – test design • Issue: this test relies on a player that has a hand and a list of “seen” cards. What should we do? • Create methods to add cards to the hand and to the list of “seen” cards • Call those methods to set up your test scenario(s) • Issue: suggestion must be based on room the player is in. How do we handle? • Create a setter so you can specify.
Test create – design decisions • Will you store Cards or Strings in the “hand” and “seen” lists? • How will you store the player’s location? • How will you represent a “suggestion” – as three strings? Maybe as a class with 3 public strings… sort of like a C++ struct? NOTE: for this usage, we can break the “private only” policy. Why is that OK?
Test Making an Accusation • Accusation = person + weapon + room • Need to ensure that all 3 are correct • fairly trivial test. • Issue: how do we know the answer? • One option: just set to known values • Design decisions: How will you store the solution? What do you call the method? Will you pass in cards or strings?