I upgraded Codeception to v4 (according to THIS) and then Symfony to v5 (according to THIS). Now, when I try to run tests I get an error about missing test file:
root#blabla: vendor/bin/codecept run
In GroupManager.php line 129:
GroupManager: File or directory /var/www/html/tests/unit/SomeFileCest.php does not exist
This file does NOT exist in current branch. It exists in another branch of the project, but current should not know anything about this file!
This problem happens no matter which branch I switch to. So somehow Codeception remembers, that one branch has additional test and demands that test in other branches. Looks like some sort of cache.
If I switch to the branch WITH the missing file, everything looks OK (I do get an error, but because of the old framework expected).
Error appears if I do vendor/bin/codecept run or vendor/bin/codecept run tests/functional for example (note that the missing test is a unit test).
I tried deleting /var and /vendor and running composer install/update. I also tried removing the branch completely and pulling from remote, but no joy.
Anybody has any idea why this would happen and how to fix this?
EDIT:
After some simple testing it looks like it's related to old references in tests/_support/failed (as #Naktibalda mentioned in his/her comment).
I still don't fully understand what happened, but this can be fixed by running:
vendor/bin/codecept clean
From Codeception help:
clean Recursively cleans log and generated code
I will try to investigate further to understand why this happens, but for now this is what I have.
I hope this helps someone avoid the frustrations I went through ;)
For my case we were using paracept, to run stuff in parallel. This generated group files in /tests/_data
Once I removed the group files in this folder my test suite ran normally.
Worth noting that codecept clean doesn't clear this _data folder.
Related
I'm quite new to PHP and have received some Symfony2 project to maintain. Now I've found out that when I update foo.html.twig, that page will not change until I perform the command console c:c -e prod. Until then the shown page will be foo.html_.twig (hence the underscore).
The problem is that I've changed a controller, let's say BarController.php, but the new added value in that controller does not work in the .twig file, I think because the BarController_.php did not get updated with the clear cache command. What did I do wrong here?
Edit:
As Nate says it's not Symfony that caches controllers, but at least I see that BarController_.php is much older than BarController.php, and it's the one with the underscore that does not have the newly added value.
Edit 2:
BarController.php and BarController_.php both reside in the same folder.
Sometimes you need to clear cache by your own. You can try
rm -rf app/cache/prod/*
and don't forget to change rights.
Apparently I was completely looking at the wrong places. It had nothing to do with caching at all.
Those underscored files appeared because of my hacky way of 'version control', which meant I copied a file I was going to edit, put '.old' after the filename so I had a backup. For some reason there was created an underscored file for these things.
The problem of not being able to read the getter's value was just a bug in my code.
First of all I have just begun to tinker with Laravel 5 and php artisan, so don't judge to harsh please ;)
To get rid of ./public/index.php in the website path I did the following:
moved all the files in root/page_local/ folder;
moved files from public folder to root/page/;
modified the root/page_local/index.php file accordingly.
So the laravel works as it should now, but php-artisan is not. Every command that I try to run returns the same error:
[BadMethodCallException]
Method patter does not exist.
But I remember creating a Controller before and it worked, I tried multiple functions (--version, list, create::controller).
Even when I run composer update it errors when it tries to run php artisan clear-compiled.
I still managed to update the composer by running composer update --no-scripts
Please help me out on this one because I couldn't find any information regarding this issue on Laravel website and google. If you will need me to provide any of my code, let me know what you need and I will do so.
Thanks in advance.
Search your code for patter string, my guess is that you have a typo somewhere and the method is called pattern so use that instead. There is no patter method anywhere in Laravel code.
I am getting an error message in my Laravel 5 application:
PHP Fatal error: Cannot redeclare class Illuminate\\Contracts\\Support\\Arrayable in /var/www/.../bootstrap/cache/compiled.php on line 156
This error only occurs on my staging environment and not on my local website. I would love to post more info but I do not have it. Because I do not know where this error is caused.
If I remove the file (cache/compiled.php) everything seems to work fine. But after every deploy the same error occurs. On my localhost everything works fine as well.
My question: does anybody have a clue where to look because I am out of ideas.
Try this way.
At first remove the cache/compiled.php file
then run this command
php artisan clear-compiled
I had the same problem and found the following article, which was very helpful:
https://sentinelstand.com/article/laravel-5-optimization-commands
The only solution that was working for me was manually deleting bootstrap/cache/compiled.php. Switching around the order in which the autoloaders are called in bootstrap/autoload.php did not work for me because I had the same problem the other way round, ie. I had a class in compiled.php that was causing something from autoload.php to be autoloaded before autoload.php ran.
In my case, I am using a combination of PSR4 and manual class mappings in my composer.json file. I'm sure this is part of the problem. (Don't judge me: this app started in Laravel 3, so it's taking time to add namespacing throughout the code base :-).
One reason why things may work differently in different environments is because the artisan optimize command will only generate the bootstrap/cache/compiled.php file if you provide the --force option or if debugging mode is not enabled. So it is likely that you are not getting this file in development because debugging is enabled but are getting this file in staging and/or production because debugging is not enabled.
Ultimately, here's what I have landed on as a solution for production deployments:
artisan config:cache
artisan optimize
rm bootstrap/cache/compiled
Update symlink to point to new version.
This way you still get bootstrap/cache/services.json, which is helpful, whereas artisan clear-compiled removes that file. Also, there will be a very brief period of time where bootstrap/cache/compiled.php will exist, which is why it is important to run these commands before you update the symlink to point your web server at the new version.
It is also worth noting that the compiled.php file that is created by artisan optimize in Laravel 5.1 is no longer generated in Laravel 5.4 because, as Taylor has stated, PHP 7 is much more performant and so the benefit of bundling all the application classes into one file, which is meant to save on disk I/O, is negligble now. Taylor recommends enabling and properly configuring your OPcache instead - you will get far more performance benefits from that.
I experienced the same but eventually found the solution.
I have my own helpers.php files in laravel. Just like the framework ones, I added them as autoloads in my composer.json. A couple of those functions are macros for the Collection (\Illuminate\Support\Collection::macro(...)).
When that helpers.php file is autoloaded, the definition of those macros cause the autoloading of Illuminate\Support\Collection. This in turn uses Illuminate\Contracts\Support\Arrayable.
So basically all of these are already loaded by the time they are defined again in cache/compiled.php. Boom.
Long story short: For me the fix was simply to switch inclusion of the compiled file and the autoloader around.
bootstrap/autoload.php:
$compiledPath = __DIR__.'/cache/compiled.php';
if (file_exists($compiledPath)) {
require $compiledPath;
}
require __DIR__.'/../vendor/autoload.php';
This might not be a viable solution add include code in your compiled file runs right away and refers to helper functions, but I think the chances on that happening should be pretty minimal.
The problem is with the artisan optimize command. If you remove the compiled.php file and then do not run optimize, it should work.
I have set up PhpStorm 5 with PHPUnit, and I'm curious if PhpStorm might have some functionality that will automatically run a unit test when saving a file. Like watchr and guard. I have tried search our beloved www and the PhpStorm docs, but haven't been able to find a solution for it.
As of version 6, PHPStorm has "File Watchers"
Open your project preferences.
Select File Watchers from the left hand list of options.
Click the + symbol at the bottom of the empty right hand panel.
Select <custom>
You will have to set up a command line for PHPUnit, it wont be the integrated testing, but you can have errors output to the console (which is good a good start!)
Various macro options are available to you, so you can include (for example) $FileNameWithoutExtension$Test.php in the arguments passed to your command line.
I personally had to set up two watchers. The first detected modifications to project files, and the second detected changes to test files (the second did not append Test.php to the filename) I also created a new project scope to exclude the tests directories from the first watcher.
You may also want to turn off immediate synchronisation, as this causes PHPUnit to run when PHPStorm auto-saves files.
My other settings are like:
File Type: PHP files (PHP)
Scope: Project excluding tests
Program: /path/to/php
Arguments: /path/to/phpunit --configuration /path/to/phpunit.xml.dist /path/to/tests/$FileNameWithoutExtension$Test.php
Working directory: $FileDir$
Output paths: $FileDir$
No output filters set, syntax error checks enabled, and console showing errors.
PHPUnit watcher named as hot phpunit runner
https://github.com/slavahatnuke/hot-phpunit-runner
You can also have a look at TDDRunner
It is console tool that execute PHPUnit autmaticly on file changes. You can also configure PHPUnit by excuting only one file ot whatever.
/usr/bin/tddrunner --group=test
There's a a German article providing further detail.
In 2017 Jetbrains release a feature that allow auto-run for tests.
It's located in the Run console, therefore it's linked to the run settings, easing the setup of this autorun.
See https://blog.jetbrains.com/phpstorm/2017/07/autorun-phpunit-tests-in-phpstorm-2017-2/
Situation
We're using PHPUnit in our project and are using a phpunit.xml to ensure things like backupGlobals is turned off.
To further ensure the include path is set and autoloading is active, we also cascade our test bootstraps. That is to say, every test and alltests-suite has a require_once(__DIR__ . '/../bootstrap.php'); at the top, all the way up to the base folder level, where it obviously reads require_once(__DIR__ . '/bootstrap.php');, and the actual bootstrap file resides.
Essentially, our tests are autonomous. You can call any AllTests.php in any folder and any *Test.php by itself and they'll run with the right configuration.
Except no. 'Wait a moment.'
That's only true if we either force our developers to use phpunit --configuration=path/to/phpunit.xml or they're in the folder with the phpunit.xml (so that PHPUnit pulls it out of the current working directory when it is executed).
Occasionally, this makes it incredibly hard to determine why tests on one developer's machine are breaking and why they're running on another. It just takes forgetting that the bootstrap is not the only thing we need to have the same test environment. Keep in mind that since you couldn't forget the bootstrap if you tried, because it's in the tests themselves, forgetting other settings, especially usually-optional ones like that (if you're in the folder with the phpunit.xml, it's automatically pulled), is easy.
In fact - it's happened a few times.
Question
Is there a way I can supply which phpunit.xml to use in the test file being run, such as in our conveniently ubiquitous bootstrap file, rather than supplying it to PHPUnit beforehand, be that by command-line switch or by being in its directory ?
A cursory glance at the code suggests the answer is no - configuration well and truly seems to be loaded before test files are even pulled:
[PHPUnit/TextUI/Command.php]
...
if (isset($this->arguments['configuration'])) {
$configuration = PHPUnit_Util_Configuration::getInstance(
$this->arguments['configuration']
);
$phpunit = $configuration->getPHPUnitConfiguration();
...
That does make some sense, given that the configuration can contain test white- or blacklists.
Really, it wouldn't make sense to load test filters in the test bootstrap itself, so that's half the potential configuration out the window with, but the actual behavioural flags of PHPUnit...
[sample of part of our phpunit.xml]
<phpunit
backupGlobals="false"
backupStaticAttributes="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
syntaxCheck="false"
processIsolation="false"
colors="true">
...perhaps with the exception of 'colors' strikes me as something that the test itself should be able to decide on some level.
Consolation prize for...
Admittedly, right now I'd be happy just knowing if I can teach PHPUnit backupGlobals="false" from the bootstrap file, if someone knows of a way.
(If fruitless, the practical answer I'll pursue will probably be to copy the phpunit.xml into all subfolders. I'd like to avoid that solution since it creates redundant copies, and if we ever choose to change a setting... yeah, ouch!)
Direct answer: No, you cant do that.
Longer story - this kind of problem is better solved by changing the habits of developers.
Here is we do it:
All developers always run the tests from the tests root directory, which has the sole phpunit.xml with all the necessary configuration - including bootstrap, which sets up an class autoloader.
We dont have testsuites as such, tests are grouped using directories, no AllTests.php anywhere, because its not necessary. PHPUnit can take a name of directory and run all tests inside it.
Its still possible to run any single test by giving a path to it or whole testsuite (by giving path to the directory). It just has to be done from the tests root directory all the time or it wont work.
Doing it like this means giving up the freedom of starting PHPUnit from any directory, but to be honest - I dont feel like thats a loss at all.
The gains are much bigger: the amount of housekeeping code is reduced, developers cannot forget anything and results are therefore consistent.
My solution is to add a bash function
function phpu ()
{
phpunit --colors --bootstrap ~/path/to/bootstrap.php "$#";
}
Then add this to all dev .bashrc files and they can switch to using that.
We like to call them from vim so I had to add this to .vimrc: set shellcmdflag=-ic
Then you add nmap ;t :! phpu % to run the test file you're currently in.
You could update the start script (Windows bat file, or shell on *nix) and have logic in there to configure to the location of the phpunit.xml. If it is in the current directory, use it, otherwise point to the main one.
I also agree with Anti though, that all the tests should always be run, as you want to ensure that the changes, even in a directory branch, do not affect other code. Therefore, always run from the top of the tree. This also requires that the test execute quickly, but I have not really had a problem with PHPUnit on that.
Maintaining the PHPUnit.xml in each directory would be a maintenance nightmare, unless is was symbolically linked from other paths to ensure there was only one actual file.