48

I have following, very simple, XML config for PHPUnit:

<phpunit bootstrap="/_tests/TestAutoload.php">
    <testsuites>
        <testsuite name="Unit Tests">
            <directory suffix=".php">_tests</directory>
        </testsuite>
    </testsuites>
</phpunit>

How to exclude certain file in this directory from test suite? I tried <exclude> and <blacklist>, but it doesn't seem to work in this context. Also couldn't find any other documentation than phpunit.de one, which doesn't mention anything about it. Else than that, this config works perfectly.

Ondrej Slinták
  • 31,386
  • 20
  • 94
  • 126

8 Answers8

59

To exclude the file name TestCase.php.

add this to your phpunit.xml

<testsuites>
    <testsuite name="BLABLA">
        <directory suffix=".php">./tests</directory>
        <exclude>./tests/TestCase.php</exclude>
    </testsuite>
</testsuites>

Here is an additional excerpt from a real-live test-suite I can confirm it working with:

...
    <testsuites>
        <testsuite name="n98-magerun-tests">
            <directory>./tests</directory>
            <exclude>tests/N98/Magento/Command/Installer/UninstallCommandTest.php</exclude>
        </testsuite>
    ...
hakre
  • 193,403
  • 52
  • 435
  • 836
Mahmoud Zalt
  • 30,478
  • 7
  • 87
  • 83
  • does this actually work for you? as per previous comment (http://stackoverflow.com/a/15632735/2314626) exclude works for directories. your proposed configuration still fails with: No tests found in class "TestCase". – glen Nov 18 '15 at 15:43
  • @ElanRuusamäe: Yes it does actually work. That *previous comment* actually is an answer from years ago that even begs to be proven wrong. – hakre Mar 19 '16 at 17:54
  • 1
    Confirmed. Maybe it didn't used to work, but it certainly does with phpunit 5.3, as well as being the simplest, clearest answer. – petercoles May 12 '16 at 15:43
  • Confirmed that it works for files and directories. I'm using PHPUnit 9.5.7 – Terry Truong Aug 13 '21 at 01:16
  • In my case it is excluded but also invisible for Autoloader. So tests extending TestCase simply have error can't load the class TestCase – Eugene Kaurov Nov 16 '21 at 12:52
47

There are a number of ways to not run a particular test - putting it into a blacklist so it's never run may not be the way - as changing it means editing the blacklist, and you'll often endup bouncing it in and out of version control.

There are several other ways that may be more appropriate:

If a test is not yet ready to run:

$this->markTestIncomplete('This test has not been implemented yet.');

If there's an outside reason it should not be run, skip it:

if (!extension_loaded('mysqli')) {
    $this->markTestSkipped('The MySQLi extension is not available.');
}

You can also put that into the setUp() function, so it will skip all the tests in a test-class.

You can make a test dependant on a previous one succeeding:

public function testEmpty()
{
    $stack = array();
    $this->assertTrue(empty($stack));
    return $stack;   // also sends this variable to any following tests - if this worked
}
/**
 * only runs if testEmpty() passed
 *
 * @depends testEmpty
 */
public function testPush(array $stack)
{
}

The @group -name- annotation is one of the best ways to specifically stop, or run one group of tests

/**
 * @group database
 * @group remoteTasks
 */
public function testSomething()
{
}

testSomething() is now in two groups, and if either is added on the command line (or in the config.xml) --exclude-group parameter. it won't be run. Likewise, you could run only tests that belong to a particular group - say named after a feature, or bug report.

Alister Bulman
  • 34,482
  • 9
  • 71
  • 110
  • I wish @group worked inside the testsuite node in addition to the phpunit node in the config. I had one test that needed to run before a static var was set for all other tests. So I put that one test in a separate test class, with the name RunFirst.php and modified my configuration to run that in a suite all by itself, but before all other suites. – b01 Nov 27 '14 at 13:16
  • 1
    The syntax for excluding groups in phpunit.xml is as follows `` `` `ExcludedTests` `` `` See https://stackoverflow.com/a/49246266/2511355 – Tim Rogers Sep 09 '20 at 08:53
6

2021 update

On top of some good single answers above here is the entire approach that allows you to apply a consistent, clean, more architecture-driven tests organization and a convinient fast testing workflow. With it you manage your tests, directories and testsuites from phpunit.xml and run tests in groups or by one as needed. So do the following:

  • Group your tests in the directories (e.g. tests/Unit, tests/Feature, tests/Integration);
  • Make testsuites grouping your directories with <testsuite> element (note you have to wrap multiple <testsuite> tags in <testsuites> tag in later versions of PHPUnit);
  • Make an all testsuite that combines all default tests you would run as a full test suite and assign it via defaultTestSuite="all" key within <phpunit> element like this:
  <phpunit .. some other keys
         defaultTestSuite="all">
    <testsuite name="all">
        <directory suffix="Test.php">./tests/Feature/</directory>
        <directory suffix="Test.php">./tests/Unit/</directory>
    </testsuite>   
  </phpunit>
  • If you need make a dedicated Tinker test suite with tests that you could use for tinkering, keeping example tests etc. you would exclude from normal testing workflow. Do not inlcude it in the all test suite.

So you will be able to:

  • use phpunit CLI command to always run the default all tests.
  • use CLI to filter on testsuite, test file or single test level for any of your test suites e.g.:
    • phpunit --testsuite SuiteOne,
    • phpunit --filter SomeTest or
    • phpunit --filter SomeTest::test_some_test_method
    • combine --testsuite with --filter arguments

Couple this workflow with the capability to run the current test or test file from within your IDE (for Sublime Text there are Mac and Linux/Windows plugins) and you will be completelly equipped to instantly chose what test to execute.

Valentine Shi
  • 6,604
  • 4
  • 46
  • 46
  • 1
    Thank you for `phpunit --filter SomeTest::test_some_test_method`! This was exactly what I was looking for. – rassoh Nov 30 '21 at 14:57
  • Can also be useful to add to this great info that `` can take a directory instead of just a file. In some cases, e.g. you're using a framework that includes tests for features you're not using (yet) it's helpful to just move all those tests to an "Excluded" directory and use `tests/Feature./tests/Feature/Excluded` – Chris Rockwell Aug 26 '23 at 14:33
  • @ChrisRockwell Hey, thanks for the comment. I am not sure [exclude](https://docs.phpunit.de/en/10.3/configuration.html#the-exclude-element) works this way. Accorind to [source](https://docs.phpunit.de/en/10.3/configuration.html#the-source-element) element docs `exclude` excludes files from code coverage report, not from testing. I do not do PHP these days so cannot confirm it practically. – Valentine Shi Aug 27 '23 at 04:20
4

The phpunit documentation is a bit minimalistic when it comes to exclusion in a testsuite. Apparently, only entire directories can be excluded but not individual files. I would be very happy to be proven wrong. The workaround seems to be using the @group feature as posted above by Alister Bulman.

It's kind of a pain needing to tag every single test in those test suites I'd like to keep.

Community
  • 1
  • 1
Bernhard Wagner
  • 1,681
  • 12
  • 15
4

Whit this PHPUnit configuration-file I have made very good experiences.

<?xml version="1.0" encoding="UTF-8"?>
<phpunit
    convertErrorsToExceptions="true"
    convertNoticesToExceptions="true"
    convertWarningsToExceptions="true"
    colors="true"
    processIsolation="true"
    stopOnFailure="true"
    syntaxCheck="false"
    backupGlobals="false"
    bootstrap="test-bootstrap.php">
    <testsuites>
        <testsuite name="php-dba-cache">
          <directory suffix="Test.php">tests</directory>
        </testsuite>
    </testsuites>
    <logging>
        <log type="coverage-html"
             target="build/coverage"
             charset="UTF-8"
             yui="true"
             highlight="true"
             lowUpperBound="35"
             highLowerBound="70"/>
   </logging>
    <filter>
        <whitelist addUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">src</directory>
            <exclude>
             <file>test-bootstrap.php</file>
            </exclude>
        </whitelist>
    </filter>
</phpunit>

https://github.com/gjerokrsteski/php-dba-cache

gjerokrsteski
  • 97
  • 1
  • 1
4

For Phpunit 6.5, exclude is under whitelist

<filter>
    <whitelist>
        <directory suffix=".php">src</directory>
        <exclude>
            <directory>src/Migrations</directory>
            <file>src/kernel.php</file>
        </exclude>
    </whitelist>
</filter>
goto
  • 7,908
  • 10
  • 48
  • 58
0

I came across this with a test class that I wanted to extended for other tests. PHPUnit would issue warnings about the test file containing no tests. Simply declaring the class inside the file abstract caused PHPunit to quiet down about that.

abstract class SetupSomeCommonThingsTestCase {
    protected function setUp(): void {
        parent:setUp();
        ...
    }
}
Derek
  • 1,466
  • 15
  • 24
-4

Hey there, Make sure that you put your exclusions in the Whitelist. Example:

<phpunit>
    <filter>
        <blacklist>
            <directory suffix=".php">/not/even/looked/at/</directory>
        </blacklist>
        <whitelist>
            <directory suffix=".php">/path/to/test/dir/</directory>
            <exclude>
                <file suffix=".php">/path/to/fileToExclude.php</file>
            </exclude>
        </whitelist>
    </filter>
</phpunit>

http://www.phpunit.de/manual/current/en/appendixes.configuration.html#appendixes.configuration.blacklist-whitelist

Enrique
  • 655
  • 1
  • 7
  • 16