Planet PHPUnit

Sebastian Bergmann » 28 January 2008 » in PHPUnit » 0 Comments

http://planet.phpunit.de/images/logo.png

I would like to announce Planet PHPUnit, a site that aggregates blog postings related to PHPUnit.

At the moment only three feeds are aggregated on Planet PHPUnit: release announcements, articles about new features in PHPUnit written by myself, and Manuel Pichler's blog postings on phpUnderControl.

I would like to invite everyone who has blogged about PHPUnit in the past to send me a link to an RSS or Atom feed that only contains their respective blog entries that relate to PHPUnit. I would also like to encourage every user of PHPUnit to start blogging about their daily usage of PHPUnit. I think it would be wonderfull to have Planet PHPUnit become not only a hub for blog postings that document PHPUnit's development, but also an ongoing stream of case studies and usage examples.

Planet PHPUnit uses Planet, the awesome "river of news" feed reader [...] that downloads news feeds published by web sites and aggregates their content together into a single combined feed, latest news first.. I am indebted to Kore Nordmann for his work on the CSS of Planet PHPUnit.

Update: I added the PHPUnit-related feeds of Mike Lively, Sebastian Nohn, Mike Naberezny, and Lars Strojny.

Support for the Cancel Case Workflow Pattern

Sebastian Bergmann » 23 January 2008 » in New Features » 3 Comments

eZ Components

Version 1.2 of the Workflow component that is part of the eZ Components adds support for the Cancel Case workflow pattern:

Cancel Case

As soon as a node of the ezcWorkflowNodeCancel type is activated, the complete workflow instance is removed. This includes currently executing nodes, those which may execute at some future time and all parent and sub-workflows. The workflow instance is recorded as having completed unsuccessfully.

My diploma thesis paper has been updated accordingly to reflect the addition of the ezcWorkflowNodeCancel class.

Defined tags for this entry: , ,

PHPUnit 3.2.10

Sebastian Bergmann » 18 January 2008 » in Announcements » 0 Comments

  • Fixed PHPUnit_Extensions_SeleniumTestCase::matchLocalAndRemotePaths() for the case when local and remote path are identical. [2187]
Defined tags for this entry: ,

PHPUnit 3.2.9

Sebastian Bergmann » 17 January 2008 » in Announcements » 1 Comment

  • The error handler now also converts E_WARNINGs to exceptions. [2126]
  • Tweaked the colors in the CSS for the code coverage report. [2073]
  • Implemented #318: Ability to get non-hit whitelisted files. [2041]
  • Implemented #319: Added node_is_leaf flag to the test table of the test database schema. [2102]
  • Implemented #320: Configure SeleniumTestCase::$browsers through XML configuration file. [2111]
  • Implemented #328: Exception tests can now test for exception codes (Exception::getCode()). [2129]
  • Implemented #339: Add namespace separator :: as valid test organization split character. [2085]
  • Implemented #340: Better error message when the expected invocation count is not met. [2095]
  • Implemented #343: Convert remote paths to local paths for Code Coverage information from Selenium tests. [2050]
  • Implemented #345: PHPDocumentor tags for SeleniumTestCase::__call(). [2099]
  • Fixed #296: $GLOBALS backup breaks the $GLOBALS reference. [1976] [2089]
  • Fixed #327: Syntax checking does not work on Windows. [2092]
  • Fixed #332: Empty message in PHPUnit_Framework_AssertionFailedError exception. [2108]
  • Fixed #337: PHPUnit_Extensions_Database_DB_MetaData_MySQL missing. [2003]
  • Fixed #338: Unknown returntype in PHPUnit_Extensions_Database_DB_IDatabaseConnection::getConfig(). [2165]
  • Fixed #342: Syntax errors not detected. [2046]
  • Fixed #346: SeleniumTestCase::getSpeed() does not return its result. [2099]
  • Fixed #349: PHPUnit_Framework_TestFailure::exceptionToString() does not handle PHPUnit_Framework_IncompleteTestError correctly. [2161]
Defined tags for this entry: ,

Support for BDD and Stories in PHPUnit 3.3

Sebastian Bergmann » 17 January 2008 » in New Features » 7 Comments

PHPUnit_Extensions_Story_TestCase is a new extension for PHPUnit that has been contributed by Xait, a company that I visited last fall. It adds a story framework with a Domain-Specific Language (DSL) for Behaviour-Driven Development (BDD).

Start by writing a Story and a @scenario:

<?php
require_once 'PHPUnit/Extensions/Story/TestCase.php';
 
require_once 'BowlingGame.php';
 
class BowlingGameSpec extends PHPUnit_Extensions_Story_TestCase
{
    /**
     * @scenario
     */
    public function scoreForOneSpareIs16()
    {
        $this->given('New game')
             ->when('Player rolls', 5)
             ->and('Player rolls', 5)
             ->and('Player rolls', 3)
             ->then('Score should be', 16);
    }
 
    // ...
}
?>

Each given(), when() and then() is a Step. The and()s are each the same kind as the previous Step. Steps get defined like this:

<?php
require_once 'PHPUnit/Extensions/Story/TestCase.php';
 
require_once 'BowlingGame.php';
 
class BowlingGameSpec extends PHPUnit_Extensions_Story_TestCase
{
    // ...
 
    public function runGiven(&$world, $action, $arguments)
    {
        switch($action) {
            case 'New game': {
                $world['game']  = new BowlingGame;
                $world['rolls'] = 0;
            }
            break;
 
            default: {
                return $this->notImplemented($action);
            }
        }
    }
 
    public function runWhen(&$world, $action, $arguments)
    {
        switch($action) {
            case 'Player rolls': {
                $world['game']->roll($arguments[0]);
                $world['rolls']++;
            }
            break;
 
            default: {
                return $this->notImplemented($action);
            }
        }
    }
 
    public function runThen(&$world, $action, $arguments)
    {
        switch($action) {
            case 'Score should be': {
                for ($i = $world['rolls']; $i < 20; $i++) {
                    $world['game']->roll(0);
                }
 
                $this->assertEquals($arguments[0], $world['game']->score());
            }
            break;
 
            default: {
                return $this->notImplemented($action);
            }
        }
    }
}
?>

We can now ask PHPUnit to "tell our stories":

sb@vmware ~ % phpunit --story BowlingGameSpec
PHPUnit @package_version@ by Sebastian Bergmann.

BowlingGameSpec
 - Score for gutter game should be 0 [successful]

   Given New game
    Then Score should be 0

 - Score for all ones is 20 [successful]

   Given New game
    When Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
     and Player rolls 1
    Then Score should be 20

 - Score for one spare is 16 [successful]

   Given New game
    When Player rolls 5
     and Player rolls 5
     and Player rolls 3
    Then Score should be 16

 - Score for one strike is 24 [successful]

   Given New game
    When Player rolls 10
     and Player rolls 3
     and Player rolls 4
    Then Score should be 24

 - Score for perfect game is 300 [successful]

   Given New game
    When Player rolls 10
     and Player rolls 10
     and Player rolls 10
     and Player rolls 10
     and Player rolls 10
     and Player rolls 10
     and Player rolls 10
     and Player rolls 10
     and Player rolls 10
     and Player rolls 10
     and Player rolls 10
     and Player rolls 10
    Then Score should be 300

Scenarios: 5, Failed: 0, Skipped: 0, Incomplete: 0.
Defined tags for this entry: , , , ,