Testing levels/groups in PHPUnit
Alternative to groups is to use a naming convention:
<testsuites>
<testsuite name="unit-tests">
<directory suffix="Test.php">test</directory>
</testsuite>
<testsuite name="benchmark">
<directory suffix="Benchmark.php">test</directory>
</testsuite>
</testsuites>
Files like test/SomethingTest.php
(class SomethingTest extends TestCase {...}
) are in the unit-test
suite and files like test/SomeBenchmark.php
(class SomeBenchmark extends TestCase {...}
) are in the benchmark
suite.
It is simple, obvious and practical.
It also allows us to have test/SomeExperiment.php
(class SomeExperiment extends TestCase {...}
) that is not part of either suite (and thus it won't fail in a CI pipeline), but it still can be executed explicitly during development.
@Schleis' answer is entirely correct and very useful. The only catch (which I admittedly didn't include in my question) is that I'd like to be able to scatter Unit and Integration tests throughout our test files - I want to avoid having two files of tests - one file for Unit tests for SomeClass, and a separate file for Functional tests, also for SomeClass.
The PHPUnit command-line option that I found that enables this is groups:
--group
Only runs tests from the specified group(s). A test can be tagged as belonging to a group using the @group annotation.
To use this approach, you simply add the @group
annotation to the multiline comment before your tests as such:
class SomeClassTest extends PHPUnit_Framework_TestCase {
/**
* @group Unit
*/
public function testSomeUnitFunctionality() {
$this->assertEquals(xyz(' .a1#2 3f4!', true), ' 12 34');
}
/**
* @group Integration
*/
public function testSomeIntegrationFunctionality() {
$this->assertEquals(xyz(' .a1#2 3f4!', true), ' 12 34');
}
}
This allows me to do the following:
phpunit --group Unit
(Just unit tests)phpunit --group Integration
(Just integration tests)phpunit
(All tests)
You can write a phpunit.xml
that will seperate your tests into test suites that you can run separately.
http://phpunit.de/manual/current/en/organizing-tests.html#organizing-tests.xml-configuration
It would look similar to:
<phpunit>
<testsuites>
<testsuite name="Unit_Tests">
<directory>SomeTests</directory>
<directory>MoreTests</directory>
</testsuite>
<testsuite name="Functional_Tests">
<directory>OtherTests</directory>
</testsuite>
</testsuites>
</phpunit>
Then when you want to run only one group of tests you would call phpunit --testsuite Unit_Tests
or phpunit --testsuite Functional_Tests
as needed.