Phpunit doesn't recognize my project namespaces and class names - phpunit

recently I've recognized that the project opis/closure is facing issues with deprecated serialization solution for php 8.1.1. So I created a fork of that and tried to fix the issue, while I was fixing the issue, I tried to test the output with the phpunit. but I've got some errors shown bellow. can you please check and feed me back about how to solve these issues:
Title
Description
Operating system
macintosh
PHP version:
PHP 8.1.1 (cli) (built: Dec 17 2021 23:49:52) (NTS) Copyright (c) The PHP Group Zend Engine v4.1.1, Copyright (c) Zend Technologies
PHP Unit version:
PHPUnit 9.5.10 by Sebastian Bergmann and contributors.
Project Git repo:
https://github.com/rhashnull/closure (my fork)
The error message:
PHP Fatal error: Uncaught Error: Class "Opis\Closure\SerializableClosure" not found in /<private_path>/Projects/closure/tests/ClosureTest.php:447
Stack trace:
#0 phar:///usr/local/Cellar/phpunit/9.5.10/bin/phpunit/phpunit/Util/FileLoader.php(56): include_once()
#1 phar:///usr/local/Cellar/phpunit/9.5.10/bin/phpunit/phpunit/Util/FileLoader.php(43): PHPUnit\Util\FileLoader::load('/Users/arash/Pr...')
#2 phar:///usr/local/Cellar/phpunit/9.5.10/bin/phpunit/phpunit/Framework/TestSuite.php(311): PHPUnit\Util\FileLoader::checkAndLoad('/Users/arash/Pr...')
#3 phar:///usr/local/Cellar/phpunit/9.5.10/bin/phpunit/phpunit/Framework/TestSuite.php(394): PHPUnit\Framework\TestSuite->addTestFile('/Users/arash/Pr...')
#4 phar:///usr/local/Cellar/phpunit/9.5.10/bin/phpunit/phpunit/Runner/BaseTestRunner.php(85): PHPUnit\Framework\TestSuite->addTestFiles(Array)
#5 phar:///usr/local/Cellar/phpunit/9.5.10/bin/phpunit/phpunit/TextUI/Command.php(108): PHPUnit\Runner\BaseTestRunner->getTest('/Users/arash/Pr...', Array)
phpunit.xml
<phpunit bootstrap="./vendor/autoload.php" verbose="true">
<testsuites>
<testsuite name="Main">
<file phpVersion="5.4.0" phpVersionOperator=">=">./tests/ClosureTest.php</file>
</testsuite>
<testsuite name="Serialize">
<file phpVersion="5.4.0" phpVersionOperator=">=">./tests/SerializeTest.php</file>
</testsuite>
<testsuite name="Recursive">
<file phpVersion="7.1.0" phpVersionOperator="<">./tests/RecursiveArrayTest.php</file>
</testsuite>
<testsuite name="Signed">
<file phpVersion="5.4.0" phpVersionOperator=">=">./tests/SignedClosureTest.php</file>
</testsuite>
<testsuite name="Namespace">
<file phpVersion="5.5.0" phpVersionOperator=">=">./tests/NamespaceTest.php</file>
<file phpVersion="5.5.0" phpVersionOperator=">=">./tests/NamespaceUnqualifiedTest.php</file>
<file phpVersion="5.5.0" phpVersionOperator=">=">./tests/NamespaceFullyQualifiedTest.php</file>
<file phpVersion="5.5.0" phpVersionOperator=">=">./tests/NamespacePartiallyQualifiedTest.php</file>
</testsuite>
<testsuite name="ReflectionClosure">
<file phpVersion="5.4.0" phpVersionOperator=">=">./tests/ReflectionClosureTest.php</file>
</testsuite>
<testsuite name="ReflectionClosure2">
<file phpVersion="7.0.0" phpVersionOperator=">=">./tests/ReflectionClosure2Test.php</file>
</testsuite>
<testsuite name="ReflectionClosure3">
<file phpVersion="7.1.0" phpVersionOperator=">=">./tests/ReflectionClosure3Test.php</file>
</testsuite>
<testsuite name="ReflectionClosure4">
<file phpVersion="7.2.0" phpVersionOperator=">=">./tests/ReflectionClosure4Test.php</file>
</testsuite>
<testsuite name="ReflectionClosure5">
<file phpVersion="7.4.0" phpVersionOperator=">=">./tests/ReflectionClosure5Test.php</file>
<file phpVersion="7.4.0" phpVersionOperator=">=">./tests/NamespaceGroupTest.php</file>
</testsuite>
<testsuite name="ReflectionClosure6">
<file phpVersion="8.0.0-dev" phpVersionOperator=">=">./tests/ReflectionClosure6Test.php</file>
</testsuite>
</testsuites>
</phpunit>
composer.json
{
"name": "opis/closure",
"description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.",
"keywords": ["closure", "serialization", "function", "serializable", "serialize", "anonymous functions"],
"homepage": "https://opis.io/closure",
"license": "MIT",
"authors": [
{
"name": "Marius Sarca",
"email": "marius.sarca#gmail.com"
},
{
"name": "Sorin Sarca",
"email": "sarca_sorin#hotmail.com"
}
],
"require": {
"php": "^5.4 || ^7.0 || ^8.0"
},
"require-dev": {
"jeremeamia/superclosure": "^2.0",
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
},
"autoload": {
"psr-4": {
"Opis\\Closure\\": "src/"
},
"files": ["functions.php"]
},
"autoload-dev": {
"psr-4": {
"Opis\\Closure\\Test\\": "tests/"
}
},
"extra": {
"branch-alias": {
"dev-master": "3.6.x-dev"
}
},
"config": {
"preferred-install": "dist",
"sort-packages": true
}
}
Special thanks to your attention.

