about bringing "doc tests" to PEAR
| From: | David Jean Louis | Date: | Wed, 23 Jan 2008 15:52:35 +0000 |
| Subject: | about bringing "doc tests" to PEAR | ||
| Groups: | php.pear.dev | ||
| Request: | Send a blank email to pear-dev+get-48979@lists.php.net to get a copy of this message | ||
Hi all,
Just wanted to share some thought:
I am a big fan of the doctest python module (1) and really miss it when I code in PHP.
I've been using it for years and it makes unit testing very easy, *quick* and fun, those of you who know python will certainly agree with me on this.
I wanted to know what do you think of bringing this to PEAR (and php code in general as the usage of such a package would not be limited to PEAR of course).
Some *raw* ideas of what it could look like:
<?php
/**
* File level example.
*
* Some description...
*
* <doctest>
* >>> // this is ignored, note that we do not include the current file
* >>> $foo = new Foo();
* >>> $foo->foo = 'Some string';
* >>> $foo->fooize();
* 'foo says: some foo string !'
* >>> $foo->fooize();
* (string) "foo says: some foo string !"
* >>> $foo->fooize();
* (string)
* >>> $foo->randomNumber();
* (float)
* </doctest>
*
* php doc tags here...
*/
/**
* Class level example.
*
* Class description...
*
* <doctest>
* >>> $foo = new Foo();
* >>> $foo->foo = 'Some string';
* >>> $foo->fooize();
* 'foo says: some foo string !'
* </doctest>
*
class Foo()
{
/**
* String foo..
*
* @var string $foo
* @access public
*/
public $foo = false;
/**
* Constructor.
*
* <doctest>
* >>> // obviously the following is stupid,
* >>> // it's for example purpose
* >>> $foo = new Foo();
* >>> $foo instanceof Foo;
* ... (bool)true
* >>> $foo;
* ... (object)
* >>> $foo;
* ... (object:'Foo')
* </doctest>
*
*/
function __construct()
{
}
/**
* Method level example.
*
* <doctest>
* >>> $foo = new Foo();
* >>> $foo->fooize();
* ... (Exception)
* >>> $foo->fooize();
* ... (Exception:'foo property is false')
* >>> $foo->fooize();
* ... (PEARException:'foo property is false')
* >>> $foo->foo = 'A string with an exclamation mark (should not be
* ... repeated) !'; // note how multiline could be handled
* >>> $foo->fooize();
* (string) "foo says: A foo string foo with foo an foo exclamation foo
* mark foo (should foo not foo be foo repeated) !"
* </doctest>
*
* @access public
* @return string
*/
function fooize()
{
if (false === $this->foo) {
throw new PEARException('foo property is false');
}
$tokens = explode(' ', strtolower(
preg_replace('/^(.*?)\s*\!/', '\1', $this->foo)));
return 'foo says: ' . implode(' foo ', $tokens) . ' !';
}
}
?>
The package could be named PHP_DocTest.
Writing doc tests could be done at 3 levels:
- file level,
- class level,
- class method or function level.
For a basic usage, tests could be executed from command line, assuming we have a bin/phpdoctest or something like this, this could be done like this:
$ phpdoctest <file>.php
// would display only test that failed.
$ phpdoctest <somedir>
// would process all files recursively in a directory
$ phpdoctest -v <file>.php
// would display all tests (succeeded and failed).
For more advanced usages, of course, PHP_DocTest could provide an API (2) to manage tests:
<?php
require_once 'PHP/DocTest.php';
$doctest = new PHP_DocTest(array('option1'=>'value', ...));
$doctest->addFile('file1.php');
$doctest->addFile(
'file2.php',
array('Class1', 'Class2::someMethod', 'func1')
);
$doctest->run();
?>
Another cool feature that could be added is an API to interact with PHPUnit like python does with unittest module (3), for example:
<?php
require_once 'PHPUnit.php';
require_once 'PHP/DocTest.php';
$suite = new PHPUnit_TestSuite();
// do something with the suite as always...
// add doc tests contained in File1/File2.php to our suite
$doctestSuite = PHP_DocTest::testSuite(array('File1.php', 'File2.php'));
// or this could be done like in the doctest API example, and then:
// $doctestSuite = $doctest->testSuite();
$suite->addTest($doctestSuite);
// run the tests
$suite->run();
?>
Well, that is, I just wanted to know what you think of the global idea, and launch a discussion about this.
Note: I am not writing this because I have existing code or I want to propose a package or whatever.
I think this is the kind of package that needs strong specs and a very good design, it could also be tricky to implement...
--
David
(1) http://docs.python.org/lib/module-doctest.html
(2) http://docs.python.org/lib/doctest-basic-api.html and http://docs.python.org/lib/doctest-advanced-api.html
(3) http://docs.python.org/lib/doctest-unittest-api.html