Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KernelTestCase no longer works with PhpUnit 6.0+ #21534

Closed
advancingu opened this issue Feb 4, 2017 · 50 comments
Closed

KernelTestCase no longer works with PhpUnit 6.0+ #21534

advancingu opened this issue Feb 4, 2017 · 50 comments

Comments

@advancingu
Copy link

advancingu commented Feb 4, 2017

Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? no
Symfony version 3.2.2

Preconditions:

  • Have a blank Symfony project version 3.2.x as installed by Symfony project generator.
  • Install PhpUnit 6.0.x with composer using composer require --dev phpunit/phpunit=~6.0.

Steps to reproduce:

  1. Run PhpUnit 6 with vendor/bin/phpunit -c .

Actual result:

PHP Fatal error:  Class 'PHPUnit_Framework_TestCase' not found in /home/user/project/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php on line 23

Expected result:

PHPUnit 6.0.3 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 107 ms, Memory: 12.00MB

OK (1 test, 2 assertions)

Notes:

  • It appears the old class name PHPUnit_Framework_TestCase which is used as a parent class of vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php was completely dropped in favor of PSR compatible namespacing in PhpUnit 6 (see this commit).
  • The new namespaced class name was introduced in PhpUnit 4.8 5.4 (see changelog).
  • Would it be possible to replace the parent class of KernelTestCase with the new namespaced class?
@robfrawley
Copy link
Contributor

robfrawley commented Feb 4, 2017

The new namespace wasn't added until phpunit 5.4, not 4.8, as you asserted (check the changelog link you referenced).

@advancingu
Copy link
Author

You're right, I got the version numbers mixed up.

@srvrguy
Copy link

srvrguy commented Feb 5, 2017

I'm not sure if this should be a new issue, but the issue also occurs with Symfony 2.8.

@advancingu
Copy link
Author

I closed the PR since it won't be possible to merge it.
As pointed out in the PR, another workaround would be to implement a polyfill with the following class:

class PHPUnit_Framework_TestCase extends \PHPUnit\Framework\TestCase
{
}

@curry684
Copy link
Contributor

curry684 commented Feb 5, 2017

The polyfill seems the way to go for now, but methinks it should go in the PHPUnit bridge, not in the general polyfill packages as it's only an issue for Symfony's own KernelTestCase and WebTestCase base classes.

Given the issues that it's causing (full crash on every single testcase) my recommendation would be to add a conflicts: "phpunit/phpunit":">=7 rule to the composer.json to at least reverse the situation the next time that it's impossible to upgrade PHPUnit at the Composer level until Symfony is compatible and the user has upgraded Symfony itself to a (verified to be) compatible version.

@curry684
Copy link
Contributor

curry684 commented Feb 5, 2017

Come to think of it, that polyfill would horribly break many projects. A regular polyfill adds missing functionality without breaking anything, but in this case many projects might consciously stay on 5.x for some time and thus would explicitly break on the suggested solution, or get stuck with an old Symfony version.

I think the only really transparent solution is changing KernelTestCase.php to something like this:

namespace Symfony\Bundle\FrameworkBundle\Test;

use Symfony\Component\DependencyInjection\ResettableContainerInterface;
use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpKernel\KernelInterface;

// Alias the PHPUnit 6.0 ancestor if available, else fall back to legacy ancestor
if (class_exists('\PHPUnit\Framework\TestCase', true)) {
  class KernelTestCaseAncestor extends \PHPUnit\Framework\TestCase {}
} else {
  class KernelTestCaseAncestor extends \PHPUnit_Framework_TestCase {}
}