Related

symfony : can't run functional tests

Version :
Symfony 3.4
phpunit 8.3
My phpunit.xml file :
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="autoload.php">
<php>
<ini name="error_reporting" value="-1" />
<env name="SYMFONY_DEPRECATIONS_HELPER" value="weak" />
<!--
<server name="KERNEL_DIR" value="/path/to/your/app/" />
-->
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>../src/*/*Bundle/Tests</directory>
<directory>../src/*/Bundle/*Bundle/Tests</directory>
<directory>../src/*Bundle/Tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>../src</directory>
<exclude>
<directory>../src/*Bundle/Resources</directory>
<directory>../src/*Bundle/Tests</directory>
<directory>../src/*/*Bundle/Resources</directory>
<directory>../src/*/*Bundle/Tests</directory>
<directory>../src/*/Bundle/*Bundle/Resources</directory>
<directory>../src/*/Bundle/*Bundle/Tests</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
my test File :
class QuittancementControllerTest extends WebTestCase
{
private $client;
/** #var EntityManager */
private $em;
private $myApiUrl;
/** #var BailRepository */
private $bailRepo;
/** #var EcritureCompteLocataireRepository */
private $ecritureRepo;
public function setUp(): void
{
$this->client = static::createClient([], [
'PHP_AUTH_USER' => 'testUser',
'PHP_AUTH_PW' => 'pa$$word',
]);
$this->myApiUrl = $this->client->getContainer()->getParameter('myApi_url');
$this->client->disableReboot();
$this->em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
$this->em->beginTransaction();
$this->ecritureRepo = $this->em->getRepository('AppBundle:EcritureCompteLocataire');
$this->bailRepo = $this->em->getRepository('AppBundle:Bail');
}
public function run(TestResult $result = null): TestResult
{
$this->setPreserveGlobalState(false);
return parent::run($result);
}
public function tearDown(): void
{
$this->em->rollback();
}
/**
* Vérifie que l'insertion d'une écriture à la date du jour met bien à jour le solde des écritures qui suivent
* #runInSeparateProcess
*/
public function testMajSoldeEcritureFuture(): void
{
/** #var Bail $bail */
$bail = $this->bailRepo->findOneBy(['numeroCompteTiers' => '9000001']);
$postData = array
(
'bail' => $bail->getId(),
'test' => 'example',
);
$this->client->request(Request::METHOD_POST, $this->myApiUrl.'/api/test', $postData);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
$solde = $this->ecritureRepo->getSolde($bail->getId(), new DateTime());
// voluntary false assertion
$this->assertEquals(111, 10);
}
}
If i run the test like this, i have this error :
{"code":500,"message":"Serialization of 'SimpleXMLElement' is not allowed"}
C:\wamp64\www\chronos2017\src\tests\AppBundle\Controller\QuittancementControllerTest.php:44
assertion with statut 200 is write and the second assertion is false but phpunit can't display properly the result
If i delete the line "#runInSeparateProcess", the client call fails :
{"code":500,"message":"Failed to start the session because headers have already been sent by \"C:\wamp64\www\mySite\src\vendor\phpunit\phpunit\src\Util\Printer.php\" at line 109."}
What's the right way to do functional tests with symfony ? Can you help me ?
I use symfony 3.4 also but phpunit 7 so maybe it's because of phpunit 8, but I didn't need to make any modifications to my phpunit.xml file. And your error seems to come from your xml file according to the error.
I guess you already used documentation but if not: https://symfony.com/doc/3.4/testing.html
My file:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="phpunit.xsd"
bootstrap="tests/bootstrap.php"
cacheResult="true"
verbose="true">
<testsuites>
<testsuite name="unit">
<directory suffix="Test.php">tests/unit</directory>
</testsuite>
<testsuite name="end-to-end">
<directory suffix=".phpt">tests/end-to-end</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
<exclude>
<file>src/Framework/Assert/Functions.php</file>
<file>src/Util/PHP/eval-stdin.php</file>
</exclude>
</whitelist>
</filter>
<php>
<const name="PHPUNIT_TESTSUITE" value="true"/>
</php>
</phpunit>

