38

I currently have a problem that I have to work around in legacy code to get our interaction with a PHP Extension to work properly (Singleton Testing Question).

As such, I do not want to execute this code when running our normal production code with the application. Therefore, I need to check in regular PHP code if the code being executed is being executed as part of a test or not.

Any suggestions on how to determine this? I thought about a defined variable tied to the presence of the test files themselves (we do not ship the tests to customers) but our developers need the Extension to work normally, while the CI server needs to run the tests.

Would a Global set in the PHPUnit.xml file be recommended? Other thoughts?

Csa77
  • 649
  • 13
  • 19
Steven Scott
  • 10,234
  • 9
  • 69
  • 117

6 Answers6

46

An alternative approach is to set a constant in the PHP section of your phpunit.xml.*:

<php>
   <const name="PHPUNIT_YOURAPPLICATION_TESTSUITE" value="true"/>
</php>

In your PHP application, you might then use the following check:

if (defined('PHPUNIT_YOURAPPLICATION_TESTSUITE') && PHPUNIT_YOURAPPLICATION_TESTSUITE)
{ 
    echo 'TestSuite running!';
}

First, we check that the constant is defined, secondly, we check the value of the constant.

Jens A. Koch
  • 39,862
  • 13
  • 113
  • 141
  • Keep in mind that PHP strangely evaluates an undefined constant as a string (if `EXAMPLE` isn't defined, it is evaluated as `'EXAMPLE'`. Meaning, you should evaluate it properly using `===`. It will still throw a notification about an undefined constant. – Martti Laine Jan 02 '14 at 13:37
  • 2
    Won't `===` also match the type up, and since it's defined as `true` (a boolean) but he is checking if it is `1` (an integer), it will fail? I understand your comment, but in this example, `==` is better. – Mathias Lykkegaard Lorenzen Jul 24 '14 at 02:17
  • 4
    Thanks to your answer I found that (in `Laravel 5`) the `APP_ENV` is set to `testing`. This made it way really easy to implement your answer. I'd really recommend this solution for Laravel. – Carsten Apr 04 '16 at 10:47
  • There is no version of PHP in which the string `"PHPUNIT_YOURAPPLICATION_TESTSUITE"` would be considered equal to 1. The only way a string would ever be considered equal to 1 is if it begins with a 1. Otherwise, it would be considered equal to 0 (or some other number), but not 1. There is no reason to use `===` here. Using `==` is perfectly "proper". (And as mentioned, `===` would not in fact work here) – DimeCadmium Jun 28 '23 at 18:18
  • Hm? PHPUNIT_YOURAPPLICATION_TESTSUITE is not a string, but a constant identifier. The second part of the comparision is the check of the value of the constant. – Jens A. Koch Jul 05 '23 at 15:23
30

Define a constant in your PHPUnit bootstrap.php file. This is executed before loading or running any tests. This shouldn't impact developers running the application normally--just the unit tests.

David Harkness
  • 35,992
  • 10
  • 112
  • 134
14

If you're using Laravel than use App::runningUnitTests()

brenjt
  • 15,997
  • 13
  • 77
  • 118
pablorsk
  • 3,861
  • 1
  • 32
  • 37
12

You could check the $argv different ways.

if(PHP_SAPI == 'cli') {

    if(strpos($_SERVER['argv'][0], 'phpunit') !== FALSE) { ... }
    // or
    if($_SERVER['argv'][0] == '/usr/bin/phpunit') { ... }

}
Marcos
  • 4,796
  • 5
  • 40
  • 64
Xeoncross
  • 55,620
  • 80
  • 262
  • 364
  • I used this in the autoloader option of phpunit, there you have no access to phpunit.xml or anything yet, so this works just great! – Steve Moretz May 29 '22 at 19:52
8

Use PHPUnit Constants

You can either define constant, but that requires your work, no typos and it's not generic. How to do it better?

PHPUnit defines 2 constants by itself:

if (! defined('PHPUNIT_COMPOSER_INSTALL') && ! defined('__PHPUNIT_PHAR__')) {
    // is not PHPUnit run
    return;
}

// is PHPUnit
Tomas Votruba
  • 23,240
  • 9
  • 79
  • 115
  • 2
    Now that there are some PHPUnit values, this is a good solution as well. My answer is older before these were fully available. Using your own also allows you to know what test suite (if you have multiple) is running as an extra bonus. – Steven Scott Mar 15 '18 at 15:47
  • 3
    In PHPUnit v3.7.28 the constant to check is 'PHPUnit_MAIN_METHOD'. – Tim Rogers Oct 10 '18 at 15:03
  • You should not use unsupported versions of PHPUnit nor PHP. It's dangerous - http://php.net/supported-versions.php – Tomas Votruba Oct 11 '18 at 04:17
0

You could look for the constant PHPUNIT_COMPOSER_INSTALL defined by the official phpunit runner by using defined('PHPUNIT_COMPOSER_INSTALL'). There are also some global variables defined by phpunit.

But they could be undefined while using alternative runner (like IDE)

Loenix
  • 1,057
  • 1
  • 10
  • 23