I am trying to use aspect mock with codeception tests.
From their documentation it is not clear how to configure.
https://github.com/Codeception/AspectMock
Include AspectMock\Kernel into tests/_bootstrap.php.
I do not have such file. Should I create it? Where should I include it?
My directory structure of codeception is:
test/codeception/acceptance.
I have file SummaryCest.php in test/codeception/acceptance.
Since I do not have _bootstrap.php file, I decided to try in SummaryCest - before declaring a class:
include __DIR__.'/../../../vendor/autoload.php'; // composer autoload
$kernel = \AspectMock\Kernel::getInstance();
$kernel->init([
'debug' => true,
'includePaths' => [__DIR__.'/../../../'],
'excludePaths' => [__DIR__.'../../../vendor'],
'cacheDir' => '/tmp/datamanager',
]);
I do not know do I really need to exclude vendor directory, but I saw such suggestions. If that is mandatory, it should be written probably in readme which I did not see.
In includePaths there should be visible all my project files.
I have function in SummaryCest.php
public function correctSummaryCounts(AcceptanceTester $I)
{
\AspectMock\Test::double(SummaryController::class, ['get' => null]);
}
and when I run test
php codecept.phar run test/codeception/acceptance/SummaryCest.php
I get message
==== Redirecting to Composer-installed version in vendor/codeception ====
Codeception PHP Testing Framework v2.3.5
Powered by PHPUnit 6.2.4 by Sebastian Bergmann and contributors.
PHP Fatal error: Uncaught Error: Class 'Go\ParserReflection\ReflectionFile' not found in /var/www/warehouseDataManager/vendor/codeception/aspect-mock/src/AspectMock/Intercept/BeforeMockTransformer.php:16
Stack trace:
#0 /var/www/warehouseDataManager/vendor/goaop/framework/src/Instrument/Transformer/CachingTransformer.php(124): AspectMock\Intercept\BeforeMockTransformer->transform(Object(Go\Instrument\Transformer\StreamMetaData))
#1 /var/www/warehouseDataManager/vendor/goaop/framework/src/Instrument/Transformer/CachingTransformer.php(83): Go\Instrument\Transformer\CachingTransformer->processTransformers(Object(Go\Instrument\Transformer\StreamMetaData))
#2 /var/www/warehouseDataManager/vendor/goaop/framework/src/Instrument/ClassLoading/SourceTransformingLoader.php(134): Go\Instrument\Transformer\CachingTransformer->transform(Object(Go\Instrument\Transformer\StreamMetaData))
#3 /var/www/warehouseDataManager/vendor/goaop/framework/src/Instrument/ClassLoading/SourceTransformingLoader.php(101): Go\Instrument\ClassLoading\SourceTran in /var/www/warehouseDataManager/vendor/codeception/aspect-mock/src/AspectMock/Intercept/BeforeMockTransformer.php on line 16
Can you explain me how to configure this?
Also I saw in readme
$userModel = test::double('UserModel', ['tableName' => 'my_users']);
but test is not even found. So I tried to use \AspectMock\Test which is at least found.
Notice that the error is throw before even running my test function. When I tried running before class declaration
$kernel->init();
it already gives same error.
_bootstrap.php files are no longer created automatically by Codeception.
To enabled them you have to add
settings:
bootstrap: _bootstrap.php
to codeception.yml file
and manually create _bootstrap.php files in tests directory and in every suite.
http://codeception.com/docs/reference/Configuration
ReflectionFile issue looks like autoloading issue.
Related
I am attempting to set up Opcache Preloading on Symfony 5.4 running on PHP8 at Platform.sh, and running into a fatal error.
Configuration
Necessary pieces included:
// platform.app.yaml
...
variables
php
'opcache.preload': 'var/cache/prod/App_KernelProdContainer.php'
...
hooks:
build: |
...
composer dump-autoload --no-dev --classmap-authoritative
deploy: |
...
sv restart app
...
I can verify that the App_KernelProdContainer.php file is being created at the correct location defined in the config above:
<?php
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
if (\class_exists(\ContainerF9HiXre\App_KernelProdContainer::class, false)) {
// no-op
} elseif (!include __DIR__.'/ContainerF9HiXre/App_KernelProdContainer.php') {
touch(__DIR__.'/ContainerF9HiXre.legacy');
return;
}
if (!\class_exists(App_KernelProdContainer::class, false)) {
\class_alias(\ContainerF9HiXre\App_KernelProdContainer::class, App_KernelProdContainer::class, false);
}
return new \ContainerF9HiXre\App_KernelProdContainer([
'container.build_hash' => 'F9HiXre',
'container.build_id' => '98091d49',
'container.build_time' => 1644501054,
], __DIR__.\DIRECTORY_SEPARATOR.'ContainerF9HiXre');
The included file ContainerF9HiXre/App_KernelProdContainer.php throws errors on the use statements like this:
Fatal error: Uncaught Error: Class "Symfony\Component\DependencyInjection\Container" not found in /app/var/cache/prod/ContainerF9HiXre/App_KernelProdContainer.php:17
Stack trace:
#0 /app/var/cache/prod/App_KernelProdContainer.php(7): include()
#1 {main}
thrown in /app/var/cache/prod/ContainerF9HiXre/App_KernelProdContainer.php on line 17
Use statements in the included file appear as such:
namespace ContainerF9HiXre;
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
You seem to be using the wrong file for preloading.
The generated file is named something like srcApp_KernelProdContainer.preload.php. But in any case, you probably should't be adding this file directly to opcache.preload, but the Symfony generated config/preload.php.
Since on platform.sh the path is resolved relative to the project root, you can use a relative path like this:
opcache.preload=config/preload.php
If you do not have this file (e.g. incomplete recipes), you could simply re-generate it by running composer recipes:update symfony/framework-bundle, as explained here.
Or, ir you are not using Symfony Flex and want to do it manually, you can simply copy the file from the appropriate recipe, like this one.
It's a very simple script in any case:
<?php
if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
}
I am starting to learn TDD by experimenting in Laravel's HTTP test. Here's my test function:
public function testLoginUsingUserDeni() {
$response = $this->json('POST', '/api/v1/login', [
'email' => 'ramadhanrperdana#gmail.com',
'password' => 'secret'
]);
$response
->assertStatus(200)
->assertJSONStructure($this->loginSuccessJsonStructure);
return $response->original['token'];
}
/**
* #depends testLoginUsingUserDeni
*/
public function testGambarBaru($token) {
Storage::fake('gambar');
$response = $this->json('POST', '/api/gambar/baru', [
'token' => $token,
'gambar' => UploadedFile::fake()->image('evidence.jpg'),
'posisi' => 1
]);
Storage::disk('gambar')->assertExists('evidence.jpg');
$response
->assertStatus(200)
->assertJSONStructure($this->gambarJsonStructure);
}
But, after running the test I got error like this:
PHPUnit 5.7.11 by Sebastian Bergmann and contributors.
Runtime: PHP 7.0.13-0ubuntu0.16.04.1
Configuration: /home/kromatin/Projects/PJB REMBANG/web-apps/KawistaK3_web/phpunit.xml
..E....................................... 42 / 42 (100%)
Time: 2.94 seconds, Memory: 20.00MB
There was 1 error:
1) Tests\Feature\Api\GambarTest::testGambarBaru
BadMethodCallException: Call to undefined method League\Flysystem\Filesystem::fake
/home/kromatin/Projects/PJB REMBANG/web-apps/KawistaK3_web/vendor/league/flysystem/src/Plugin/PluggableTrait.php:86
/home/kromatin/Projects/PJB REMBANG/web-apps/KawistaK3_web/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php:475
/home/kromatin/Projects/PJB REMBANG/web-apps/KawistaK3_web/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemManager.php:328
/home/kromatin/Projects/PJB REMBANG/web-apps/KawistaK3_web/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:221
/home/kromatin/Projects/PJB REMBANG/web-apps/KawistaK3_web/tests/Feature/Api/GambarTest.php:65
ERRORS!
Tests: 42, Assertions: 313, Errors: 1.
Script phpunit --color=always --verbose handling the test event returned with error code 2
I got error when executing testGambarBaru function, while other functions worked well. That error pointed to the line where I place Storage::fake('gambar');.
The purpose of my test function is to ensure my file upload API works well. I followed Laravel's documentation about testing file upload from this doc: https://laravel.com/docs/5.4/http-tests#testing-file-uploads. But the result said there is no method called fake in Storage Facade. I've done some search inside vendor directory to find any fake method around Storage facades but I can't find it. I am using Laravel 5.4. Is there something I've missed?
[SOLVED]
I checked laravel's Github repository and realized that fake method for Storage Facade added several days ago. After doing composer update my problem solved.
Lesson learned today was to not neglecting such a powerfull tool like composer and make sure to update our project dependencies to ensure that we can execute latest feature as well.
I have a number of tests written for a Laravel 5.1 application, and I'm currently using PHPUnit to run the tests. I'm attempting to investigate codeception as we have other applications that aren't built on Laravel, so codeception looks like the easiest way to get a similar interface for testing.
We have a reasonably large team, so I would prefer to use a single consistent command for testing across all projects instead of some using codecept and some using phpunit.
Here's what I've tried as my codeception.yml:
actor: Tester
paths:
tests: tests
log: storage/codeception/_output
data: storage/codeception/_data
support: storage/codeception/_support
envs: storage/codeception/_envs
modules:
enabled:
- Laravel5:
environment_file: .env
But I get this response:
$ codecept run
Codeception PHP Testing Framework v2.1.4
Powered by PHPUnit 4.8.18 by Sebastian Bergmann and contributors.
[RuntimeException]
Suite '' could not be found
So my question is this:
How do I convince codeception to run my existing PHPUnit tests with as little modification as possible?
After a lot of time, I found out that it's possible, but you have to make some modifications to how your tests are laid out. The bonus, though, is that it doesn't stop you from just running PHPUnit itself.
For posterity, here's how to do it:
Move your unit tests and TestCase.php into a folder named unit under the tests folder.
It should look like this:
tests/
tests/unit/
tests/unit/MyUnitTest.php
tests/unit/TestCase.php
Add the unit.suite.yml file in the tests/ folder.
The contents should look something like this:
modules:
enabled:
- Laravel5:
environment_file: .env.testing
Update your composer.json to with the correct folder for the testing classmap
In your autoload-dev section:
"classmap": [
"tests/unit/TestCase.php"
]
Update your TestCase.php to load bootstrap.php from the correct folder.
This should be in the createApplication() method at the top of TestCase.php
public function createApplication()
{
// $app = require __DIR__ . '/../bootstrap/app.php';
$app = require __DIR__ . '/../../bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
return $app;
}
Finally, run composer dump-autoload, and codeception should run. As a bonus, phpunit should also still run.
I'm trying to get into using codeception for my acceptance testing.
I have the following for one of my tests:
<?php
use Codeception\Util\Stub;
class SomeTest extends \Codeception\TestCase\Test
{
protected $webGuy;
/**
* #test
*/
public function incorrect_login_should_redirect_back()
{
$I = $this->webGuy;
$I->wantTo('fail at logging in');
$I->amOnPage('/'); // <-- This is the line that is failing
$I->fillField('email','info#tntstudio.hr');
$I->fillField('password','pass');
$I->click('Login');
$I->see('email', 'input');
$I->seeCurrentUrlEquals('/login');
}
}
Initially the tests ran OK, however after adding Laravel4 to the acceptance.suite.yml file and running build, the test now fails with the following:
1) SomeTest::incorrect_login_should_redirect_back
Symfony\Component\HttpKernel\Exception\NotFoundHttpException:
#1 /Applications/MAMP/htdocs/hired/vendor/laravel/framework/src/Illuminate/Routing/Router.php:1021
#2 /Applications/MAMP/htdocs/hired/vendor/laravel/framework/src/Illuminate/Routing/Router.php:989
#3 /Applications/MAMP/htdocs/hired/vendor/laravel/framework/src/Illuminate/Routing/Router.php:968
#4 /Applications/MAMP/htdocs/hired/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:738
#5 /Applications/MAMP/htdocs/hired/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:708
#6 /Applications/MAMP/htdocs/hired/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php:81
#7 /Applications/MAMP/htdocs/hired/vendor/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php:325
#8 /Applications/MAMP/htdocs/hired/app/tests/acceptance/WebGuy.php:476
#9 /Applications/MAMP/htdocs/hired/app/tests/acceptance/SomeTest.php:16
I'm running my app in a virtual environment using vagrant, at http://localhost:3030/
I have set this to the url for the PhpBrowser config in acceptance.suite.yml as below:
class_name: WebGuy
modules:
enabled:
- PhpBrowser
- WebHelper
- Laravel4
config:
PhpBrowser:
url: 'http://localhost:3030/'
I'm wondering if anybody else has come across this, or has any ideas on how to get around this, I've been tearing my hair out for hours on this.
Laravel4 module will cause Codeception to use the "testing" environment in Laravel.
Laravel will disable all route filters in "testing" environment - so your filters are not working correctly and its probably calling the wrong route, causing your app to die and your test to fail.
I dont think using the Laravel4 module with "acceptance" tests is correct - it should only be for functional tests? Edit: I just found that the Codeception Laravel4 module docs actually say "This module allows you to run functional tests for Laravel 4" - so I guess it was not actually designed for Acceptance tests?
But with all the changes in Codeception 2.x - you are better off using PhpBrowser module for your acceptance tests, and Laravel4 module for your functional tests.
If you are using Homestead, I do this in my start.php file to detect if Codeception is running, and specifically put it into a 'codeception' environment, otherwise I let it run my environment detection normally
if ((gethostname() === 'homestead') && (isset($_SERVER['REMOTE_ADDR'])) && ($_SERVER['REMOTE_ADDR'] === '127.0.0.1'))
{
$env = $app->detectEnvironment(['codeception' => ['homestead']]);
}
else
{
$env = $app->detectEnvironment(['dev' => ['homestead']]);
}
Then in my 'codeception' environment, I setup a SQLite file database, and run acceptance tests against that (which is faster than mySQL testing).
You don't even have to change your start.php. You can set the environment for codecption in the laravel4 Module config. So in your acceptance.suite.yml it will look like this:
modules:
enabled: [PhpBrowser, WebHelper, Laravel4]
config:
Laravel4:
environment : 'codeception'
filters : true
Now, when you execute php codecept run acceptance in your terminal, the Laravel4 Module will use the configuration files from app/config/codeception.
Was not able to find a solution to this, so for now am going to just go without the Laravel4 module, sadly.
I get phpunit and install it as this link using the simplest way for test purposes. I just download the phpunit.phar file, chmod & rename & move to /usr/local/bin
Then, I run phpunit --version, its ok.
I write a simple php test case.
class SimpleTest extends PHPUnit_Framework_TestCase {
public function testSomething(){
$this -> assertTrue(true);
}
}
In terminal , I go to my php class folder, and execute
phpunit --colors SimpleTest
Now I got the exceptions
PHP ReflectionException: Method suite does not exist
in phar:///usr/local/bin/phpunit/phpunit/Runner/BaseTestRunner.php on line 113
PHP Stack trace:
PHP 1. {main}() /usr/local/bin/phpunit:0
PHP 2. PHPUnit_TextUI_Command::main($exit = *uninitialized*)
/usr/local/bin/phpunit:612
PHP 3. PHPUnit_TextUI_Command->run($argv = array (
0 => '/usr/local/bin/phpunit',
1 => '--colors',
2 => 'SimpleTest.php'),
$exit = TRUE)
phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:129
PHP 4. PHPUnit_Runner_BaseTestRunner->getTest(
$suiteClassName = 'SimpleTest',
$suiteClassFile = '/home/kevin/Workspace/php/laravel/app/tests/SimpleTest.php',
$suffixes = array (0 => 'Test.php', 1 => '.phpt'))
phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:150
PHP 5. ReflectionClass->getMethod('suite')
phar:///usr/local/bin/phpunit/phpunit/Runner/BaseTestRunner.php:113
PHPUnit 3.7.27 by Sebastian Bergmann.
Anything is welcome, thanks .
It looks like this error comes from an xdebug setting.
The solution appears to be adding this line to your php.ini file (or changing your the existing value to 0):
xdebug.show_exception_trace = 0
Take a look at
PHPUnit ReflectionException Method suite does not exist and
Why does PHPUnit hide my xdebug backtrace? for more info.