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.