Skip to content

Commit 5e4b745

Browse files
committed
Merge pull request #6 from mybuilder/ignore-policy
Ignore policy
2 parents 58f6579 + 312a009 commit 5e4b745

4 files changed

Lines changed: 119 additions & 37 deletions

File tree

README.md

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,57 @@
1-
PHPUnit Accelerator
2-
===================
1+
# PHPUnit Accelerator
2+
33
[![Build Status](https://secure.travis-ci.org/mybuilder/phpunit-accelerator.svg?branch=master)](http://travis-ci.org/mybuilder/phpunit-accelerator)
44

55
Inspired by [Kris Wallsmith faster PHPUnit article](http://kriswallsmith.net/post/18029585104/faster-phpunit), we've created a [PHPUnit](http://phpunit.de) test listener that speeds up PHPUnit tests about 20% by freeing memory.
66

7-
Setup and Configuration
8-
-----------------------
9-
Add the following to your `composer.json` file
10-
```json
11-
{
12-
"require-dev": {
13-
"mybuilder/phpunit-accelerator": "~1.0"
14-
}
15-
}
16-
```
7+
## Installation
8+
9+
To install this library, run the command below and you will get the latest version
1710

18-
Update the vendor libraries
11+
``` bash
12+
composer require mybuilder/phpunit-accelerator
13+
```
1914

20-
curl -s http://getcomposer.org/installer | php
21-
php composer.phar install
15+
## Usage
2216

23-
Usage
24-
-----
2517
Just add to your `phpunit.xml` configuration
18+
2619
```xml
2720
<phpunit>
2821
<listeners>
2922
<listener class="\MyBuilder\PhpunitAccelerator\TestListener"/>
3023
</listeners>
3124
</phpunit>
3225
```
26+
27+
### Ignoring Tests
28+
29+
Sometimes it is necessary to ignore specific tests, where freeing their properties is undesired. For this use case, you have the ability to *extend the behaviour* of the listener by implementing the `IgnoreTestPolicy` interface.
30+
31+
As an example, if we hypothetically wanted to ignore all tests which include "Legacy" in their test filename, we could create a custom ignore policy as follows
32+
33+
```php
34+
<?php
35+
36+
use MyBuilder\PhpunitAccelerator\IgnoreTestPolicy;
37+
38+
class IgnoreLegacyTestPolicy implements IgnoreTestPolicy {
39+
public function shouldIgnore(\ReflectionObject $testReflection) {
40+
return strpos($testReflection->getFilename(), 'Legacy') !== false;
41+
}
42+
}
43+
```
44+
45+
And pass it to the constructor of our test listener in `phpunit.xml` configuration
46+
47+
```xml
48+
<phpunit>
49+
<listeners>
50+
<listener class="\MyBuilder\PhpunitAccelerator\TestListener">
51+
<arguments>
52+
<object class="\IgnoreLegacyTestPolicy"/>
53+
</arguments>
54+
</listener>
55+
</listeners>
56+
</phpunit>
57+
```

src/IgnoreTestPolicy.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace MyBuilder\PhpunitAccelerator;
4+
5+
interface IgnoreTestPolicy
6+
{
7+
/**
8+
* @return boolean
9+
*/
10+
public function shouldIgnore(\ReflectionObject $testReflection);
11+
}

src/TestListener.php

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,46 @@
44

55
class TestListener implements \PHPUnit_Framework_TestListener
66
{
7+
private $ignorePolicy;
8+
79
const PHPUNIT_PROPERTY_PREFIX = 'PHPUnit_';
810

11+
public function __construct(IgnoreTestPolicy $ignorePolicy = null)
12+
{
13+
$this->ignorePolicy = ($ignorePolicy) ?: new NeverIgnoreTestPolicy();
14+
}
15+
916
public function endTest(\PHPUnit_Framework_Test $test, $time)
1017
{
11-
$this->safelyFreeProperties($test);
18+
$testReflection = new \ReflectionObject($test);
19+
20+
if ($this->ignorePolicy->shouldIgnore($testReflection)) {
21+
return;
22+
}
23+
24+
$this->safelyFreeProperties($test, $testReflection->getProperties());
1225
}
1326

14-
private function safelyFreeProperties($test)
27+
private function safelyFreeProperties(\PHPUnit_Framework_Test $test, array $properties)
1528
{
16-
foreach ($this->getProperties($test) as $property) {
29+
foreach ($properties as $property) {
1730
if ($this->isSafeToFreeProperty($property)) {
1831
$this->freeProperty($test, $property);
1932
}
2033
}
2134
}
2235

23-
private function getProperties($test)
24-
{
25-
$reflection = new \ReflectionObject($test);
26-
27-
return $reflection->getProperties();
28-
}
29-
30-
private function isSafeToFreeProperty($property)
36+
private function isSafeToFreeProperty(\ReflectionProperty $property)
3137
{
3238
return !$property->isStatic() && $this->isNotPhpUnitProperty($property);
3339
}
3440

35-
private function isNotPhpUnitProperty($property)
41+
private function isNotPhpUnitProperty(\ReflectionProperty $property)
3642
{
3743
return 0 !== strpos($property->getDeclaringClass()->getName(), self::PHPUNIT_PROPERTY_PREFIX);
3844
}
3945

40-
private function freeProperty($test, $property)
46+
private function freeProperty(\PHPUnit_Framework_Test $test, \ReflectionProperty $property)
4147
{
4248
$property->setAccessible(true);
4349
$property->setValue($test, null);
@@ -59,3 +65,11 @@ public function startTest(\PHPUnit_Framework_Test $test) {}
5965

6066
public function addRiskyTest(\PHPUnit_Framework_Test $test, \Exception $e, $time) {}
6167
}
68+
69+
class NeverIgnoreTestPolicy implements IgnoreTestPolicy
70+
{
71+
public function shouldIgnore(\ReflectionObject $testReflection)
72+
{
73+
return false;
74+
}
75+
}

tests/TestListenerTest.php

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,34 @@
11
<?php
22

33
use MyBuilder\PhpunitAccelerator\TestListener;
4+
use MyBuilder\PhpunitAccelerator\IgnoreTestPolicy;
45

56
class TestListenerTest extends \PHPUnit_Framework_TestCase
67
{
7-
private $listener;
88
private $dummyTest;
99

1010
protected function setUp()
1111
{
12-
$this->listener = new TestListener();
1312
$this->dummyTest = new DummyTest();
1413
}
1514

1615
/**
1716
* @test
1817
*/
19-
public function shouldFreeProperty()
18+
public function shouldFreeTestProperty()
2019
{
21-
$this->endTest();
20+
$this->endTest(new TestListener());
2221

22+
$this->assertFreesTestProperty();
23+
}
24+
25+
private function endTest(TestListener $listener)
26+
{
27+
$listener->endTest($this->dummyTest, 0);
28+
}
29+
30+
private function assertFreesTestProperty()
31+
{
2332
$this->assertNull($this->dummyTest->property);
2433
}
2534

@@ -28,14 +37,29 @@ public function shouldFreeProperty()
2837
*/
2938
public function shouldNotFreePhpUnitProperty()
3039
{
31-
$this->endTest();
40+
$this->endTest(new TestListener());
3241

42+
$this->assertDoesNotFreePHPUnitProperty();
43+
}
44+
45+
private function assertDoesNotFreePHPUnitProperty()
46+
{
3347
$this->assertNotNull($this->dummyTest->phpUnitProperty);
3448
}
3549

36-
private function endTest()
50+
/**
51+
* @test
52+
*/
53+
public function shouldNotFreeTestPropertyWithIgnoreAlwaysPolicy()
54+
{
55+
$this->endTest(new TestListener(new AlwaysIgnoreTestPolicy()));
56+
57+
$this->assertDoesNotFreeTestProperty();
58+
}
59+
60+
private function assertDoesNotFreeTestProperty()
3761
{
38-
$this->listener->endTest($this->dummyTest, 0);
62+
$this->assertNotNull($this->dummyTest->property);
3963
}
4064
}
4165

@@ -48,3 +72,11 @@ class DummyTest extends \PHPUnit_Fake
4872
{
4973
public $property = 1;
5074
}
75+
76+
class AlwaysIgnoreTestPolicy implements IgnoreTestPolicy
77+
{
78+
public function shouldIgnore(\ReflectionObject $testReflection)
79+
{
80+
return true;
81+
}
82+
}

0 commit comments

Comments
 (0)