PHPUnit¶
If you don't yet feel confident completely switching to a different test runner, BlackBox can also be used with PHPUnit.
As a data provider¶
use Innmind\BlackBox\{
PHPUnit\BlackBox,
Set,
};
use PHPUnit\Framework\{
TestCase,
Attributes\DataProvider,
};
final class MyTestCase extends TestCase
{
use BlackBox;
#[DataProvider('values')]
public function testAddIsCommutative(int $a, int $b)
{
$this->assertSame(
add($a, $b),
add($b, $a),
);
}
public static function values(): iterable
{
return self::forAll(
Set::integers(),
Set::integers(),
)->asDataProvider();
}
}
This will generate 100
scenarii for the test.
By using BlackBox as a data provider you enter into some limitations:
- you won't benefit from the shrinking mechanism
- you may run out of memory (since PHPUnit keep in memory all scenarii data)
Like BlackBox¶
The previous example becomes:
use Innmind\BlackBox\{
PHPUnit\BlackBox,
Set,
};
use PHPUnit\Framework\TestCase;
final class MyTestCase extends TestCase
{
use BlackBox;
public function testAddIsCommutative(int $a, int $b)
{
$this
->forAll(
Set::integers(),
Set::integers(),
)
->then(function(int $a, int $b) {
$this->assertSame(
add($a, $b),
add($b, $a),
);
});
}
}
Here you need to use the PHPUnit methods to write your assertions. BlackBox only deals with generating and shrinking data.
Like this BlackBox is able to shrink a failing scenario. But to see the generated input values you need to add an extension.
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
colors="true"
bootstrap="vendor/autoload.php"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.1/phpunit.xsd">
<extensions>
<bootstrap class="Innmind\BlackBox\PHPUnit\Extension">
</bootstrap>
</extensions>
<testsuites>
<testsuite name="Test suite">
<directory>./tests</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory>.</directory>
</include>
</source>
</phpunit>
Running your tests via BlackBox¶
If you wish to migrate to BlackBox but don't want to rewrite all your existing tests you can run them directly via BlackBox.
The first step is to prefix the PHPUnit\Framework\TestCase
class with Innmind\BlackBox\
.
The second step is to load the tests like this:
use Innmind\BlackBox\{
Application,
PHPUnit\Load,
};
Application::new()
->tryToProve(function() {
yield from Load::testsAt('path/to/your/tests');
})
->exit();
If you want to take a look at a migration you can look at BlackBox's own PHPUnit tests that are now run via BlackBox itself.
Running BlackBox's PHPUnit tests via BlackBox increase execution speed by 35% (from ~7.1s down to ~4.6s) on a MackBook Pro M1 Max.
Display all scenarii¶
If you've declared your proofs inside a PHPUnit test method, when run directly via BlackBox it will show up as a single scenario. On top of that you can't see the shrinking mechanism.
You can better integrate these proofs inside BlackBox via these changes:
use Innmind\BlackBox\{
PHPUnit\BlackBox,
Set,
};
use PHPUnit\Framework\TestCase;
final class MyTestCase extends TestCase
{
use BlackBox;
public function testAddIsCommutative(int $a, int $b): BlackBox\Proof
{
return $this
->forAll(
Set::integers(),
Set::integers(),
)
->prove(function(int $a, int $b) {
$this->assertSame(
add($a, $b),
add($b, $a),
);
});
}
}
Instead of calling $this->forAll()->then()
you call $this->forAll()->prove()
and return the object.
Now each scenario will be correctly displayed and the number of scenarii configured in Innmind\BlackBox\Application
is correctly respected (no need to use the BLACKBOX_SET_SIZE
environment variable anymore).
Note
Note that the calls to ->take()
and ->disableShrinking()
won't do anything in this context as it uses the global configuration.
Feature coverage¶
PHPUnit is a very large testing framework with lots of features. BlackBox doesn't support all its features when running your tests.
Supported features:
- test
setUp()
/tearDown()
- assertions that have a correspondance in BlackBox
- data providers declared with an attribute
- groups declared with an attribute (the name must have a correspondance in
Innmind\BlackBox\Tag
)
Some important features that are not supported:
- mocks
- classes
setUpBeforeClass()
/tearDownAfterClass()
- assertions that don't have a correspondance in BlackBox (such as files assertions)