PHP Developers Network

Testing that array gets shuffled
Page 1 of 1

Author:  Luke [ Thu Nov 08, 2012 4:19 pm ]
Post subject:  Testing that array gets shuffled

I really am rusty! Sheesh! I can't think of a good way to test this. Basically I have a deck of cards and I want to make sure that its shuffle() method shuffles the cards. The testing code doesn't have access to the internal array of the class though, so how do I test that the order isn't the same?

Syntax: [ Download ] [ Hide ]
$deck = new Cards\Deck;
$deck->shuffle(); // randomizes internal $deck->_cards;
// now how do I know it's shuffled?

I can't just test the top card, because it could, by chance, be the same card. And the class doesn't have any external access to the cards other than deal() which pops off the top card, so how do I test this? Should I add something like Cards\Deck::getCards() that returns the cards array?

Author:  requinix [ Thu Nov 08, 2012 6:09 pm ]
Post subject:  Re: Testing that array gets shuffled

I keep bouncing between ideas but I know that I would try to avoid adding methods to the class just so you can write a more complete test suite.

Right now I'm thinking you can subclass Deck to provide the functionality you need specifically for testing.
Syntax: [ Download ] [ Hide ]
namespace Test\Cards;

class DeckTestHelper extends \Cards\Deck {
    public function getCards() {
        return $this->cards; // make sure $cards is protected

Or even make the subclass be the test code itself.

My next choice would be to use existing functionality, even if the test code has to work a bit harder. Like if you still need a foreach on the Deck then you can build and compare an array of cards before and after the shuffle. But it's quite possible that you'll decide that foreaching (or otherwise iterating) over the cards in the deck doesn't make sense as an appropriate use case either - it's not like anyone should be able to thumb through the deck looking at what's there.

Author:  Luke [ Thu Nov 08, 2012 6:22 pm ]
Post subject:  Re: Testing that array gets shuffled

Oooh I think I like your first idea. Thanks!

Author:  josh [ Tue Jul 02, 2013 7:19 pm ]
Post subject:  Re: Testing that array gets shuffled

You could serialize the results to a string and hash that. Shuffle & hash multiple times, then assert you have a minimum number of unique results. Regarding requinix's comment about avoiding a getCards() method on the class, there's nothing wrong with having that method. Why don't you want that method? If there's a temptation to get at some state during testing, there's probably a use to get at that state during production too. The need may not be immediate, but its often inevitable. e.g. maybe you need an audit feature for admins later on. Just like the test is auditing the cards, maybe an admin user needs to audit the cards after a game is played. Having the method doesn't hurt. Security concerns go in the controller, not the model which is the part you're testing.

Private state is a code smell IMO. Encapsulation isn't about disallowing the programmer from inspecting state. Its about allowing him to use the object without having to inspect the state.

Page 1 of 1 All times are UTC - 5 hours
Powered by phpBB® Forum Software © phpBB Group