Chapters
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.1.3, <8.0
Subscribe to download the code!Compatible PHP versions: ^7.1.3, <8.0
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
Bootstrapping a Test Suite
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeOur security requirements are about to get... pretty complicated. And so, instead of testing all of that manually and hoping we don't break anything, I think it's time to take a few minutes to get a nice functional testing system set up.
Spin over to your terminal and run:
composer require "test:1.0.6" "symfony/phpunit-bridge:4.3.3" --dev
This will download Symfony's test-pack, which most importantly comes with the PHPUnit bridge: a small Symfony component that wraps around PHPUnit.
When that finishes... yep - we'll put our tests in the tests/
directory and run PHPUnit via php bin/phpunit
. That's a bit different than if you installed PHPUnit directly and you'll see why in a minute. That file - bin/phpunit
was added by the recipe. And... if you run git status
, you'll see that the recipe also added a phpunit.xml.dist
file, which holds sensible default config for PHPUnit itself.
Configuring the PHPUnit Version
Open that file up. One of the keys here is called SYMFONY_PHPUNIT_VERSION
, which at the time I recorded this is set to 7.5 in the recipe. You can leave this or change it to the latest version of PHPUnit, which for me is 8.2
Tip
PHPUnit 8.2 requires PHP 7.2. If you're using PHP 7.1, stay with PHPUnit 7.5.
Show Lines
|
// ... lines 1 - 3 |
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
Show Lines
|
// ... lines 5 - 8 |
> | |
<php> | |
<ini name="error_reporting" value="-1" /> | |
<server name="APP_ENV" value="test" force="true" /> | |
<server name="SHELL_VERBOSITY" value="-1" /> | |
<server name="SYMFONY_PHPUNIT_REMOVE" value="" /> | |
<server name="SYMFONY_PHPUNIT_VERSION" value="8.2" /> | |
</php> | |
Show Lines
|
// ... lines 17 - 32 |
</phpunit> |
But wait... why are we controlling the version of PHPUnit via some variable in an XML file? Isn't PHPUnit a dependency in our composer.json
file? Actually... no! When you use Symfony's PHPUnit bridge, you don't require PHPUnit directly. Instead, you tell it which version you want, and it downloads it in the background.
Check it out. Run:
php bin/phpunit
This downloads PHPUnit in the background and installs its dependencies. That's not really an important detail... but it might surprise you the first time you run this. Where did it download PHPUnit? Again, that's not an important detail... but I do like to know what's going on. In your bin/
directory, you'll now find a .phpunit/
directory.
Customizing the test Database
After downloading PHPUnit, that bin/phpunit
script does then execute our tests... except that we don't have any yet. Before we write our first one, let's tweak a few other things.
The recipe added another interesting file: .env.test
. Thanks to its name, this file will only be loaded in the test
environment... which allows us to create test-specific settings. For example, I like to use a different database for my tests so that running them doesn't mess with my development database.
# define your env variables for the test env here | |
KERNEL_CLASS='App\Kernel' | |
APP_SECRET='$ecretf0rt3st' | |
SYMFONY_DEPRECATIONS_HELPER=999999 | |
Show Lines
|
// ... lines 5 - 6 |
Inside .env
, copy the DATABASE_URL
key, paste it in .env.test
and add a little _test
at the end.
Show Lines
|
// ... lines 1 - 4 |
DATABASE_URL=mysql://root:@127.0.0.1:3306/cheese_whiz_test |
Cool, right? One of the gotchas of the .env
system is that the .env.local
file is normally loaded last and allows us to override settings for our local computer. That happens in every environment... except for test
. In the test
environment, .env
& .env.test
are read, but not .env.local
. That little inconsistency exists so that everyone's test environment behaves the same way.
Anyways, now that our test environment knows to use a different database, let's create that database! Run bin/console doctrine:database:create
. But since we want this command to execute in the test
environment, also add --env=test
:
php bin/console doctrine:database:create --env=test
Repeat that same thing with the doctrine:schema:create
command:
php bin/console doctrine:schema:create --env=test
Perfect! Next, Api Platform has some really nice testing tools which... aren't released yet. Boo! Well... because I'm impatient, let's backport those new tools into our app and get our first test running.
42 Comments
Sounds like the behavior I would expect :)
hi there, is there any way to get a repository so I can start from here and up to date? I have many errors and tried to fix them by changing them to different versions but non of them work.. nothing seems to work anymore
Yo Thijs!
Sorry about the trouble - that's not what we want :/. The only code I have available is the same you have. Well, I can fast forward the code to this *exact* chapter, but that's is just the code from the "start" of this tutorial + what we've done in the first 9 chapters. To help, what kinds of issues are you having? Is it related to the API Platform test files that we "backport" from version 2.5 (which wouldn't be necessary when using API Platform 2.5 and later)? Or something different?
Let me know. We run CI on our courses to make sure they keep working - but there are almost definitely "holes" in what we're checking in our CI.
Cheers!
Hi
I run out a new issue (dependencies, always dedendencies).
At this point my code is like https://github.com/atournayre/symfonycasts_code_api_platform-_security/commit/f8f5133e0c901d06d044bfba64a17f3246654bc5
When I run composer require symfony/test-pack --dev
Here is the end of composer's trace
<blockquote>
Symfony operations: 1 recipe (07704831784e60d7ba454f35c88fd980)
- Configuring phpunit/phpunit (>=4.7): From github.com/symfony/recipes:master
Executing script cache:clear [OK]
Executing script assets:install public [OK]
Some files may have been created or updated to configure your new packages.
Please review, edit and commit them: these files are yours.
Unpacked symfony/test-pack dependencies
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Package operations: 0 installs, 0 updates, 1 removal
- Removing symfony/test-pack (v1.0.8)
Package zendframework/zend-code is abandoned, you should avoid using it. Use laminas/laminas-code instead.
Package zendframework/zend-eventmanager is abandoned, you should avoid using it. Use laminas/laminas-eventmanager instead.
Package phpunit/php-token-stream is abandoned, you should avoid using it. No replacement was suggested.
28 packages you are using are looking for funding.
Use thecomposer fund
command to find out more!
</blockquote>
start/composer.json do not look like finish/composer.json
In this version of dependencies, php bin/phpunit
doesn't work as phpunit do not exists in /bin
After composer require, require-dev looks like this
`
"require-dev": {
"phpunit/phpunit": "^9.2",
"symfony/browser-kit": "^4.3",
"symfony/css-selector": "^4.3",
"symfony/maker-bundle": "^1.11",
"symfony/phpunit-bridge": "^5.3",
"symfony/profiler-pack": "^1.0"
}
`
Exact versions are :
phpunit/phpunit => 9.2.5
symfony/browser-kit => 4.3.11
symfony/css-selector => 4.3.11
symfony/maker-bundle => 1.12.0
symfony/phpunit-bridge => 5.3.3
symfony/profiler-pack => 1.0.4
Do anyone have an idea about how to make phpunit work in this configuration ?
I solve the problem by using code in finish directory
https://github.com/atournay...
- copy bin/phpunit, composer.json, composer.lock and phpunit.xml.dist from /finish
- composer install
- php bin/phpunit
Hey atournayre
I'm glad you could fix your problem. I believe the recipe that got installed was outdated due to your Symfony version or something else. When I find myself in that situation I just copy-paste the file I'm missing from the recipe repository. If you go to https://flex.symfony.com/ you will find all of the recipes and a link to their repositories
Cheers!
Ok so I am not sure of what are the advantages of the symfony bridge thing...
As far as I see the only advantage is we have a shortcut to call the tests, other than that it makes reading the test results harder with the amount of spam it fills my console with and makes my CI containers have to download the test suit every time since it is out of composer install step on my build stage.
Either I am doing something wrong or in a less recommended way, or the bridge is not that useful...
So what are the practical advantages of the bridge? What am I doing wrong??
Note: the involuntary spam is always a negative point for me. I should opt in to it not the other way around...
Hey Fernando A.
It's a good question =) First about CI setup, you should save bin/.phpunit/
folder in persistent cache, so it won't be downloaded each time. So now about advantages, the main is that you will have cleaner dependencies and installed phpunit will not conflict any of you installed deps, also it will not block something from installing, also it has a lot of helpers for testing you can find more exact info here https://symfony.com/doc/current/components/phpunit_bridge.html
Cheers!
Now I'm running into this error when trying to install test.
[UnexpectedValueException]<br />Invalid version string "5.x"
Googling this so far only came up with composer self-update as a possible fix but it didn't help. Any ideas?
Hey Aaron,
Hmm, I'd need to see more information about the error. Try again passing the option -vvv
to composer. Also, give it a try clearing composer's cache composer clearcache
Cheers!
Hmmm, thought I replied but don't see it here. Was it deleted?
Clearing the cache didn't seem to help. Here's the full output after clearing the cache.
`Reading ./composer.json
Loading config file ./composer.json
Checked CA file C:\Users\ack\AppData\Local\Temp\ope1669.tmp: valid
Executing command (C:\Users\ack\PhpstormProjects\API-Platform-Training): git branch --no-color --no-abbrev -v
Executing command (C:\Users\ack\PhpstormProjects\API-Platform-Training): git describe --exact-match --tags
Executing command (CWD): git --version
Executing command (C:\Users\ack\PhpstormProjects\API-Platform-Training): git log --pretty="%H" -n1 HEAD --no-show-signature
Executing command (C:\Users\ack\PhpstormProjects\API-Platform-Training): hg branch
Executing command (C:\Users\ack\PhpstormProjects\API-Platform-Training): fossil branch list
Executing command (C:\Users\ack\PhpstormProjects\API-Platform-Training): fossil tag list
Executing command (C:\Users\ack\PhpstormProjects\API-Platform-Training): svn info --xml
Failed to initialize global composer: Composer could not find the config file: C:/Users/ack/AppData/Roaming/Composer/composer.json
To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section
Reading C:\Users\ack\PhpstormProjects\API-Platform-Training/vendor/composer/installed.json
Loading plugin Symfony\Flex\Flex
Downloading https://repo.packagist.org/packages.json
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/packages.json into cache
Downloading http://repo.packagist.org/p/provider-2013$97f5d9dda812073c84ecf273acfd5fedffe98708e0803b508efcab91e83965bf.json
Downloading http://repo.packagist.org/p/provider-2014$5182f2d4ecee95d6f0d9f26215a61447a4ad337f4463b12f80e5cc6d3bb07d24.json
Downloading http://repo.packagist.org/p/provider-2015$36e049d4d45dc87b656de56bf89bde32cee2d63fa405c99fac52fec5fa75f8e2.json
Downloading http://repo.packagist.org/p/provider-2016$208eddf0d1e2f55e115caed65c94dce8695a5e3de2eccea9b1284571d2d91e71.json
Downloading http://repo.packagist.org/p/provider-2017$65102f8576a5c8ed6c12be8cafdc01623b5e803cd2a6d99bf383e0edcab6b29d.json
Downloading http://repo.packagist.org/p/provider-2018$f1c4fa3a046d712671217832f02c961549da0500e43bbcc8fdd230750b4aae68.json
Downloading http://repo.packagist.org/p/provider-2019$23dcce68f316bda995b715b574d08e81013520917f41050f6cb0b4df946a1f42.json
Downloading http://repo.packagist.org/p/provider-2020-01$2ec363a4baba72e84759e7ec9215a83f86a3aaf9d545907ca87f86193ed6852b.json
Downloading http://repo.packagist.org/p/provider-2020-04$d3ee8af1a5ea0f01060c75aea9e912ddfaecc5ff0cdd5532bb35bd7271a6dbd4.json
Downloading http://repo.packagist.org/p/provider-2020-07$2e28893c98ae8902efaafaa70bcaa12ddae690753fc7082e139664530fa61541.json
Downloading http://repo.packagist.org/p/provider-archived$238324efe8fb943f822bb7872ce9001ea63c2e345322c09f4a2122a9d272411f.json
Downloading http://repo.packagist.org/p/provider-latest$acfeb9c609494e69d892094c60f939fa6f68c7ed2a7232d993bd46d54e105a75.json
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-latest.json into cache
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-archived.json into cache
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2020-07.json into cache
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2020-04.json into cache
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2020-01.json into cache
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2019.json into cache
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2018.json into cache
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2017.json into cache
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2016.json into cache
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2015.json into cache
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2014.json into cache
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2013.json into cache
Loading plugin PackageVersions\Installer
Running 1.10.13 (2020-09-09 11:46:34) with PHP 7.4.9 on Windows NT / 10.0
Downloading https://flex.symfony.com/aliases.json
Writing C:/Users/ack/AppData/Local/Composer/repo/https---flex.symfony.com/aliases.json into cache
Downloading https://flex.symfony.com/versions.json
Writing C:/Users/ack/AppData/Local/Composer/repo/https---flex.symfony.com/versions.json into cache
Downloading https://repo.packagist.org/packages.json
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/packages.json into cache
Reading C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2013.json from cache
Reading C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2014.json from cache
Reading C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2015.json from cache
Reading C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2016.json from cache
Reading C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2017.json from cache
Reading C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2018.json from cache
Reading C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2019.json from cache
Reading C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2020-01.json from cache
Reading C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2020-04.json from cache
Reading C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-2020-07.json from cache
Reading C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-archived.json from cache
Reading C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/p-provider-latest.json from cache
Downloading http://repo.packagist.org/p/symfony/test-pack$f4ec73f6f7784cf4b4c02a4abf573eadbad89565446ea82d14e6f9f23ac851cc.json
Writing C:/Users/ack/AppData/Local/Composer/repo/https---repo.packagist.org/provider-symfony$test-pack.json into cache
[UnexpectedValueException]
Invalid version string "5.x"
Exception trace:
() at phar://C:/ProgramData/ComposerSetup/bin/composer.phar/vendor/composer/semver/src/VersionParser.php:185
Composer\Semver\VersionParser->normalize() at C:\Users\ack\PhpstormProjects\API-Platform-Training\vendor\symfony\flex\src\Cache.php:123
Symfony\Flex\Cache->getVersions() at C:\Users\ack\PhpstormProjects\API-Platform-Training\vendor\symfony\flex\src\Cache.php:58
Symfony\Flex\Cache->removeLegacyTags() at C:\Users\ack\PhpstormProjects\API-Platform-Training\vendor\symfony\flex\src\TruncatedComposerRepository.php:41
Symfony\Flex\TruncatedComposerRepository->fetchFile() at phar://C:/ProgramData/ComposerSetup/bin/composer.phar/src/Composer/Repository/ComposerRepository.php:366
Composer\Repository\ComposerRepository->whatProvides() at phar://C:/ProgramData/ComposerSetup/bin/composer.phar/src/Composer/Repository/ComposerRepository.php:140
Composer\Repository\ComposerRepository->findPackage() at phar://C:/ProgramData/ComposerSetup/bin/composer.phar/src/Composer/Repository/RepositoryManager.php:58
Composer\Repository\RepositoryManager->findPackage() at C:\Users\ack\PhpstormProjects\API-Platform-Training\vendor\symfony\flex\src\Unpacker.php:39
Symfony\Flex\Unpacker->unpack() at C:\Users\ack\PhpstormProjects\API-Platform-Training\vendor\symfony\flex\src\Command\RequireCommand.php:51
Symfony\Flex\Command\RequireCommand->execute() at phar://C:/ProgramData/ComposerSetup/bin/composer.phar/vendor/symfony/console/Command/Command.php:245
Symfony\Component\Console\Command\Command->run() at phar://C:/ProgramData/ComposerSetup/bin/composer.phar/vendor/symfony/console/Application.php:835
Symfony\Component\Console\Application->doRunCommand() at phar://C:/ProgramData/ComposerSetup/bin/composer.phar/vendor/symfony/console/Application.php:185
Symfony\Component\Console\Application->doRun() at phar://C:/ProgramData/ComposerSetup/bin/composer.phar/src/Composer/Console/Application.php:281
Composer\Console\Application->doRun() at phar://C:/ProgramData/ComposerSetup/bin/composer.phar/vendor/symfony/console/Application.php:117
Symfony\Component\Console\Application->run() at phar://C:/ProgramData/ComposerSetup/bin/composer.phar/src/Composer/Console/Application.php:113
Composer\Console\Application->run() at phar://C:/ProgramData/ComposerSetup/bin/composer.phar/bin/composer:61
require() at C:\ProgramData\ComposerSetup\bin\composer.phar:24
require [--dev] [--prefer-source] [--prefer-dist] [--fixed] [--no-progress] [--no-suggest] [--no-update] [--no-scripts] [--update-no-dev] [--update-with-dependencies] [--update-with-all-dependencies] [--ignore-platform-reqs] [--prefer-stable] [--prefer-lowest] [--sort-packages] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--unpack] [--] [<packages>]...`
I don't really know what's wrong so I'll tell you a few things you can do
1) Upgrade composer composer selfupgrade
2) Upgrade Symfony Flex composer upgrade symfony/flex
3) Create a new Symfony app and try the command there. It's just to confirm that the problem is not your OS
Tested on my Linux machine and no issues so I'm guessing there's a bug somewhere in the Windows executables introduced in a recent update.
Hmm, that's very strange but you may be right. Windows is very tricky to work with. If you feel like so, you could open an issue here https://github.com/symfony/cli that's the official repository for reporting issues related to the Symfony CLI
Cheers!
OK, so if I create a brand new 5.x project with just "symfony new test" and then go in the test project to try to composer require a package then it works just fine. It's only if I take these actions that there's an issue:
1. Copy course code into new empty project folder
2. Run composer install
3. Run composer require xyz (any package)
Would that be a symfony or composer issue?
Hey @Aaron!
So, you've stumbled over an issue that's occurred in Symfony as they've been renaming their master branch to 5.x. Here is the issue: https://github.com/symfony/...
Basically, if you're inside a project using Symfony Flex 1.5.2 or lower, Flex will now be broken (there is a workaround in the issue to upgrade Flex). Until Friday morning, THIS code came with a version of Flex lower than 1.5.2 and THAT is why you got the error. Unfortunately, this error was introduced around Wednesday, and we didn't catch it, open that issue and fix it until Friday. Sorry about that!
Anyways, try downloading the fresh code again from this page - it should work because it now has a new symfony/flex version. But if you have any issues, please let us know.
Cheers!
Hey weaverryan you mean this is an instant where the problem did not exist between the keyboard and chair? I need to print out this thread and frame it.
lol - that was a good one :)
Hey @ Aaron Kincer!
> you mean this is an instant where the problem did not exist between the keyboard and chair
HA! Yep! And if you think you are unique in the problem "often" being between the keyboard and chair, I can tell you personally that you're wrong 😉
Cheers!
Looks like I'm not the only one experiencing this. Going to start by reinstalling Symfony CLI to see if it helps. Something has obviously gotten borked along the way.
FYI -- I created a brand new project, copied in course code and ran "composer install" then as soon as I tried to composer require a new package got the error.
Uninstalling and reinstalling symfony and composer didn't fix it for me like it did for one person. Something strange is going on.
#1 says it's up to date. #2 (and just composer upgrade) is failing with a strange error:
Call to a member function getVersions() on null
I'm guessing something got screwed up somewhere. I'll create a new project and start over.
Hi,
I have a problem to create a test database. I use docker and this is my two service of docker-compose:
mysql:
image: mysql:5.7
env_file: .env.local
container_name: mysql57-apiplat
restart: on-failure
ports:
- '3506:3306'
volumes:
- .docker/data/db:/var/lib/mysql
networks:
- gs_net
mysql-test:
image: mysql:5.7
env_file: .env.test.local
container_name: mysql57-test-apiplat
restart: on-failure
ports:
- '3606:3306'
volumes:
- .docker/data/db-test:/var/lib/mysql
networks:
- gs_net
For the first db I have this configuration insde .env and it works fine:
DATABASE_URL=mysql://sf5:sf5@mysql/sf5
In this chapter I have a .env.test and following the tutorial I have to use DATABASE_URL=mysql://sf5_test:sf5_test@mysql/sf5_test.
<u>PLEASE NOTE</u>: When I run docker-compose, inside .env.local, I get the variables for user, password, db and so on.
I use the command to create the db with --env=test and I expect a message more or less like 'db sf5_test already exists' (<u>PLEASE NOTE</u>: if I try to use the console command without --env=test I get the message 'sf5 exists' and it is normal because I created this db) but I got this message:
SQLSTATE[HY000] [1045]: Access denied for user 'sf5_test'@'172.185.0.5' (using password: YES).
I tried to look for a solution on the web but it doesn't work.
Could you help me to understand my error?
Thanks
Hey Gaetano S.
I think you can simplify your setup by reusing the database container for both environments, you only need to tweak your config. Inside config/packages/test/doctrine.yaml
append _test
to the doctrine.dbal.url
key. Example
doctrine:
dbal:
url: '%env(resolve:DATABASE_URL)%_test'
Does it makes sense?
Cheers!
I followed your suggestion and files look like this:
`
// docker-compose.yaml
version: '3.7'
services:
database:
image: 'postgres:11.6'
environment:
POSTGRES_PASSWORD: main
POSTGRES_USER: main
POSTGRES_DB: main
ports:
- target: 5432
published: 5432
protocol: tcp
// packages/doctrine.yaml
doctrine:
dbal:
url: '%env(resolve:DATABASE_URL)%'
server_version: '11.6'
orm:
auto_generate_proxy_classes: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
// packages/test/doctrine.yaml
doctrine:
dbal:
url: '%env(resolve:DATABASE_URL)%_test'
`
When I run symfony console doctrine:database:create --env=test
, I got this error:
`
Could not create database "main" for connection named default
An exception occurred while executing 'CREATE DATABASE "main"':
SQLSTATE[42P04]: Duplicate database: 7 ERROR: database "main" already exists
`
It doesn't seem like creating main_test
database.
Any idea? Thanks!
That's interesting. I believe your Database URL variable is formatted different than I expected. Could you run symfony console debug:container --env-vars
and look for the DB env var, I'd like to see how it's formatted (I'm guessing it will contain ?serverVersion
at the end)
This is what I got from symfony console debug:container --env-vars
.
<br /> APP_SECRET n/a "018ab41e394191547a91723137e22d31"<br /> CORS_ALLOW_ORIGIN n/a "^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$"<br /> DATABASE_URL n/a "postgres://main:main@127.0.0.1:5432/main?sslmode=disable&charset=utf8"<br /> JWT_PASSPHRASE n/a "xUqjziAiTJt4otyiBPPA"<br /> JWT_PUBLIC_KEY n/a "%kernel.project_dir%/config/jwt/public.pem"<br /> JWT_SECRET_KEY n/a "%kernel.project_dir%/config/jwt/private.pem"<br /> VAR_DUMPER_SERVER "127.0.0.1:9912" n/a<br />
It doesn't have serverVersion. Is it why not working?
Thank you!
Hey Sung L.!
You are running into a problem with the Docker setup and test databases that we're aware of. Basically, if you use the symfony binary + Docker setup, it's not easy to have a test database. The eventual fix will be for us to allow you to override the doctrine.dbal.dbname
in the test config file and have this override the database name specified in the doctrine.dbal.url
. Right now, if you have the url option specified, and you try to override just the dbname option in the test environment, the url "wins" (we need to make it possible for the dbname to win). This is actually on my open source TODO list (I've validated the fix with Fabien).
So, in your case, the reason it's not working is that the DATABASE_URL (as you can see) has query parameters on the end of it:
postgres://main:main@127.0.0.1:5432/main?sslmode=disable&charset=utf8
This means that when you do this - url: '%env(resolve:DATABASE_URL)%_test'
- it ultimately generates this database url:
postgres://main:main@127.0.0.1:5432/main?sslmode=disable&charset=utf8_test
See the problem?
For now, I've been creating 2 separate database containers - one for the normal environment and one for the test environment. Try downloading the code from this tutorial - https://symfonycasts.com/screencast/api-platform-extending - and looking at the "start" code - you'll see this system in action.
Let me know if you have any questions - doing this simple thing is currently WAY to hard and we (I) need to fix that!
Cheers!
Thanks for your help. I followed your advise and I used the same container for both env. But I have to use the root access (
DATABASE_URL=mysql://root:root@mysql/sf5) of .env.test. otherwise I would have the same error about access denied.
Hey Gaetano S.!
I'm just catching up here. I was little confused by your original setup - I'm not sure how the env_file: .env.local
config was working on Docker. If .env.local specifies DATABASE_URL... does the mysql container use this environment variable at all? I know this is something that Symfony/Docker will read, but I'm not aware (but I could be wrong) of whether or not this is something that the MySQL image actually uses to configure itself. Let me know :).
Generally-speaking, I like Diego's solution. But yea, you would probably need to use the root user in order to talk to both databases, or somehow make sure that there is some user that can access both. But other than that, it's a very simple way to set things up.
If you did use 2 different containers, I don't think you would need each to have a different database name or username, etc. Each container is independent, so each could have the exact same database name, username and password. The only thing you would need to modify in .env.test is that hostname - e.g. DATABASE_URL=mysql-test://sf5:sf5@mysql/sf5
.
Cheers!
Well, I use a .env.local file because I don't want to put all Mysql variables (MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER ans so on) inside the docker_compose. Then I use here the variable APP_ENV=dev and APP_SECRET. And yes, it does. The service of docker-compose (in this case the mysql image) uses these variables. OK, I will try also two different containers with your solution but before I would like to understand how to fix tests. I saw that you replied about it, I let you know. Thanks again, you are all very awesome.
Hi Gaetano S.!
Ah! I understand - thought you ONLY had DATABASE_URL
in .env.local - and I was searching the Internet to see if the MySQL Docker image somehow read this :).
And, ok - let's go debug those tests!
Cheers!
Hi, I'm jumping in in the middle of this screencast and composer require --dev test doesn't find any packages (trying to setup a dev env first and I want to have tests enabled before moving forward).
I'm guessing it's referring to:
composer require symfony/test-pack
Hey Cristian A.
This shortcuts depends on symfon/flex
package probably you can't use test
shortcut because flex is outdated or not installed. What is your situation?
Cheers!
Hey, I though I didn't post this :)
Turned out I was in the incorrect folder. I should have been inside /api, but instead tried to install it in the root. After that it worked as expected.
Ha! No problem!)) Anyways feel free to ask question! We are here to help!
Cheers! Have a great development!
FYI, you need to have PHP 7.2+ to use PHPUnit 8.2. Also installing phpunit and updating dependencies takes some time. For me, it took more than 10 min.
If you know how to make it faster, please share with us.
Thanks.
Hey Sung L.!
Ah, you're right - I should have made a point of that. We'll add a note! About the updating, that is strange. Internally, the script is basically doing a "composer create-project" on PHPUnit itself (which is sort of like doing a composer update) then, depending on your config, possibly also a few other composer commands. So, it shouldn't be super quick, but it shouldn't take more than 1 minute. Do you also see equally slow times if you run, for example, a composer update
on your project?
Cheers!
First, I had XDebug installed recently and I noticed it makes composer require test --dev
command super slow. Waited more than 20 min and still no response so I killed the process. After removing XDebug, installing test pack gets faster, but not as fast/responsive as "npm" install. composer update
is fast when I running it. However, updating PHPUnit is still slow.
Hey Sung L.!
Yea, XDebug is a huge problem for Composer - that will definitely kill performance. And Composer will never be as fast/responsible as "npm", unfortunately. Part of that I think is due to how sophisticated its dependency algorithm is, but also I think that algorithm could be improved (but very complex systems take a lot of effort to optimize!).
But the fact that composer update
is fast, but updating PHPUnit is is still slow doesn't make sense to me. When you execute the phpunit
file, ultimately it is loading vendor/symfony/phpunit-bridge/bin/simple-phpunit.php
(https://github.com/symfony/symfony/blob/4.4/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php). You can see that it's ultimately just running some composer commands - https://github.com/symfony/symfony/blob/042f5b5a9d580fd09889c30f1894af33caa6d775/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php#L118-L136
And, of course, these commands should be running as the same terminal user as normal. It's possible (but unlikely) that the script is using a different PHP binary or Composer executable... you could check by hacking into that file and dumping $COMPOSER
and $PHP
. But mostly, this is a bit of a mystery...
If you found out anything else, let me know!
Cheers!
"Houston: no signs of life"
Start the conversation!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3, <8.0",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/core": "^2.1", // v2.4.5
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.13.2
"doctrine/doctrine-bundle": "^1.6", // 1.11.2
"doctrine/doctrine-migrations-bundle": "^2.0", // v2.0.0
"doctrine/orm": "^2.4.5", // v2.7.2
"nelmio/cors-bundle": "^1.5", // 1.5.6
"nesbot/carbon": "^2.17", // 2.21.3
"phpdocumentor/reflection-docblock": "^3.0 || ^4.0", // 4.3.1
"symfony/asset": "4.3.*", // v4.3.2
"symfony/console": "4.3.*", // v4.3.2
"symfony/dotenv": "4.3.*", // v4.3.2
"symfony/expression-language": "4.3.*", // v4.3.2
"symfony/flex": "^1.1", // v1.21.6
"symfony/framework-bundle": "4.3.*", // v4.3.2
"symfony/http-client": "4.3.*", // v4.3.3
"symfony/monolog-bundle": "^3.4", // v3.4.0
"symfony/security-bundle": "4.3.*", // v4.3.2
"symfony/twig-bundle": "4.3.*", // v4.3.2
"symfony/validator": "4.3.*", // v4.3.2
"symfony/webpack-encore-bundle": "^1.6", // v1.6.2
"symfony/yaml": "4.3.*" // v4.3.2
},
"require-dev": {
"hautelook/alice-bundle": "^2.5", // 2.7.3
"symfony/browser-kit": "4.3.*", // v4.3.3
"symfony/css-selector": "4.3.*", // v4.3.3
"symfony/maker-bundle": "^1.11", // v1.12.0
"symfony/phpunit-bridge": "^4.3", // v4.3.3
"symfony/stopwatch": "4.3.*", // v4.3.2
"symfony/web-profiler-bundle": "4.3.*" // v4.3.2
}
}
BTW. If you install PHPUnit and then change the version to 8.2 and run bin/phpunit again, it will install the new version in another directory with the version postfix.
Happy coding!