How to run PHPUnit tests in a Drupal 8 environment for custom modules

I am trying to create and run PHPUnit tests for Drupal 8. Here are the details:
My top-level directory, where composer.json is located.
Dockerfile bootstrap.php composer.lock phpunit-examples phpunit.xml.org web
Jenkinsfile checkstyle.xml config phpunit.xml scripts
LICENSE components drush phpunit.xml.dist sonar-project.properties
README.md composer.json patches phpunit.xml.dist.org vendor
./vendor/bin/phpunit --version
PHPUnit 6.5.14 by Sebastian Bergmann and contributors.
phpunit.xml.dist
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"
verbose="true"
>
<testsuites>
<testsuite name="unit">
<file>./tests/TestSuites/UnitTestSuite.php</file>
</testsuite>
<testsuite name="kernel">
<file>./tests/TestSuites/KernelTestSuite.php</file>
</testsuite>
<testsuite name="functional">
<file>./tests/TestSuites/FunctionalTestSuite.php</file>
</testsuite>
<testsuite name="functional-javascript">
<file>./tests/TestSuites/FunctionalJavascriptTestSuite.php</file>
</testsuite>
</testsuites>
</phpunit>
phpunit.xml
<phpunit
bootstrap="bootstrap.php"
colors="true"
strict="true"
verbose="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutChangesToGlobalState="true"
checkForUnintentionallyCoveredCode="false">
<testsuites>
<testsuit name="Simple Example Test Suite">
<directory>phpunit-examples/tests</directory>
</testsuit>
</testsuites>
<php>
<ini name="error_reporting" value="32767"/>
<ini name="memory_limit" value="-1"/>
<env name="SIMPLETEST_BASE_URL" value="http://drupal-8.localhost"/>
<env name="SIMPLETEST_DB" value="mysql://drupal-8:drupal-8#localhost/drupal-8"/>
<env name="BROWSERTEST_OUTPUT_DIRECTORY" value="/var/www/sites/default/simpletest"/>
<includePath>phpunit-examples/src/</includePath>
</php>
</phpunit>
custom code to be tested:
web/modules/custom/benefit/src/BenefitListBuilder.php
test located at:
web/modules/custom/benefit/tests/src/BenefitListBuilderTest.php
<?php declare(strict_types = 1);
namespace Drupal\Tests\benefit;
use Mockery;
use Mockery\MockInterface;
use PHPUnit\Framework\TestCase;
use Drupal\benefit\BenefitListBuilder;
/**
* Test basic functionality of My Module.
*
* #group benefit
*/
class BenefitListBuilderTest extends UnitTestCase
{
/** #var BenefitListBuilder */
private $benefitListBuilder;
protected function setUp()
{
$a = "var_a";
$b = "var_b";
$this->benefitListBuilder = new BenefitListBuilder($a,$b);
}
public function testMissing()
{
$this->fail('Test not yet implemented');
}
}
Now, i try to run just this test:
$./vendor/bin/phpunit web/modules/custom/benefit/tests/src/BenefitListBuilderTest.php
PHP Fatal error: Class 'Drupal\Tests\benefit\UnitTestCase' not found in /Users/syedahmed/BG-REPOS/PHPUNITTEST-BenefitsAPI/BenefitsAPI/web/modules/custom/benefit/tests/src/BenefitListBuilderTest.php on line 15
Fatal error: Class 'Drupal\Tests\benefit\UnitTestCase' not found in /Users/syedahmed/BG-REPOS/PHPUNITTEST-BenefitsAPI/BenefitsAPI/web/modules/custom/benefit/tests/src/BenefitListBuilderTest.php on line 15
i tried moving the test under web/modules/custom/benefit/tests/src/Unit/BenefitListBuilderTest.php , but got same error.
How do i get the test to recognize the Path for UnitTestCase?
Update:
I have setup the repository in PHPStorm, so now i am getting error:
Error : Class 'Drupal\Tests\BenefitListBuilder' not found
As I see it, #kamal, the problem is you're instantiating the tests as this: use PHPUnit\Framework\TestCase; but you're using Drupal, so it should be as follows: use Drupal\Tests\UnitTestCase;
I hope this helps.