/**
 * KernelTestCase is the base class for tests needing a Kernel.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class KernelTestCase extends KernelTestCaseAncestor
{
  ...
}

Just tried it out and this makes my local tests pass both on 5.7 and 6.0.

Then again, perhaps it would be easier on Symfony and other frameworks if @sebastianbergmann either added this alias to 6.0 until 6.1 comes out, and marks 6.1 as conflicting with symfony/framework-bundle:<=3.2.2, or add that conflicts rule to the next 6.0.x patch - that would perhaps be a lot cleaner.

@robfrawley
Copy link
Contributor

robfrawley commented Feb 6, 2017

@curry684 All you need to do is "polyfill" (by creating an alias) the PHPUnit_Framework_TestCase class when it doesn't exist and \PHPUnit\Framework\TestCase does. Such code shouldn't go in the KernelTestCase class file, imho. Instead, I think it's appropriate to add it to the phpunit-bridge, as the symfony-polyfill component generally handles language-level polyfilling.

Something like the following could be added to the stub section of the phpunit-bridge component's composer.json, or otherwise loaded

<?php

if (!class_exists('\PHPUnit_Framework_TestCase') && class_exists('\PHPUnit\Framework\TestCase')) {
  class_alias('\PHPUnit\Framework\TestCase', '\PHPUnit_Framework_TestCase');
}

@nicolas-grekas Is this something that is appropriate for the symfony-polyfill component? Or should it go elsewhere, such as phpunit-bridge?

@curry684
Copy link
Contributor

curry684 commented Feb 6, 2017

@robfrawley if you do it in the polyfill it is aliased for every test case in a project using the polyfill, not just those using KernelTestCase. This would inadvertently make tons of people not notice at all that they didn't apply any of the required modifications to cleanly upgrade their separate unit tests to become PHPUnit 6.0 compatible.

Global polyfilling is in this case a carpet bomb approach while we're only trying to patch KernelTestCase.

Admittedly the class_alias solution is better than my dummy class, didn't think of that option, but I still think it would need to define the KernelTestCase ancestor only. Doesn't really matter where but the file itself is the only place where it's guaranteed to be loaded in time as the framework-bundle package itself has no globally run code to my knowledge.

@robfrawley
Copy link
Contributor

Solid point. Not positive what the best route is to proceed...

@sebastianbergmann
Copy link
Contributor

Re: #21534 (comment)

I made the conscious decision to not provide aliases as they only delay the problem. It is your right, of course, to make the conscious decision to add aliases in your project.

@sebastianbergmann
Copy link
Contributor

Looking at your composer.json I see that Symfony 3 needs to run its test suite with PHP 5.5. This limits you to PHPUnit 4.8 (which is no longer supported).

I have just released PHPUnit 4.8.35 to which I have backported the forward compatibility layer for PHPUnit 6 from PHPUnit 5 so that PHPUnit\Framework\TestCase can be used instead of PHPUnit_Framework_TestCase.

@advancingu
Copy link
Author

I opened a new PR since the new namespaces now exists in PHPUnit 4.8.

@curry684
Copy link
Contributor

curry684 commented Feb 6, 2017

That PR isn't enough as you then still need the proper conflict headers in composer.json to block phpunit/phpunit:<4.8.35.

All in all I would recommend not making PRs until a clear path on this is chosen by the powers that be - it's not a trivial minor issue so at least @nicolas-grekas should have a say in this as he likely has the best insight in impact.

@stof
Copy link
Member

stof commented Feb 6, 2017

@curry684 creating a class alias with the PHPUnit class name has already been rejected, for the reason given by you above (it would also break feature detection for code checking the availability of the class btw).

As the forward compatibility layer is now available in 4.8 and 5.4+, we can switch to it IMO

@xabbuh
Copy link
Member

xabbuh commented Feb 6, 2017

Well, making sure that the PhpUnitBridge doesn't use the cache, but reinstalls PHPUnit instead will probably make the tests green.

@Jean85
Copy link
Contributor

Jean85 commented Feb 6, 2017

I was already trying to tackle this problem for the bridge here: #21221
Unfortunately, for the bridge the compat issue is more extensive...

@pculka
Copy link

pculka commented Feb 8, 2017

ok, so what is the solution to this? I'm using symfony 3.1 for a project, PHPUnit 6.0.6 and the tests won't even start, i.e. my CI fails every build, which won't let me deploy...

@xabbuh
Copy link
Member

xabbuh commented Feb 8, 2017

@pculka For the moment, you can stick with PHPUnit 5.x.

@pculka
Copy link

pculka commented Feb 8, 2017

@xabbuh that's what I did. The workaround above by @curry684 works, so long you don't use for example LIIP functional test bundle (which I do). I fixed my composer.json (had phpunit using @stable ) and now tests work.

@curry684
Copy link
Contributor

curry684 commented Feb 8, 2017

On my current project I've put the following in my PHPUnit bootstrap file after the autoloader until it's resolved on the Symfony and/or PHPUnit levels, with "phpunit/phpunit:"^5.7 || ^6.0" in the composer.json:

// Polyfill PHPUnit 6.0 both ways
if (!class_exists('\PHPUnit\Framework\TestCase', true)) {
    class_alias('\PHPUnit_Framework_TestCase', '\PHPUnit\Framework\TestCase');
} elseif (!class_exists('\PHPUnit_Framework_TestCase', true)) {
    class_alias('\PHPUnit\Framework\TestCase', '\PHPUnit_Framework_TestCase');
}

I'm only using this because I want the bundle to support only PHPUnit 6 eventually. In regular projects I'm sticking with 5.x for the time being as @xabbuh suggests.

@Toilal
Copy link

Toilal commented Feb 14, 2017

There are other polyfills required, like those ...

class PHPUnit_Util_ErrorHandler extends \PHPUnit\Util\ErrorHandler
class PHPUnit_Util_Test extends \PHPUnit\Util\Test

@curry684
Copy link
Contributor

Not for Symfony as the conflict only arises from KernelTestCase extending PHPUnit_Framework_TestCase.

@Jean85
Copy link
Contributor

Jean85 commented Feb 14, 2017

Those are needed for the PHPUnit bridge, in fact

@scaytrase
Copy link
Contributor

Ok, conflict section is an option then. But, I think we should add a conflict with >=7.0 also there, yes? To be ensured people do not use modern phpunit until we ensure symfony is compatible?

@xabbuh
Copy link
Member

xabbuh commented Feb 17, 2017

Even if PHPUnit 7 were out and our base test case classes were not compatible with PHPUnit 7 yet, users would still be able to use it if they did not make use of our base classes.

@peterrehm
Copy link
Contributor

Technically it is not sure yet and since PHPUnit is optionally tooling it should updated once the changes in 7.0 are clear. There are good chances that there might not be any issues. You will in any case immediately notice if there are issues with your testsuite.

fabpot added a commit that referenced this issue Feb 18, 2017
This PR was squashed before being merged into the 2.7 branch (closes #21564).

Discussion
----------

Update to PHPUnit namespaces

| Q             | A
| ------------- | ---
| Branch?       | 2.7+
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #21534
| License       | MIT
| Doc PR        | -

Replaces #21540

@nicolas-grekas Is the update of the cache-id like this sufficient? Do we maybe have to specifiy 4.8.35 in simple-phpunit?

Commits
-------

ddd2dff Update to PHPUnit namespaces
@fabpot fabpot closed this as completed Feb 18, 2017
@ChangePlaces
Copy link

This also occurs with Silex 2

@xabbuh
Copy link
Member

xabbuh commented Mar 11, 2017

@RafaelPlantard
Copy link

I'm facing: PHP Fatal error: Call to undefined method PHPUnit_Util_Configuration::getTestdoxGroupConfiguration() in /home/travis/build/ShopBackBR/php-apns/vendor/phpunit/phpunit/src/TextUI/TestRunner.php on line 1066 issue at PHP 5.6 at Travis CI.

@rernesto
Copy link

I tried with PHPUnit 5.7/Symfony 2.8 and PhpUnit 6.x/Symfony 3.x. I got the Class Not Found Error. I only have this error on Functional Tests extending Symfony\Bundle\FrameworkBundle\Test\WebTestCase

@xabbuh
Copy link
Member

xabbuh commented Mar 21, 2017

Can you please show the output of composer show?

@rernesto
Copy link

rernesto commented Mar 21, 2017

The composer.json for symfony2.8. PhpUnit 6.x conflicts with phpunit-brifge 2.8

"require": {
        "php": ">=5.3.9",
        "doctrine/doctrine-bundle": "~1.4",
        "doctrine/orm": "^2.4.8",
        "friendsofsymfony/rest-bundle": "~2.0",
        "friendsofsymfony/user-bundle": "~2.0",
        "incenteev/composer-parameter-handler": "~2.0",
        "javiereguiluz/easyadmin-bundle": "^1.16",
        "sensio/distribution-bundle": "~4.0",
        "sensio/framework-extra-bundle": "^3.0.2",
        "symfony/assetic-bundle": "~2.3",
        "symfony/monolog-bundle": "^3.0.2",
        "symfony/swiftmailer-bundle": "~2.3,>=2.3.10",
        "symfony/symfony": "2.8.*",
        "twig/twig": "^1.0||^2.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^5.0",
        "sensio/generator-bundle": "~3.0"
    },

Composer show

doctrine/annotations                 v1.4.0      Docblock Annotations Parser
doctrine/cache                       v1.6.1      Caching library offering an object-oriented API for many cache backends
doctrine/collections                 v1.4.0      Collections Abstraction library
doctrine/common                      v2.7.2      Common Library for Doctrine projects
doctrine/dbal                        v2.5.12     Database Abstraction Layer
doctrine/doctrine-bundle             1.6.7       Symfony DoctrineBundle
doctrine/doctrine-cache-bundle       1.3.0       Symfony Bundle for Doctrine Cache
doctrine/inflector                   v1.1.0      Common String Manipulations with regard to casing and singular/plural rules.
doctrine/instantiator                1.0.5       A small, lightweight utility to instantiate objects in PHP without invoking their constructors
doctrine/lexer                       v1.0.1      Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.
doctrine/orm                         v2.5.6      Object-Relational-Mapper for PHP
friendsofsymfony/rest-bundle         2.1.1       This Bundle provides various tools to rapidly develop RESTful API's with Symfony
friendsofsymfony/user-bundle         2.0.0-beta2 Symfony FOSUserBundle
incenteev/composer-parameter-handler v2.1.2      Composer script handling your ignored parameter file
ircmaxell/password-compat            v1.0.4      A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash
javiereguiluz/easyadmin-bundle       v1.16.5     Admin generator for Symfony applications
jdorn/sql-formatter                  v1.2.17     a PHP SQL highlighting library
kriswallsmith/assetic                v1.4.0      Asset Management for PHP
monolog/monolog                      1.22.1      Sends your logs to files, sockets, inboxes, databases and various web services
myclabs/deep-copy                    1.6.0       Create deep copies (clones) of your objects
pagerfanta/pagerfanta                v1.0.5      Pagination for PHP 5.3
paragonie/random_compat              v2.0.10     PHP 5.x polyfill for random_bytes() and random_int() from PHP 7
phpdocumentor/reflection-common      1.0         Common reflection classes used by phpdocumentor to reflect the code structure
phpdocumentor/reflection-docblock    3.1.1       With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information t...
phpdocumentor/type-resolver          0.2.1       
phpspec/prophecy                     v1.7.0      Highly opinionated mocking framework for PHP 5.3+
phpunit/php-code-coverage            4.0.7       Library that provides collection, processing, and rendering functionality for PHP code coverage information.
phpunit/php-file-iterator            1.4.2       FilterIterator implementation that filters files based on a list of suffixes.
phpunit/php-text-template            1.2.1       Simple template engine.
phpunit/php-timer                    1.0.9       Utility class for timing
phpunit/php-token-stream             1.4.11      Wrapper around PHP's tokenizer extension.
phpunit/phpunit                      5.7.17      The PHP Unit Testing framework.
phpunit/phpunit-mock-objects         3.4.3       Mock Object library for PHPUnit
psr/log                              1.0.2       Common interface for logging libraries
sebastian/code-unit-reverse-lookup   1.0.1       Looks up which function or method a line of code belongs to
sebastian/comparator                 1.2.4       Provides the functionality to compare PHP values for equality
sebastian/diff                       1.4.1       Diff implementation
sebastian/environment                2.0.0       Provides functionality to handle HHVM/PHP environments
sebastian/exporter                   2.0.0       Provides the functionality to export PHP variables for visualization
sebastian/global-state               1.1.1       Snapshotting of global state
sebastian/object-enumerator          2.0.1       Traverses array structures and object graphs to enumerate all referenced objects
sebastian/recursion-context          2.0.0       Provides functionality to recursively process PHP variables
sebastian/resource-operations        1.0.0       Provides a list of PHP built-in functions that operate on resources
sebastian/version                    2.0.1       Library that helps with managing the version number of Git-hosted PHP projects
sensio/distribution-bundle           v4.0.38     Base bundle for Symfony Distributions
sensio/framework-extra-bundle        v3.0.23     This bundle provides a way to configure your controllers with annotations
sensio/generator-bundle              v3.1.4      This bundle generates code for you
sensiolabs/security-checker          v3.0.5      A security checker for your composer.lock
swiftmailer/swiftmailer              v5.4.6      Swiftmailer, free feature-rich PHP mailer
symfony/assetic-bundle               v2.8.1      Integrates Assetic into Symfony2
symfony/monolog-bundle               v3.0.3      Symfony MonologBundle
symfony/phpunit-bridge               v2.8.18     Symfony PHPUnit Bridge
symfony/polyfill-apcu                v1.3.0      Symfony polyfill backporting apcu_* functions to lower PHP versions
symfony/polyfill-intl-icu            v1.3.0      Symfony polyfill for intl's ICU-related data and classes
symfony/polyfill-mbstring            v1.3.0      Symfony polyfill for the Mbstring extension
symfony/polyfill-php54               v1.3.0      Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions
symfony/polyfill-php55               v1.3.0      Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions
symfony/polyfill-php56               v1.3.0      Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions
symfony/polyfill-php70               v1.3.0      Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions
symfony/polyfill-util                v1.3.0      Symfony utilities for portability of PHP codes
symfony/security-acl                 v3.0.0      Symfony Security Component - ACL (Access Control List)
symfony/swiftmailer-bundle           v2.5.3      Symfony SwiftmailerBundle
symfony/symfony                      v2.8.18     The Symfony PHP framework
twig/extensions                      v1.4.1      Common additional features for Twig that do not directly belong in core
twig/twig                            v2.2.0      Twig, the flexible, fast, and secure template language for PHP
webmozart/assert                     1.2.0       Assertions to validate method input/output with nice error messages.
willdurand/jsonp-callback-validator  v1.1.0      JSONP callback validator.
willdurand/negotiation               v2.2.1      Content Negotiation tools for PHP provided as a standalone library.

@peterrehm
Copy link
Contributor

You need dev-master of the bridge.

@rernesto
Copy link

I don't know why I should require dev-master version of the bridge (I am not using it), but I did it. Isn't working, same Class not found Error. I tried with PhpUnit 5.x and 6.x on both versions of symfony (2.8 and 3.2)

@peterrehm
Copy link
Contributor

If you want PHPUnit 6.0 you need the dev-master version of the bridge as only the master version supports PHPUnit 6.0.

@xabbuh
Copy link
Member

xabbuh commented Mar 21, 2017

How do you run the tests? What is the exact error you get?

@rernesto
Copy link

rernesto commented Mar 21, 2017

I am don't care if is 5.x or 6.x version of PHPUnit, I just need a version working. I already tried everything I found about it. Including load the bootstrap.php.cache in phpunit.xml, run the test directly, etc. nothing works.
phpunit --coverage-text app src/Fluency/Bundle/SchedulerBundle/Tests/Controller/DefaultControllerTest.php

phpunit .

phpunit src/Fluency/Bundle/SchedulerBundle/Tests/Controller/DefaultControllerTest.php

The same error I got with the default controller with default AppBundle.

Class 'Symfony\Bundle\FrameworkBundle\Test\WebTestCase' not found in /var/www/scheduler/src/Fluency/Bundle/SchedulerBundle/Tests/Controller/DefaultControllerTest.php on line 7

@xabbuh
Copy link
Member

xabbuh commented Mar 21, 2017

This does not answer my question how you run your tests. Please explain how you did that before the tests started to fail and how your config was at that time. Did you then get the same error? Please note that the initial issue was about the \PHPUnit_Framework_TestCase class not being found while your last error is about Symfony's WebTestCase class.

@rernesto
Copy link

rernesto commented Mar 21, 2017

I re-start everything from scratch, now is working. I think the problem was with the PhpUnit versions. Anyway for some reason my global installations of PHPUnit is not working (The Composer and OS Native).
I am using my bin/phpunit inside the project folder.
Thanks everyone for your time.

@xabbuh I did nothing, my Unit Tests works fine all the time, using my global phpunit installations, just the functional test failed. And WebTestCase is a child class of PHPUnit_Framework_TestCase. Thank you

@RafaelPlantard
Copy link

I started to use only the composer version. I was using composer + system version, and when they were different I was facing issues. So I'm now just using composer versions.
My composer.json:

{
    "name": "jwage/php-apns",
    "type": "library",
    "description": "Object Oriented PHP Apple Push Notification Integration Library",
    "keywords": ["apple", "notifications", "apns"],
    "homepage": "http://github.com/jwage/php-apns",
    "license": "MIT",
    "authors": [
        {"name": "Jonathan H. Wage", "email": "jonwage@gmail.com"}
    ],
    "autoload": {
        "psr-0": {"JWage\\APNS": "src/"}
    },
    "require": {
        "php": ">=5.3.0",
        "ext-openssl": "*",
        "ext-zip": "*",
        "phpunit/phpunit": "*"
    }
}

My phpunit run command: vendor/bin/phpunit, I'm using this command at Travis CI:

language: php

php:
  - 5.3
  - 5.4
  - 5.5
  - 5.6
  - 7.0
  - 7.1

before_script: composer install

script: vendor/bin/phpunit

notifications:
  email: false

ghalse added a commit to tenet-ac-za/metadata-validator that referenced this issue Mar 23, 2017
@sinasalek
Copy link

There is also another workaround using composer directly. there is a plugin for class aliasing. This way there no need to change anything else
https://github.com/TYPO3/class-alias-loader

@sonicoder86
Copy link

Will be there a fix for this? I consider the aliasing as a monkey patch, not a real fix.

@xabbuh
Copy link
Member

xabbuh commented Oct 27, 2017

There shouldn't be any issue if you are using a recent version of the PhpUnitBridge or PHPUnit itself.

@sonicoder86
Copy link

Using it with PHPUnit itself results in error. I don't know if this bridge works with Silex.

@curry684
Copy link
Contributor

But this is the Symfony issue tracker, not Silex'.

@xabbuh
Copy link
Member

xabbuh commented Oct 27, 2017

@BlackSonic Which PHPUnit version and which error?

russellvt pushed a commit to russellvt/travis-ci-examples-php that referenced this issue Jun 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests