Writing your first test (Simple)
One of the primary goals of PHPUnit is to make it easy to write tests. The easier it is to write tests, the more likely it is that tests will be written. In this recipe, we will discuss the basic parts of a test and how to implement each of those parts in PHPUnit.
Getting ready...
Each test in our system will consist of four parts: the fixture, the test, the verification, and the tear down. The fixture sets up the unit that you are testing to have the necessary state for the rest of the test. The test then exercises the system, typically by calling a single method. When verifying the test you are just checking to see if the results of our method are what you expected them to be. The tear down step is actually very rarely needed in PHP as memory management is handled for you. Occasionally, you may need to close files, delete data, or manage other external resources. The tear down part of a test is the appropriate place to do this work.
How to do it...
We will begin by testing the Card
class unit.
The following code defines that class and should be put in
Card.php
:<?php class Card { private $number; private $suit; public function __construct($number, $suit) { $this->number = $number; $this->suit = $suit; } public function getNumber() { return $this->number; } public function getSuit() { return $this->suit; } public function isInMatchingSet(Card $card) { return ($this->getNumber() == $card->getNumber()); } }
The following code defines a test for this unit and should be put in
CardTest.php
:<?php require 'Card.php'; class CardTest extends PHPUnit_Framework_TestCase { public function testGetNumber() { $card = new Card('4', 'spades'); $actualNumber = $card->getNumber(); $this->assertEquals(4, $actualNumber, 'Number should be <4>'); } public function testGetSuit() { $card = new Card('4', 'spades'); $actualSuit = $card->getSuit(); $this->assertEquals('spades', $actualSuit, 'Suit should be <spades>'); } public function testIsInMatchingSet() { $card = new Card('4', 'spades'); $matchingCard = new Card('4', 'hearts'); $this->assertTrue($card->isInMatchingSet($matchingCard), '<4 of Spades> should match <4 of Hearts>'); } public function testIsNotInMatchingSet() { $card = new Card('4', 'spades'); $matchingCard = new Card('5', 'hearts'); $this->assertFalse($card->isInMatchingSet($matchingCard), '<4 of Spades> should not match <5 of Hearts>'); } }
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
How it works...
The CardTest
class extends the PHPUnit_Framework_TestCase
class to create our first unit test. The PHPUnit_Framework_TestCase
class is what makes this a test. It takes care of all of the low-level tasks of testing for us so that we can just focus on writing the tests in an easy and concise manner.
In each of our tests you can see that we first create our fixture: one or more instances of our Card
classes. Next, we call the method that we are testing. Finally, we utilize PHPUnit's assert methods to verify the results of the tested methods.
We always pass a message as the final argument to our assert functions. This will be displayed by PHPUnit should any of our tests fail due to these assertions. It can be very important as your test suite gets larger and as time passes to have a good description of our failures so that we clearly understand the expected behavior and what broke. Not only will this provide us a reminder of how the test works, it could also be invaluable to anyone else that works on our code in the future.
The other important thing to note is the require "Card.php"
line. Your test will already have access to any PHPUnit framework classes and functions; however, you must include the code you are testing yourself. If this line is not present, when the test is run you will get an error because PHPUnit doesn't know about the Card
class. In a later recipe we will see a much easier way to include the code.
There's more...
Even though these are all simple tests, we are beginning to see some of the simplicity of PHPUnit. One of the most important things that we need to know to effectively use PHPUnit is the basic assert methods it supplies. The ability to perform basic value checking is available, but there are also more complicated assertions possible on arrays, objects, and even XML. Have a look at http://www.phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.assertions to see all of the assertion methods you have access to.
Class names
It is a common practice in PHPUnit to name your test case class after the class it is responsible for testing. We are using that method here. The CardTest
class is testing the Card
class. Naming your test case classes in this fashion makes your tests easier to find and also makes it easier to understand what class a test case is responsible for covering.