Phpunit on Symfony 3.4 You have requested a non-existent service

I am working on a Symfony 3.4 installation that was upgraded from version 2.
When I try to run a unit test with this command
./bin/phpunit tests/MyBundle/ -c tests/phpunit.xml
I get the following error:
Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "XXXX\MyBundle\Services\ListServices".
/apps/xxxx/unitTest/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php:348
/apps/xxxx/unitTest/tests/MyBundle/Services/ListServicesTest.php:19
I have made the Services public
services:
_defaults:
autowire: true
autoconfigure: true
public: true
But that did not work. I also tried adding a Compiler pass, but that was it's own can of worms...
my phpunit.xml
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
backupGlobals="false"
colors="true"
convertErrorsToExceptions = "true"
convertNoticesToExceptions = "true"
convertWarningsToExceptions = "true"
processIsolation = "false"
stopOnFailure = "false"
syntaxCheck = "false"
stderr = "true"
bootstrap="bootstrap_test.php"
>
<php>
<ini name="error_reporting" value="-1" />
<server name="KERNEL_CLASS" value="AppKernel" />
<server name="KERNEL_DIR" value="../app/" />
<env name="SYMFONY_DEPRECATIONS_HELPER" value="weak"/>
<env name="APP_ENV" value="test"/>
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>../tests/*</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>../src</directory>
<exclude>
<directory>../src/*/*Bundle/Resources</directory>
<directory>../src/*/*Bundle/Tests</directory>
<directory>../src/*/*Bundle/DataFixtures</directory>
<directory>../src/*/*Bundle/Admin</directory>
<directory>../src/*/*Bundle/DependencyInjection</directory>
<directory>../src/*/*Bundle/Twig</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
this is my test file
namespace Tests\MyBundle\Services;
use XXXX\MyBundle\Services\ListServices;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class ListServicesTest extends WebTestCase
{
/**
* #test
*/
public function testGetCurrentList()
{
$kernel = new AppKernel('dev', false);
$kernel->boot();
$container = $kernel->getContainer();
$listService = $container->get(ListServices::class);
$this->assertNotNull($listService->getCurrentList());
}
}
Any ideas on how to get the unit tests to work?
thanks
You are trying to get the service by it's name (class name) and not by it's alias from the container. Service should be registered in the container:
services:
your_service_alias:
class: YourApp\Services\ListServices
arguments: (if any)
- "#some_dependency"
Then in your test you should get the service by it's alias
$container->get('your_service_alias')

Why symfony container is build in test environment when I run phpunit whereas .env defines APP_ENV as dev?

