I try to add this code in my DefaultControllerTest
$load = new Loader();
$load->load('src/AppBundle/DataFixtures/ORM/product.yml');
and here is the complete code of my controller
<?php
namespace Tests\AppBundle\Controller;
use Nelmio\Alice\Fixtures\Loader;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class DefaultControllerTest extends WebTestCase
{
public function testIndex()
{
$load = new Loader();
$load->load('src/AppBundle/DataFixtures/ORM/product.yml');
$client = static::createClient();
$crawler = $client->request('GET', '/');
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$this->assertContains('Welcome to Symfony', $crawler->filter('#container h1')->text());
}
}
If I run phpunit. It works and no errors found. It successfully tested but the problem here the product.yml doesn't insert any data in my database. But If I run this command bin/console hautelook_alice:doctrine:fixtures:load --append. This will works. It insert the data. How can I load the datafixture before I test the controller? I try to research more about it. but I have no clue on how to add it now.
You can simply use a bash script. Something like this (adapt to your needs):
#!/bin/bash
echo "# Refresh data model and load fixtures"
php bin/console doctrine:database:create --if-not-exists --env=dev
php bin/console doctrine:schema:drop --force --env=dev
php bin/console doctrine:schema:create --env=dev
php bin/console doctrine:schema:validate --env=dev
php bin/console hautelook_alice:doctrine:fixtures:load --append --env=dev
echo -e " --> DONE\n"
Then you can launch phpunit that will use this fresh database. Or you could just add the phpunit call in this script:
./bin/simple-phpunit --debug --verbose
Related
When I try to run that phing command: bin/phing clear_cache_action from a console, everything works. Unfortunately, when I try to run the same command from the controller in the Symfony project I get an error.
That my code:
public function clearAction()
{
$process = new Process('bin/phing clear_cache_action');
$process->run();
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
echo $process->getOutput();
}
Symfony returns me that error:
The command "bin/phing clear_cache_action" failed.
Exit Code: 127(Command not found)
Working directory: /var/www/caolin/web
Output:
================
Error Output:
================
sh: 1: bin/phing: not found
Linux commands e.g. 'ls' works properly.
How can I run phing command from code?
I guess you are trying to execute phing from a Controller. Thus Working directory: /var/www/caolin/web instead of /var/www/caolin causes resolving bin/phing to /var/www/caolin/web/bin/phing which does not exist. You should set your current working directory to %kernel.project_dir%:
$process = new Process(
['bin/phing', 'clear_cache_action'],
$this->getParameter('kernel.project_dir')
);
$process->run();
However, I would not recommend starting a process from a Controller unless you are really sure what you are doing.
I have a Symfony 4 application and Doctrine with Doctrine migrations. I'm introducing Codeception for running API tests, and need to run migrations before the tests run. Since I'm using the Doctrine2 module I don't really want to be also including the DB module as it's not needed for the tests and would require configuring the test database in two different locations.
I am using the Symfony module currently, and I noticed that the Laravel module has a run_database_migrations configuration option.
What is the best way to handle running the Doctrine migrations command in a Symfony app prior to the tests? (bin/console doctrine:migrations:migrate -n is the specific command).
Edit I've got a solution that, although it works, is nowhere near ideal. By using Codeception Customisation I've created the following extension that basically manually execs the underlying Symfony commands.
class DatabaseMigrationExtension extends Extension
{
public static $events = [
Events::SUITE_BEFORE => 'beforeSuite',
];
public function beforeSuite(SuiteEvent $e)
{
echo(exec('bin/console doctrine:database:drop --force') . PHP_EOL);
echo(exec('bin/console doctrine:database:create') . PHP_EOL);
echo(exec('bin/console doctrine:migrations:migrate -n') . PHP_EOL);
}
}
Edit 2 The goal of this is basically to replicate similar functionality to what the Codeception DB module does, which allows you to provide an SQL dump of a database that it automatically uses in the tests, but instead use Doctrine migrations to handle the DB. - https://codeception.com/docs/modules/Db#sql-data-dump
I spent a while trying a couple of different ways to achieve this. I initially used RunProcess however this seemed to cause sporadic issues with the DB being deleted and not recreated, despite using the sleep configuration. I ended up just updating the existing extension to use the CLI module instead, and it works as desired (without having to create scripts or run multiple commands) and without having to use exec.
Final extension;
class DatabaseMigrationExtension extends Extension
{
public static $events = [
Events::SUITE_BEFORE => 'beforeSuite',
];
public function beforeSuite()
{
try {
/** #var \Codeception\Module\Cli $cli */
$cli = $this->getModule('Cli');
$this->writeln('Recreating the DB...');
$cli->runShellCommand('bin/console doctrine:database:drop --if-exists --force');
$cli->seeResultCodeIs(0);
$cli->runShellCommand('bin/console doctrine:database:create');
$cli->seeResultCodeIs(0);
$this->writeln('Running Doctrine Migrations...');
$cli->runShellCommand('bin/console doctrine:migrations:migrate --no-interaction');
$cli->seeResultCodeIs(0);
$this->writeln('Test database recreated');
} catch (\Exception $e) {
$this->writeln(
sprintf(
'An error occurred whilst rebuilding the test database: %s',
$e->getMessage()
)
);
}
}
}
and registered;
// codeception.yml
extensions:
enabled:
- \DatabaseMigrationExtension
Output (-vv or higher also displays the output of the DB & Migration commands);
I always create a bash script to do this, or a Makefile.
bash command
My ./runtests.sh scripts contains
#!/bin/bash
./bin/console command:for:migrations
./bin/phpunit
Makefile
Same with Makefile
.FOO: testsuite
testsuite:
./runtests.sh
or
.FOO: testsuite
testsuite:
./bin/console command:for:migrations
./bin/phpunit
why I prefer Makefile
Recently I added this script in my .bash_profile that allow me to autocomplete from bash all target made in makefile (very easy because you dont need anymore to remember all commands, but just make and tab).
complete -W "`grep -oE '^[a-zA-Z0-9_.-]+:([^=]|$)' Makefile | sed 's/[^a-zA-Z0-9_.-]*$//'`" make
Thus, .. you can create target like:
runtests
runtests_with_fixtures
migrations
runtests_with_migrations
...
and so on
My suggestion is to create your custom and easy way to run commands.
Here a way to run all or just one command usgin make
.FOO: dropforce
dropforce:
bin/console doctrine:database:drop --force
.FOO: dbcreate
dbcreate:
bin/console doctrine:database:create
.FOO: migrate
migrate:
bin/console doctrine:migrations:migrate
.FOO: suite
suite: dropforce dbcreate migrate
With Codeception 4 you can do it without Cli module:
$symfony = $this->getModule('Symfony');
$symfony->runSymfonyConsoleCommand('doctrine:database:drop',['--if-exists'=>true, '--force'=>true]);
$symfony->runSymfonyConsoleCommand('doctrine:database:create');
$symfony->runSymfonyConsoleCommand('doctrine:migrations:migrate', ['--no-interaction'=>true]);
I'm trying to write some functional tests for a Symfony2 app.
Those tests interacts with the database, using, obviously, Doctrine.
Now, I setup the configuration to call the test database, but it is empty and has no tables, so my tests fail.
How can I build the database schema into the test database before the execution of the tests?
I have tried this
namespace AppBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class GetStartedControllerTest extends WebTestCase
{
public function setUp()
{
passthru(sprintf('php "%s/console" cache:clear --env=test --no-warmup --no-interaction', __DIR__));
passthru(sprintf('php "%s/console" doctrine:database:drop --env=test --force --no-interaction', __DIR__));
passthru(sprintf('php "%s/console" doctrine:database:create --env=test --no-interaction', __DIR__));
passthru(sprintf('php "%s/console" doctrine:schema:update --force --env=test --no-interaction', __DIR__));
}
/**
*
*/
public function testRegisterNewUser()
{
...
But it seems not working...
Any ideas? Thank you!
I know you can run all datafixtures by running this command:
php app/console doctrine:fixtures:load
And that you can run a specific fixture by running this command:
php app/console doctrine:fixtures:load --fixtures=/path/to/fixture1
But now I'm trying the second command to load a specific datafixture like this:
php app/console doctrine:fixtures:load --fixtures=/src/VolleyScout/VolleyScoutBundle/DataFixtures/ORM/LoadRegionData
My LoadRegionData class is located at:
src/VolleyScout/VolleyScoutBundle/DataFixtures/ORM/LoadRegionData.php
When I run the command I always get the following error:
[InvalidArgumentException]
Could not find any fixtures to load in:
- /src/VolleyScout/VolleyScoutBundle/DataFixtures/ORM/LoadRegionData
LoadRegionData.php
<?php
namespace VolleyScout\VolleyScoutBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use VolleyScout\VolleyScoutBundle\Entity\Regions;
class LoadRegionData implements FixtureInterface
{
/**
* {#inheritDoc}
*/
public function load(ObjectManager $manager)
{
$regions = ['West-Vlaanderen', 'Oost-Vlaanderen', 'Antwerpen', 'Vlaams-Brabant', 'Limburg', 'Vlaanderen'];
foreach($regions as $r){
$region = new Regions();
$region->setRegionName($r);
$region->setRegionDescription($r);
$manager->persist($region);
$manager->flush();
}
}
}
?>
try
php app/console doctrine:fixtures:load --fixtures=src/VolleyScout/VolleyScoutBundle/DataFixtures/ORM
Try it with the full path:
php app/console doctrine:fixtures:load --fixtures=/Users/foobar/projects/projectname/src/VolleyScout/VolleyScoutBundle/DataFixtures/ORM
I have a test that runs a Symfony 2.0 Command. In the test, I run the Command like this:
$application = new Application(static::$kernel);
$application->add(new MyCommand());
$command = $application->find('mycommand:name');
$commandTester = new CommandTester($command);
$commandTester->execute(array('command' => $command->getName()));
I want to run the Command with the --no-debug flag, which is a built-in flag to the app:console (I guess?). I've tried:
$commandTester->execute(array('command' => $command->getName(), '--no-debug' => true));
and I've also tried:
$application->run(new StringInput('mycommand:name --no-debug'));
as suggested here. I've tried some other permutations too. But none of them do what I want, which is turn off all the Debug messages in the logs. Is there a way to do what I want in the test?
disabling debug in the kernel
You can initialize the kernel in your test's setUp() method with debug set to false.
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class YourCommandTest extends WebTestCase
{
public function setUp()
{
static::$kernel = static::createKernel(array('debug' => false));
static::$kernel->boot();
// ...
}
Have a look at WebTestCase->createKernel().
using enviroments
If you don't want the debug output in your logs edit/create app/config/config_test.yml and edit ...
monolog:
handlers:
file:
type: stream
level: debug # log-level ...
... to another log level that suits your needs.
Then execute your command using the test environment with --env=test
--no-debug obviously disable debug mode which show errors. Try to run command in test environment with --env=test.