Reader small image

You're reading from  Instant Hands-on Testing with PHPUnit How-to

Product typeBook
Published inMay 2013
Reading LevelIntermediate
PublisherPackt
ISBN-139781782169581
Edition1st Edition
Languages
Right arrow
Author (1)
Michael Lively
Michael Lively
author image
Michael Lively

Michael Lively has worked in a variety of roles in the software development industry for over 15 years, from developer to development director. He has worked on a variety of different projects and a variety of different technologies over that time, from small home-grown sites serving a handful of regular users to large enterprise platforms serving millions of consumers. His current job is with Slickdeals.net, the largest and most trusted deal sharing community and a routine presence in the top 100 sites in the US. In addition to his professional work, he has been an active member of the PHP open source community. Some of his contributions include the database extension for PHPUnit and an alternative mocking framework for PHP called Phake.
Read more about Michael Lively

Right arrow

Using data providers (Intermediate)


Data providers are a great way to test many different variants of a single method call quickly. When you have a method that is responsible for applying an algorithm to the method arguments and come up with a predictable result then data providers are a great option.

How to do it...

Modify the contents of test/CardTest.php to the following:

<?php
class CardTest extends PHPUnit_Framework_TestCase
{
  private $card;
  public function setUp()
  {
    $this->card = new Card('4', 'spades');
  }
  public function testGetNumber()
  {
    $actualNumber = $this->card->getNumber();
    $this->assertEquals(4, $actualNumber, 'Number should be <4>');
  }
  public function testGetSuit()
  {
    $actualSuit = $this->card->getSuit();
    $this->assertEquals('spades', $actualSuit, 'Suit should be <spades>');
  }
  public function matchingCardDataProvider()
  {
    return array(
      array(new Card('4', 'hearts'), true, 'should match'),
      array(new Card('5', 'hearts'), false, 'should not match')
    );
  }

  /**
   * @dataProvider matchingCardDataProvider
   */
  public function testIsInMatchingSet(Card $matchingCard, $expected, $msg)
  {
    $this->assertEquals($expected, $this->card->isInMatchingSet($matchingCard),
        "<{$this->card->getNumber()} of {$this->card->getSuit()}> {$msg} "
        . "<{$matchingCard->getNumber()} of {$matchingCard->getSuit()}>");
  }
}

How it works...

The new matchingCardDataProvider() method is our data provider. It should return an array containing multiple arrays of arguments to pass into a test method. The method does need to be public as it actually gets called from outside the test case. Also, the method does not have to be static, as you do not have reliable access to any variable you should treat the method as though it were static.

You then need to assign the data provider to one of your test methods. This is done using the @dataProvider annotation. In this example, the annotation is assigned to the testIsInMatchingSet() method. You will notice that this method has three parameters. This is exactly the same number of items there are in each sub-array returned by matchingCardDataProvider().

The three parameters in this example are the arguments provided for isInMatchingSet(), an expected value, as well as part of the assertion failure message. When using data providers you can use the Don't Repeat Yourself (DRY) principal very effectively to reduce the amount of code you have to write for each test. However, this does need to be balanced with readability. If you reduce the amount of code that has to be written, but someone else can't understand what the test is doing then the effectiveness and maintainability of the test is actually reduced.

Identifying test failures

You may be wondering how to identify which data set failed while using the data providers. Fortunately, PHPUnit takes care of this for you. Modify the matchingCardDataProvider() method to return a row that will force the test to fail.

public function matchingCardDataProvider()
{
  return array(
    array(new Card('4', 'hearts'), true, 'should match'),
    array(new Card('5', 'hearts'), false, 'should not match'),
    array(new Card('4', 'clubs'), false, 'should not match')
  );
}

Then, run the unit test suite and you will see the following:

As you can see it tells you the index of the data set along with the actual parameters passed as a part of that data set.

This can be improved even further by providing keys to the array that your data provider returns. Try using the following data provider:

public function matchingCardDataProvider()
{
  return array(
    '4 of Hearts' => array(new Card('4', 'hearts'), true, 'should match'),
    '5 of Hearts' => array(new Card('5', 'hearts'), false, 'should not match'),
    '4 of Clubs' => array(new Card('4', 'clubs'), false, 'should not match')
  );
}

Run the tests again to see the following output:

As you can see, you can utilize data providers to not only consolidate your code, but you can also make it very easy to isolate the data set you have problems with.

Previous PageNext Page
You have been reading a chapter from
Instant Hands-on Testing with PHPUnit How-to
Published in: May 2013Publisher: PacktISBN-13: 9781782169581
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Michael Lively

Michael Lively has worked in a variety of roles in the software development industry for over 15 years, from developer to development director. He has worked on a variety of different projects and a variety of different technologies over that time, from small home-grown sites serving a handful of regular users to large enterprise platforms serving millions of consumers. His current job is with Slickdeals.net, the largest and most trusted deal sharing community and a routine presence in the top 100 sites in the US. In addition to his professional work, he has been an active member of the PHP open source community. Some of his contributions include the database extension for PHPUnit and an alternative mocking framework for PHP called Phake.
Read more about Michael Lively