Skip to content

Commit 5d60881

Browse files
committed
Merge pull request #8 from fiunchinho/using_reflection
Using reflection to set the order of the tests
2 parents c9eb13c + 4f4e88d commit 5d60881

File tree

8 files changed

+147
-203
lines changed

8 files changed

+147
-203
lines changed

example_tests/ExampleTest.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,38 @@
22

33
class ExampleTest extends \PHPUnit_Framework_TestCase
44
{
5+
public static $setUpBeforeClass = -1;
6+
public $setUp;
7+
58
public static function setUpBeforeClass()
69
{
7-
//echo __METHOD__ . "\n";
10+
self::$setUpBeforeClass = true;
811
}
912

1013
public static function tearDownAfterClass()
1114
{
12-
//echo __METHOD__ . "\n";
15+
self::$setUpBeforeClass = false;
1316
}
1417

1518
public function setUp()
1619
{
17-
//echo __METHOD__ . "\n";
20+
$this->setUp = true;
1821
}
1922

2023
public function tearDown()
2124
{
22-
//echo __METHOD__ . "\n\n";
25+
$this->setUp = false;
2326
}
2427

2528
public function test1()
2629
{
30+
$this->assertTrue(self::$setUpBeforeClass);
2731
echo __METHOD__ . "\n";
2832
}
2933

3034
public function test2()
3135
{
36+
$this->assertTrue($this->setUp);
3237
print __METHOD__ . "\n";
3338
}
3439

example_tests/OtherExampleTest.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,39 @@
22

33
class OtherExampleTest extends \PHPUnit_Framework_TestCase
44
{
5+
public static $setUpBeforeClass = -1;
6+
public $setUp;
7+
58
public static function setUpBeforeClass()
69
{
7-
//echo __METHOD__ . "\n";
10+
self::$setUpBeforeClass = true;
811
}
912

1013
public static function tearDownAfterClass()
1114
{
12-
//echo __METHOD__ . "\n";
15+
self::$setUpBeforeClass = false;
1316
}
1417

1518
public function setUp()
1619
{
17-
//echo __METHOD__ . "\n";
20+
$this->setUp = true;
1821
}
1922

2023
public function tearDown()
2124
{
22-
//echo __METHOD__ . "\n\n";
25+
$this->setUp = false;
2326
}
2427

2528
public function test1()
2629
{
30+
$this->assertTrue(self::$setUpBeforeClass);
2731
echo __METHOD__ . "\n";
2832
}
2933

3034
public function test2()
3135
{
32-
echo __METHOD__ . "\n";
36+
$this->assertTrue($this->setUp);
37+
print __METHOD__ . "\n";
3338
}
3439

3540
public function test3()

src/PHPUnitRandomizer/Command.php

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,26 @@
33

44
class Command extends \PHPUnit_TextUI_Command
55
{
6-
/**
7-
* Seed for the randomizer.
8-
*
9-
* Defaults to -1 until customized or when default value gets set.
10-
*
11-
* @var int
12-
*/
13-
protected $seed = -1;
14-
156
public function __construct()
167
{
17-
$this->longOptions['seed='] = 'seedHandler';
188
$this->longOptions['order='] = 'orderHandler';
19-
$this->seed = rand(0, 9999);
20-
$this->order = 'defined';
219
}
2210

2311
public static function main($exit = TRUE)
2412
{
2513
return parent::main($exit);
2614
}
2715

28-
private function setSeedToPrinter($seed)
16+
/**
17+
* Only called when 'order' argument is used.
18+
*
19+
* @param string $order_parameter The order argument passed in command line.
20+
*/
21+
protected function orderHandler($order_parameter)
2922
{
30-
if (isset($this->arguments['printer']) && $this->arguments['printer'] instanceof ResultPrinter )
31-
{
32-
$this->arguments['printer']->setSeed($seed);
33-
}
23+
list($order, $seed) = $this->getOrderAndSeed($order_parameter);
24+
$this->arguments['order'] = $order;
25+
$this->arguments['seed'] = $seed;
3426
}
3527

3628
/**
@@ -44,7 +36,7 @@ private function getOrderAndSeed($order)
4436
@list($order, $seed) = explode(':', $order, 2);
4537

4638
if (empty($seed)) {
47-
$seed = $this->seed;
39+
$seed = $this->getRandomSeed();
4840
}
4941

5042
if (!is_numeric($seed)) {
@@ -54,19 +46,14 @@ private function getOrderAndSeed($order)
5446
return array($order, $seed);
5547
}
5648

57-
protected function orderHandler($order_parameter)
49+
private function getRandomSeed()
5850
{
59-
list($order, $seed) = $this->getOrderAndSeed($order_parameter);
60-
$this->order = $order;
61-
$this->arguments['order'] = $order;
62-
$this->seed = $seed;
63-
$this->arguments['seed'] = $seed;
64-
$this->setSeedToPrinter($this->seed);
51+
return rand(0, 9999);
6552
}
6653

6754
protected function createRunner()
6855
{
69-
return new TestRunner($this->arguments['loader'], null, $this->seed);
56+
return new TestRunner($this->arguments['loader']);
7057
}
7158

7259
public function showHelp()

src/PHPUnitRandomizer/Decorator.php

Lines changed: 0 additions & 115 deletions
This file was deleted.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
namespace PHPUnitRandomizer;
4+
5+
class Randomizer
6+
{
7+
/**
8+
* Order the TestSuite tests in a random order.
9+
*
10+
* @param TestSuite $suite The suite to randomize.
11+
* @param array $arguments Arguments to use.
12+
* @return \PHPUnit_Framework_Test
13+
*/
14+
public function randomizeTestSuite(\PHPUnit_Framework_Test $suite, $seed)
15+
{
16+
if ($this->testSuiteContainsOtherSuites($suite))
17+
{
18+
$this->randomizeSuiteThatContainsOtherSuites($suite, $seed);
19+
}
20+
else
21+
{
22+
$this->randomizeSuite($suite, $seed);
23+
}
24+
25+
return $suite;
26+
}
27+
28+
/**
29+
* Randomize each Test Suite inside the main Test Suite.
30+
*
31+
* @param [type] $suite Main Test Suite to randomize.
32+
* @param [type] $seed Seed to use.
33+
* @return \PHPUnit_Framework_Test
34+
*/
35+
private function randomizeSuiteThatContainsOtherSuites($suite, $seed)
36+
{
37+
$order = 0;
38+
foreach ($suite->tests() as $test) {
39+
$this->randomizeSuite($test, $seed, $order);
40+
$order++;
41+
}
42+
43+
return $this->randomizeSuite($suite, $seed, $order);
44+
}
45+
46+
/**
47+
* Test Suites can contain other Test Suites or just Test Cases.
48+
*
49+
* @param \PHPUnit_Framework_Test $suite [description]
50+
* @return Boolean
51+
*/
52+
private function testSuiteContainsOtherSuites($suite)
53+
{
54+
$tests = $suite->tests();
55+
return isset($tests[0]) && $tests[0] instanceof \PHPUnit_Framework_TestSuite;
56+
}
57+
58+
/**
59+
* Randomize the test cases inside a TestSuite, with the given seed.
60+
*
61+
* @param \PHPUnit_Framework_Test $suite Test suite to randomize.
62+
* @param integer $seed Seed to be used for the random funtion.
63+
* @param integer $order Arbitrary value to "salt" the seed.
64+
* @return \PHPUnit_Framework_Test
65+
*/
66+
private function randomizeSuite($suite, $seed, $order = 0)
67+
{
68+
$reflected = new \ReflectionObject($suite);
69+
$property = $reflected->getProperty('tests');
70+
$property->setAccessible(true);
71+
$property->setValue($suite, $this->randomizeTestsCases($suite->tests(), $seed, $order));
72+
73+
return $suite;
74+
}
75+
76+
/**
77+
* Randomize an array of TestCases.
78+
*
79+
* @param array $tests TestCases to randomize.
80+
* @param integer $seed Seed used for PHP to randomize the array.
81+
* @param integer $order A salt so it doesn't randomize all the classes in the same "random" order.
82+
* @return array Randomized array
83+
*/
84+
private function randomizeTestsCases(array $tests, $seed, $order)
85+
{
86+
srand($seed + $order);
87+
shuffle($tests);
88+
return $tests;
89+
}
90+
}

0 commit comments

Comments
 (0)