sebastianbergmann / phpunit

The PHP Unit Testing framework.
https://phpunit.de/
BSD 3-Clause "New" or "Revised" License
19.66k stars 2.2k forks source link

@runInSeparateProcess doesn't respect @requires #4391

Open GlennM opened 4 years ago

GlennM commented 4 years ago
Q A
PHPUnit version PHPUnit 8.5.8
PHP version PHP 7.4.5
Installation Method Composer
cakephp/cache                      3.9.0   Easy to use Caching library wi...
cakephp/collection                 3.9.0   Work easily with arrays and it...
cakephp/core                       3.9.0   CakePHP Framework Core classes
cakephp/database                   3.9.0   Flexible and powerful Database...
cakephp/datasource                 3.9.0   Provides connection managing a...
cakephp/log                        3.9.0   CakePHP logging library with s...
cakephp/utility                    3.9.0   CakePHP Utility classes such a...
deployer/deployer                  v6.8.0  Deployment Tool
deployer/phar-update               v2.2.0  Integrates Phar Update to Symf...
deployer/recipes                   6.2.2   3rd party deployer recipes
doctrine/collections               1.6.5   PHP Doctrine Collections libra...
doctrine/instantiator              1.3.1   A small, lightweight utility t...
fzaninotto/faker                   v1.9.1  Faker is a PHP library that ge...
gitonomy/gitlib                    v1.2.1  Library for accessing git
monolog/monolog                    2.1.0   Sends your logs to files, sock...
myclabs/deep-copy                  1.10.1  Create deep copies (clones) of...
phar-io/manifest                   1.0.3   Component for reading phar.io ...
phar-io/version                    2.0.1   Library for handling version i...
phpdocumentor/reflection-common    2.2.0   Common reflection classes used...
phpdocumentor/reflection-docblock  5.1.0   With this component, a library...
phpdocumentor/type-resolver        1.3.0   A PSR-5 based resolver of Clas...
phpoption/phpoption                1.7.4   Option Type for PHP
phpro/grumphp                      v0.17.2 A composer plugin that enables...
phpspec/prophecy                   v1.10.3 Highly opinionated mocking fra...
phpunit/php-code-coverage          7.0.10  Library that provides collecti...
phpunit/php-file-iterator          2.0.2   FilterIterator implementation ...
phpunit/php-text-template          1.2.1   Simple template engine.
phpunit/php-timer                  2.1.2   Utility class for timing
phpunit/php-token-stream           3.1.1   Wrapper around PHP's tokenizer...
phpunit/phpunit                    8.5.8   The PHP Unit Testing framework.
pimple/pimple                      v3.3.0  Pimple, a simple Dependency In...
psr/container                      1.0.0   Common Container Interface (PH...
psr/event-dispatcher               1.0.0   Standard interfaces for event ...
psr/log                            1.1.3   Common interface for logging l...
psr/simple-cache                   1.0.1   Common interfaces for simple c...
robmorgan/phinx                    0.11.7  Phinx makes it ridiculously ea...
sebastian/code-unit-reverse-lookup 1.0.1   Looks up which function or met...
sebastian/comparator               3.0.2   Provides the functionality to ...
sebastian/diff                     3.0.2   Diff implementation
sebastian/environment              4.2.3   Provides functionality to hand...
sebastian/exporter                 3.1.2   Provides the functionality to ...
sebastian/global-state             3.0.0   Snapshotting of global state
sebastian/object-enumerator        3.0.3   Traverses array structures and...
sebastian/object-reflector         1.1.1   Allows reflection of object at...
sebastian/recursion-context        3.0.0   Provides functionality to recu...
sebastian/resource-operations      2.0.1   Provides a list of PHP built-i...
sebastian/type                     1.1.3   Collection of value objects th...
sebastian/version                  2.0.1   Library that helps with managi...
seld/jsonlint                      1.8.0   JSON Linter
squizlabs/php_codesniffer          3.5.5   PHP_CodeSniffer tokenizes PHP,...
symfony/config                     v5.1.2  Symfony Config Component
symfony/console                    v5.1.2  Symfony Console Component
symfony/dependency-injection       v5.1.2  Symfony DependencyInjection Co...
symfony/deprecation-contracts      v2.1.3  A generic function and convent...
symfony/event-dispatcher           v5.1.2  Symfony EventDispatcher Component
symfony/event-dispatcher-contracts v2.1.3  Generic abstractions related t...
symfony/filesystem                 v5.1.2  Symfony Filesystem Component
symfony/finder                     v5.1.2  Symfony Finder Component
symfony/options-resolver           v5.1.2  Symfony OptionsResolver Component
symfony/polyfill-ctype             v1.17.1 Symfony polyfill for ctype fun...
symfony/polyfill-intl-grapheme     v1.17.1 Symfony polyfill for intl's gr...
symfony/polyfill-intl-normalizer   v1.17.1 Symfony polyfill for intl's No...
symfony/polyfill-mbstring          v1.17.1 Symfony polyfill for the Mbstr...
symfony/polyfill-php73             v1.17.1 Symfony polyfill backporting s...
symfony/polyfill-php80             v1.17.1 Symfony polyfill backporting s...
symfony/process                    v5.1.2  Symfony Process Component
symfony/service-contracts          v2.1.3  Generic abstractions related t...
symfony/string                     v5.1.2  Symfony String component
symfony/yaml                       v5.1.2  Symfony Yaml Component
theseer/tokenizer                  1.1.3   A small library for converting...
twilio/sdk                         6.8.0   A PHP wrapper for Twilio's API
vlucas/phpdotenv                   v4.1.7  Loads environment variables fr...
webmozart/assert                   1.9.0   Assertions to validate method ...

Summary

@runInSeparateProcess doesn't respect @requires

Current behavior

Test with @runInSeparateProcess gets executed while the condition for @requires is false

How to reproduce

/**
 * @runInSeparateProcess
 *
 * @requires PHP < 7.4
 */

Expected behavior

Test should not be executed when condition is false.

mvorisek commented 1 year ago

I confirm this problem is still present in the latest phpunit 9.x (9.6.8, 10.x probably too, untested).

The @requires must be evaluated before a new process is started.

kubawerlos commented 1 week ago

I confirm this problem is still present in the latest phpunit 9.x (9.6.8, 10.x probably too, untested).

@mvorisek I can't replicate it, what am I doing wrong here?

kub@:~/code/sebastianbergmann/phpunit(10.5)$ git remote -v
upstram git@github.com:sebastianbergmann/phpunit.git (fetch)
upstram git@github.com:sebastianbergmann/phpunit.git (push)

kub@:~/code/sebastianbergmann/phpunit(10.5)$ git checkout 9.6.8
// (...)
HEAD is now at 17d621b3a Prepare release

kub@:~/code/sebastianbergmann/phpunit((HEAD detached at 9.6.8))$ composer install -q

kub@:~/code/sebastianbergmann/phpunit((HEAD detached at 9.6.8))$ cat test.php
<?php
class Test extends \PHPUnit\Framework\TestCase
{
    /**
     * @runInSeparateProcess
     *
     * @requires PHP < 7.4
     */
    public function testSomething(): void
    {
        self::assertTrue(false);
    }
}
kub@:~/code/sebastianbergmann/phpunit((HEAD detached at 9.6.8))$ cat test.php
<?php
class Test extends \PHPUnit\Framework\TestCase
{
    /**
     * @runInSeparateProcess
     *
     * @requires PHP < 7.4
     */
    public function testSomething(): void
    {
        self::assertTrue(false);
    }
}

kub@:~/code/sebastianbergmann/phpunit((HEAD detached at 9.6.8))$ php phpunit test.php
PHPUnit 9.6.8 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.3.11
Configuration: /home/kuba/code/sebastianbergmann/phpunit/phpunit.xml

S                                                                   1 / 1 (100%)

Time: 00:00.037, Memory: 6.00 MB

There was 1 skipped test:

1) Test::testSomething
PHP < 7.4 is required.

