Since PHPUnit 3.4.0 a new extension point for interacting with issue tracking systems (TTS) based on the test results has been added to PHP's first choice xUnit framework. The extension point has been introduced by an abstract PHPUnit_Extensions_TicketListener class, which allows developer to add tailor-made ticket listeners supporting their favoured TTS. Currently PHPUnit ships with a single ticket listener for Trac as it's still the used TTS for the framework itself. As I start to become more and more accustomed to use GitHub for some of my exploratory projects and hacks, the following blog post will contain a GitHub_TicketListener implementation and a showcase of it's usage.Annotating tests with ticket meta dataAs you might know, it's considered to be a best practice to write a test for each new ticket representing a bug and drive the system under test (SUT) till the issue is resolved. This extension of test-driven development is also known as test-driven bug fixing. To create a relation between these tests and their associated tickets, PHPUnit provides a new @ticket annotation which will be analyzed before each test is run. The following code listing shows such an annotated test.<?phpPeeking at the GitHub_TicketListener implementationThe current version (3.4.6) of PHPUnit has a pending issue regarding the abstract TicketListener class, so the first step is to apply an 'exploratory' patch, which might break the functionality of the shipped Trac ticket listener but will enable the use of the one for GitHub's TTS.
require_once 'PHPUnit/Framework.php';
class ExampleTest extends PHPUnit_Framework_TestCase
{
....
/**
* @ticket 2
* @test
*/
public function shouldGuarantyThatTheSutHandlesTheIssueCorrectly()
{
// test code
}
....
The next step en route to a working GitHub_TicketListener is to extend the patched abstract PHPUnit_Extensions_TicketListener class. This abstract class contains two abstract methods named getTicketInfo and updateTicket which have to be implemented by the specific ticket listener class, and will be responsible for the interaction with the TTS.
The implementation of the getTicketInfo method retrieves the ticket status for the annotated ticket, while the updateTicket method is responsible for changing the ticket status based on the test result and the former ticket state. Both implementations make use of the relevant TTS part of the GitHub API by utilizing PHP's curl extension as shown in the next code listing which alternatively is available via this gist.
<?php
require_once('PHPUnit/Extensions/TicketListener.php');
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
/**
* A ticket listener that interacts with the GitHub issue API.
*/
class PHPUnit_Extensions_TicketListener_GitHub extends
PHPUnit_Extensions_TicketListener
{
const STATUS_CLOSE = 'closed';
const STATUS_REOPEN = 'reopened';
private $_username = null;
private $_apiToken = null;
private $_repository = null;
private $_apiPath = null;
private $_printTicketStateChanges = false;
/**
* @param string $username The username associated with the GitHub account.
* @param string $apiToken The API token associated with the GitHub account.
* @param string $repository The repository of the system under test (SUT) on GitHub.
* @param string $printTicketChanges Boolean flag to print the ticket state
* changes in the test result.
* @throws RuntimeException
*/
public function __construct($username, $apiToken, $repository,
$printTicketStateChanges = false)
{
if ($this->_isCurlAvailable() === false) {
throw new RuntimeException('
Truncated by Planet PHP, read more at the original (another 8040 bytes)