Peewee
Moderator: General Moderators
- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
Peewee
I wrote this about a month ago. I was going to finish the mock object support but I still haven't got round to it so I'm setting it up on Google code anyway. There's a User manual in HTML in the repo if you check it out.
If you would like to have a philosophical discussion about the direction I should take it in I'd be most open to that.
If you would like to have a philosophical discussion about the direction I should take it in I'd be most open to that.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
Being on the same page
.
Myself and Travis S wicegood are also working on some new/revised testing/specing frameworks. You should run a search for PHPSpec (a behavour driven development framework based on rspec), PHPMock and there's rumour of a revised PHPT style setting also
.I'm working primarily on PHPSpec (met it while writing Ruby way back when), and I expect an initial lightweight release in a few weeks (requesting a review before then from what's in svn a week from now). I'll also be looking into some TestNG style options. We're aimed at least partly on avoiding File based setup (e.g. PHPUnit's AllTests.php) in favour of a directory iterator and detect solution.
There could be points in this (e.g. PHPMock) where collaboration could benefit both of us. Travis and I are keen to have an independent Mock Object framework not tied in to any one framework. As far as I know only SimpleTest has a really good Mocking solution so far (PHPUnit's doesn't seem all that great to date - maybe when it's better documented and tested).
I'm downloading the code for a look - I think a lightweight unit testing library would be quite welcome in PHP and best of luck with it!
Myself and Travis S wicegood are also working on some new/revised testing/specing frameworks. You should run a search for PHPSpec (a behavour driven development framework based on rspec), PHPMock and there's rumour of a revised PHPT style setting also
There could be points in this (e.g. PHPMock) where collaboration could benefit both of us. Travis and I are keen to have an independent Mock Object framework not tied in to any one framework. As far as I know only SimpleTest has a really good Mocking solution so far (PHPUnit's doesn't seem all that great to date - maybe when it's better documented and tested).
I'm downloading the code for a look - I think a lightweight unit testing library would be quite welcome in PHP and best of luck with it!
- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
I tell you what. In the interest of not flooding the market with stuff and ultimate community benefit. why don't I just discontinue development of peewee (it has been that way for a month already anyway) and help you guys out with PHPMock then. I am I right in thinking you've no source just for PHPMock? I couldn't see any in the svn browser.There could be points in this (e.g. PHPMock) where collaboration could benefit both of us.
Sounds like an excellent idea to me.Travis and I are keen to have an independent Mock Object framework not tied in to any one framework.
Hang on, I thought you both you and Travis are involved in the using more PHP 5 and re-writing the mock objects for SimpleTest? And now your going off and starting your own framework as well?As far as I know only SimpleTest has a really good Mocking solution so far
The object model I have created for smalltalk mock objects make use of expectations, so that the construct of the mock object appears along the lines of (loosely translated to php):There are also convenience methods for passing an array of return values to the expectation, to save calling return() many times 
I can also specify the methods manually, so I don't have to use a specification:Just an insight in case you guys may be looking for ideas/user stories 
Code: Select all
$mock = new MockObject('SomeClass');
$expectSomeMethod = $mock->expectCall('SomeMethod');
$expectSomeMethod->return('foovalue', 1); // returns 'foovalue' on the first call
$expectSomeMethod->returnDefault(null); // return null on all calls without specified return value
$expectSomeMethod->expectNumberOfCalls('SomeMethod', 5); // expect 5 calls to SomeMethod()
$object->setSomeClass($mock);
$object->doSomething();
$this->should($mock->evaluate()); // evalute on MockObject iterates through all expectations and calls evalutate() on each, which in turn validates behaviour of the expectation.I can also specify the methods manually, so I don't have to use a specification:
Code: Select all
$mock = new MockObject();
$mock->addMethod('SomeMethod');- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
Well, you can grab us on the PHPSpec-Devel mailing list - http://www.phpspec.org redirects to our Google page.I tell you what. In the interest of not flooding the market with stuff and ultimate community benefit. why don't I just discontinue development of peewee (it has been that way for a month already anyway) and help you guys out with PHPMock then. I am I right in thinking you've no source just for PHPMock? I couldn't see any in the svn browser.
I wouldn't actually ask you stop peewee development. There is quite a bit of room around for alternate (Unit/Other) Testing libraries. So the niche is fair game
You're right in that we have no code for PHPMock yet, it was literally start PHPSpec, wonder if a Mocking library existed, finding it didn't, and off went PHPMock to Google Code. We haven't had time to do any planning for it yet so your timing would be impeccable
We're both SimpleTest users and developers/maintainers/infrequent bug solvers actuallyHang on, I thought you both you and Travis are involved in the using more PHP 5 and re-writing the mock objects for SimpleTest? And now your going off and starting your own framework as well?
SimpleTest, as far as I'm concerned, is the best TDD friendly UT framework existing for PHP (PHPUnit likes to think it is for some reason
Anyway, after nattering on for too many words (again) - get onto the PHPSpec mailing list
- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
Uhhh, I don't know any more. I'm not even sure I'm going to be writing PHP for that much longer. I'm considering enforcing a personal rule of only maintaining existing things. Of course that could mean I'm still using it for at least a year. You made a lot of sense with what you say there Maugrim and I do like Peewee, I'm just very unsure about where to take it. There's only so much you can do with minimalism. I should start by documenting the API.
Anyway, I got the opportunity to use Peewee in a bit of a server test here. Also I wrote this in a way so as to test the tests would fail incorrect data which is not something I've done before. I enclose the code for your interest:
run.php
testVersions.php
Seems like a hell of a lot of code for very simple checks but they couldn't be much more thorough or strong. Some of these things could make it into the standard peewee.php - Evil objects, sounds good doesn't it 
Anyway, I got the opportunity to use Peewee in a bit of a server test here. Also I wrote this in a way so as to test the tests would fail incorrect data which is not something I've done before. I enclose the code for your interest:
run.php
Code: Select all
<?php
require_once 'peewee/peewee.php';
class Evil
{
protected function _randomElement($array)
{
return array_slice($array, mt_rand(0, count($array)), 1);
}
}
abstract class ServerTestCase extends Peewee_UnitTestCase
{
private $_isEvil;
public function __construct($isEvil = false)
{
$this->_isEvil = $isEvil;
}
final public function setUp()
{
if ($this->_isEvil) {
$this->setUpEvil();
} else {
$this->setUpNice();
}
$this->_secondrySetup();
}
public function setUpEvil() {}
public function setUpNice() {}
protected function _secondrySetup() {}
}
foreach (glob('test*.php') as $testFile) {
require_once $testFile;
}
/**
* Runs tests in a nice and evil way and shows the discrepencies
*/
function runTests()
{
// numbers of passes for each test need to be records because the
// evil versions should have that many failures
$passCounts = array();
// runs all the test cases in nice mode
foreach (Peewee_Runner::getDefinedTestCases() as $testCase) {
$testCase->run();
$passCounts[get_class($testCase)] = $testCase->getCounter()->get('pass');
}
// runs all the test cases in evil mode
foreach (get_declared_classes() as $class) {
if (strpos($class, 'Evil') === 0 && strlen($class) > 4) {
$caseName = 'Test' . substr($class, strlen('Evil'));
$case = new $caseName(true);
ob_start();
$case->run(); // won't need to show output if there aren't discrepencies
$output = ob_get_contents();
ob_end_clean();
$failures = $case->getCounter()->get('fail');
if ($failures !== $passCounts[$caseName]) {
// differences found
echo "Expected to find {$passCounts[$caseName]} failures from evil case but found $failures:\n";
echo " >>>> \n$output <<<<\n\n";
}
}
}
echo array_sum($passCounts), " passes\n";
}
runTests();Code: Select all
<?php
interface Versions_Interface
{
function getIssueName();
function getIssueVersion();
function getPhpVersion();
function getApacheVersion();
}
class Versions implements Versions_Interface
{
const VERSION_REGEX = '~(\d+\.?)+~';
const ISSUE_FILENAME = '/etc/issue.net';
private function _getIssueParts()
{
if (!is_readable(self::ISSUE_FILENAME)) {
throw new Exception('Unable to read issue file ' . (file_exists(self::ISSUE_FILENAME) ? 'but does' : 'and does not') . ' exist');
}
return preg_split('~\s+~', trim(file_get_contents(self::ISSUE_FILENAME)), -1, PREG_SPLIT_NO_EMPTY);
}
public function getIssueName()
{
list($issue) = $this->_getIssueParts();
return strtolower($issue);
}
public function getIssueVersion()
{
foreach ($this->_getIssueParts() as $part) {
if (preg_match(self::VERSION_REGEX, $part)) {
return $part;
}
}
throw new Exception('Could not find version data in issue file (' . self::ISSUE_FILENAME . ')');
}
public function getPhpVersion()
{
return PHP_VERSION;
}
public function getApacheVersion()
{
preg_match('~(\d+\.?)+~', `apache2ctl -v | grep version`, $matches);
return $matches[0];
}
}
// All/any of these should cause failures in the tests, if they don't we'll hear about it
class Evil_Versions extends Evil implements Versions_Interface
{
public function getIssueName()
{
return $this->_randomElement(array('Debian', 'ubun', 'Ubun'));
}
public function getIssueVersion()
{
return $this->_randomElement(array('6.11', '6.09', '7.0'));
}
public function getPhpVersion()
{
return $this->_randomElement(array('5.2.2', '5.2.4', '2'));
}
public function getApacheVersion()
{
return $this->_randomElement(array('2.1', '2.054', '1.9', '2.2'));
}
}
class Test_Versions extends ServerTestCase
{
private $_vers;
public function setUpNice()
{
$this->_vers = new Versions();
}
public function setUpEvil()
{
$this->_vers = new Evil_Versions();
}
public function testUbuntu610()
{
$this->assertEqual($this->_vers->getIssueName(), 'ubuntu');
$this->assertEqual($this->_vers->getIssueVersion(), '6.10');
}
public function testPhpVersion()
{
$this->assertEqual($this->_vers->getPhpVersion(), '5.2.3');
}
public function testApache20()
{
$this->assertTrue(
version_compare($this->_vers->getApacheVersion(), '2.0.55') >= 0 &&
version_compare($this->_vers->getApacheVersion(), '2.1') < 0
);
}
}