I face a problem with env variables and running tests with phpunit on symfony 4.2 framework.
According to the documentation, .env and services.yaml are loaded first but if the APP_ENV is defined and set to a value like test, the container will be configured to load .env.test and services_test.yaml.
What I want to understand is : my .env files contains a key APP_ENV set to dev, but when I run phpunit to execute some tests, the environment is automatically (?) set to test...
To see that, I've dump $this->environment in the class Kernel.php.
bootstrap.php
<?php
use Symfony\Component\Dotenv\Dotenv;
require dirname(__DIR__).'/vendor/autoload.php';
// Load cached env vars if the .env.local.php file exists
// Run "composer dump-env prod" to create it (requires symfony/flex >=1.2)
if (is_array($env = #include dirname(__DIR__).'/.env.local.php')) {
$_SERVER += $env;
$_ENV += $env;
} elseif (!class_exists(Dotenv::class)) {
throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.');
} else {
// load all the .env files
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
}
$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev';
$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV'];
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
.env
###> symfony/framework-bundle ###
APP_ENV=dev
...
Kernel.php
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
{
$container->addResource(new FileResource($this->getProjectDir().'/config/bundles.php'));
// Feel free to remove the "container.autowiring.strict_mode" parameter
// if you are using symfony/dependency-injection 4.0+ as it's the default behavior
$container->setParameter('container.autowiring.strict_mode', true);
$container->setParameter('container.dumper.inline_class_loader', true);
$confDir = $this->getProjectDir().'/config';
$loader->load($confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{packages}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{services}'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob');
dump($this->environment); //print "test"
}
phpunit.xml.dist
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="config/bootstrap.php"
>
<php>
<ini name="error_reporting" value="-1" />
<server name="KERNEL_CLASS" value="AppBundle\Kernel" />
<!-- ###+ symfony/framework-bundle ### -->
<env name="APP_ENV" value="dev" force="true"/> <!-- doesn't work with or without force="true" -->
<!-- env name="TRUSTED_PROXIES" value="127.0.0.1,127.0.0.2" -->
<!-- env name="TRUSTED_HOSTS" value="'^localhost|example\.com$'" -->
<!-- ###- symfony/framework-bundle ### -->
<!-- ###+ doctrine/doctrine-bundle ### -->
<!-- Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url -->
<!-- For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db" -->
<!-- Configure your db driver and server_version in config/packages/doctrine.yaml -->
<env name="DATABASE_URL" value="sqlite:///%kernel.project_dir%/app/test.db"/>
<!-- ###- doctrine/doctrine-bundle ### -->
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>src</directory>
<exclude>
<directory>src/*Bundle/Resources</directory>
<directory>src/*/*Bundle/Resources</directory>
<directory>src/*/Bundle/*Bundle/Resources</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
Could you give me a clue about what happens, why my container is configure in test environment instead of the value of the APP_ENV?

Phabricator phpunit configuration - coverage

I am trying to set up a coverage report within the DIFF view for phabricator. I have the following configs:
.arcconfig
{
"project_id" : "SuperProject",
"conduit_uri" : "https://phabricator.dev/",
"unit.engine": "PhpunitTestEngine",
"unit.phpunit.binary": "./vendor/bin/phpunit",
"phpunit_config": "tests/phpunit.xml"
}
tests/phpunit.xml
<phpunit>
<testsuite name="unit">
<directory suffix="Test.php">unit/accountancy</directory>
....
<directory suffix="Test.php">unit/store</directory>
</testsuite>
<logging>
<log type="coverage-clover" target="../build/logs/clover.xml" />
</logging>
</phpunit>
But when I run arc unit --coverage --json, I get something like the following:
{
"0": {
"namespace": null,
"name": "Restriction\\CalculatorTest::testGetDiscount with data set #0",
"link": null,
"result": "pass",
"duration": 0.00362205505371,
"extra": null,
"userData": "",
"coverage": [] <-- why is it empty?
},
...
}
Seems like arcanist is not picking up coverage info. I've tried even looking through the phabricator source code, but couldn't find a clue on how to enable that.
Any suggestions are very welcome!
add whitelist to your tests/phpunit.xml. Check https://phpunit.de/manual/current/en/code-coverage-analysis.html#code-coverage-analysis.whitelisting-files

Resources