This library sits on top of PHPUnit and adds sugar to make it easier to work with large test suites. The primary feature is test chunking which gives you the ability to run your tests in parallel chunks.
TODO:
- Dependencies need to be cleaned up.
- Move command line classes with execute() methods to own namespace.
- Try to identify and remove assumptions/hardcoded things that won't work for other people.
Run all tests:
./bin/phpchunkit all
Run just unit tests:
./bin/phpchunkit unit
Run all functional tests:
./bin/phpchunkit functional
Run a specific chunk of functional tests:
./bin/phpchunkit functional --chunk=1
Watch your code for changes and run tests:
./bin/phpchunkit watch
Run tests that match a filter:
./bin/phpchunkit filter BuildSandbox
Run a specific file:
./bin/phpchunkit file tests/PHPChunkit/Test/BuildSandboxTest.php
Run tests for changed files:
Note: This relies on git to know which files have changed.
./bin/phpchunkit changed
Create test databases and schema:
./bin/phpchunkit create-dbs
With the chunk
, num-chunks
, sandbox
and create-dbs
options you can run multiple
chunks in parallel in sandboxed environments across multiple servers or even on a single server.
Here is an example:
# Server 1
./bin/phpchunkit functional --num-chunks=4 --chunk=1 --sandbox --create-dbs
./bin/phpchunkit functional --num-chunks=4 --chunk=2 --sandbox --create-dbs
# Server 2
./bin/phpchunkit functional --num-chunks=4 --chunk=3 --sandbox --create-dbs
./bin/phpchunkit functional --num-chunks=4 --chunk=4 --sandbox --create-dbs
Hook this up to something like Jenkins and you can scale your tests and keep them fast! At OpenSky our test suite takes 25 to 30 minutes when ran serially but when ran across 14 parallel jobs on a single Jenkins server they take ~2 minutes.
It is important to note that you are responsible for implementing the sandbox preparation, database creation and sandbox cleanup processes by adding EventDispatcher listeners. You can listen for the following events:
sandbox.prepare
- Use theEvents::SANDBOX_PREPARE
constant.sandbox.cleanup
- Use theEvents::SANDBOX_CLEANUP
constant.databases.create
- Use theEvents::DATABASES_CREATE
constant.
Here is an example setup:
#!/usr/bin/env php
<?php
use PHPChunkit\Configuration;
use PHPChunkit\Events;
use PHPChunkit\TesterApplication;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
$rootDir = realpath(__DIR__.'/..');
$sourceDir = sprintf('%s/src', $rootDir);
$testsDir = sprintf('%s/tests', $rootDir);
$phpunitPath = sprintf('%s/vendor/bin/phpunit', $rootDir);
require_once $rootDir.'/vendor/autoload.php';
$input = new ArgvInput();
$output = new ConsoleOutput();
$app = new Application();
$configuration = (new Configuration())
->setRootDir($rootDir)
->setWatchDirectories([$sourceDir, $testsDir])
->setTestsDirectory($testsDir)
->setPhpunitPath($phpunitPath)
;
$eventDispatcher = $configuration->getEventDispatcher();
$eventDispatcher->addListener(Events::SANDBOX_PREPARE, function() {
// prepare a sandboxed environment
// modify database configuration files here
});
$eventDispatcher->addListener(Events::SANDBOX_CLEANUP, function() {
// cleanup modified database configuration file and cleanup sandboxed databases
});
$eventDispatcher->addListener(Events::DATABASES_CREATE, function() {
// create test databases
});
$testerApplication = new TesterApplication($app, $configuration);
$testerApplication->run($input, $output);
Take a look at the example in bin/phpchunkit which has example listeners using MySQL.