/home/kuba/code/sebastianbergmann/phpunit/test.php:7
/home/kuba/code/sebastianbergmann/phpunit/test.php:7
/home/kuba/code/sebastianbergmann/phpunit/src/Framework/TestCase.php:2128
/home/kuba/code/sebastianbergmann/phpunit/src/Framework/TestCase.php:1195
/home/kuba/code/sebastianbergmann/phpunit/src/Framework/TestResult.php:728
/home/kuba/code/sebastianbergmann/phpunit/src/Framework/TestCase.php:964

OK, but incomplete, skipped, or risky tests!
Tests: 1, Assertions: 0, Skipped: 1.
mvorisek commented 1 week ago

@kubawerlos try with phpunit started using php -d disable_functions=exec, passthru, proc_open, shell_exec, system, popen

You should observe that the tests in a separate process still start the process.

kubawerlos commented 1 week ago

How exactly?

kub@:~/code/sebastianbergmann/phpunit((HEAD detached at 9.6.8))$ php -d disable_functions=exec,passthru,proc_open,shell_exec,system,popen phpuni
t test.php
Call to undefined function proc_open()

kub@:~/code/sebastianbergmann/phpunit((HEAD detached at 9.6.8))$ php -d disable_functions=exec,passthru,shell_exec,system,popen phpunit test.php

PHPUnit 9.6.8 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.3.11
Configuration: /home/kuba/code/sebastianbergmann/phpunit/phpunit.xml

S                                                                   1 / 1 (100%)

Time: 00:00.047, Memory: 6.00 MB

There was 1 skipped test:

1) Test::testSomething
PHP < 7.4 is required.

/home/kuba/code/sebastianbergmann/phpunit/test.php:7
/home/kuba/code/sebastianbergmann/phpunit/test.php:7
/home/kuba/code/sebastianbergmann/phpunit/src/Framework/TestCase.php:2128
/home/kuba/code/sebastianbergmann/phpunit/src/Framework/TestCase.php:1195
/home/kuba/code/sebastianbergmann/phpunit/src/Framework/TestResult.php:728
/home/kuba/code/sebastianbergmann/phpunit/src/Framework/TestCase.php:964

OK, but incomplete, skipped, or risky tests!
Tests: 1, Assertions: 0, Skipped: 1.
mvorisek commented 1 week ago

Based on your post it seems proc_open is used by phpunit to open a new process. And it seems you was able to replicate the issue - if all tests that requires a new process would be skipped, no proc_open would be needed.

kubawerlos commented 1 week ago

if all tests that requires a new process would be skipped, no proc_open would be needed.

not necessary, proc_open can still be used and the test is skipped, as in the php -d disable_functions=exec,passthru,shell_exec,system,popen phpunit test.php attempt.

My understanding of the report is that when @runInSeparateProcess and @requires are used together, the latter is ignored, test is executed and fails on self::assertTrue(false);, which is not happening.

mvorisek commented 1 week ago

See https://github.com/sebastianbergmann/phpunit/issues/4391#issuecomment-1547311304 on my opinion on this, I belive the @requires must be evaluated before the process is started, as in edge case, no process could be even started and if so, it is slow, as a new process start takes some milliseconds which might sum up when there are many tests to be skipped.

kubawerlos commented 1 week ago

Test should not be executed when condition is false.

This is the original report and it behaves correctly.

The @requires must be evaluated before a new process is started.

Why? Is it some good practice that I am not aware of? @sebastianbergmann do you agree on 👆🏼 and this is actually a bug?