w3resource

Organizing Tests in PHPUnit

Introduction

Tests organization is very important in PHPUnit. One of the primary goals of PHPUnit is that tests should be composable and independent: we want to be able to run any number or combination of tests together without interference.

For instance, the tests for a whole project, or the tests for all classes of a component that is part of a project, or just the tests for a single class should run without one disrupting the other.

PHPUnit supports different ways of organizing tests and composing them into a test suite, but this tutorial looks at the most commonly used approaches.

#Composing a Test Suite Using the Filesystem

This type of file organization is probably the easiest way to compose a test suite. It involves keeping all the test case source files in a test directory. PHPUnit can automatically discover and run the tests by recursively traversing the test directory.

For instance, let’s take a look at the test suite of the sebastianbergmann/money library. Looking at this project’s directory structure, we see that the test case classes in the `tests` directory mirror the package and class structure of the System Under Test (SUT) in the `src` directory:

src                                 tests
`-- Currency.php                    `-- CurrencyTest.php
`-- IntlFormatter.php               `-- IntlFormatterTest.php
`-- Money.php                       `-- MoneyTest.php
`-- autoload.php

With the above organization, to run the tests for this library we just need to point the PHPUnit command-line test runner to the test directory as shown in the example below

$ phpunit --bootstrap src/autoload.php tests
PHPUnit |version|.0 by Sebastian Bergmann and contributors.

.................................

Time: 636 ms, Memory: 3.50Mb

OK (33 tests, 52 assertions)

Note:

Whenever PHPUnit command-line test runner is pointed to a directory it by default searches  for `*Test.php` files.

We can also select specific tests to run, especially in situations where we don’t want all the tests to run at the same time. For example, to run only the tests that are declared in the `CurrencyTest` test case class in `tests/CurrencyTest.php` we can use the following command:

$ phpunit --bootstrap src/autoload.php tests/CurrencyTest
PHPUnit |version|.0 by Sebastian Bergmann and contributors.

........

Time: 280 ms, Memory: 2.75Mb

OK (8 tests, 8 assertions)

For more fine-grained control of which tests to run we can use the `--filter` option:

$ phpunit --bootstrap src/autoload.php --filter testObjectCanBeConstructedForValidConstructorArgument tests
PHPUnit |version|.0 by Sebastian Bergmann and contributors.

..

Time: 167 ms, Memory: 3.00Mb

OK (2 test, 2 assertions)

Note:

A drawback of this approach is that we have no control over the order in which the tests are run. This can lead to problems with regard to test dependencies.

In the next section you will see how you can make the test execution order explicit by using the XML configuration file.

#Composing a Test Suite Using XML Configuration

PHPUnit’s XML configuration file can also be used to compose a test suite. When this is used in test composition, the order at which the test is to be performed can be completely controlled.

The example below illustrates with a minimal `phpunit.xml` file that will add all `*Test` classes that are found in `*Test.php` files when the `tests` directory is recursively traversed.

Example, illustrating the composition of a test suite using XML configuration

<phpunit bootstrap="src/autoload.php">
  <testsuites>
    <testsuite name="money">
      <directory>tests</directory>
    </testsuite>
  </testsuites>
</phpunit>

If `phpunit.xml` or `phpunit.xml.dist` exist in the current working directory and `--configuration` flag is not used, the configuration will be automatically read from that file.

With XML Configuration file, the  order in which tests are executed can be made explicit as illustrated below:

<phpunit bootstrap="src/autoload.php">
  <testsuites>
    <testsuite name="money">
      <file>tests/IntlFormatterTest.php</file>
      <file>tests/MoneyTest.php</file>
      <file>tests/CurrencyTest.php</file>
    </testsuite>
  </testsuites>
</phpunit>

Previous: More on fixtures
Next: Risky tests



Follow us on Facebook and Twitter for latest update.