skip to Main Content

I have a problem for a week, my tests can not connect with the database.
Indeed I have passed my environment under docker, my database connects perfectly but not the tests. Do you know why?
My errors :

[critical] Uncaught PHP Exception DoctrineDBALExceptionConnectionException: "An exception occurred in the driver: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo for database failed: Name or service not known" at /opt/project/vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php line 103

Here are my files:

docker-compose.yml

version: '3.7'
services:
    database:
        image: 'mysql:5.7'
        environment:
            MYSQL_ROOT_PASSWORD: root
            MYSQL_DATABASE: app
        ports:
            - '3306:3306'
        volumes:
            - db-data:/var/lib/mysql/data:rw

    app:
        image: peedro07/app:latest
        ports:
          - "8080:80"
        environment:
          DATABASE_URL: mysql://root:root@database:3306/app

volumes:
    db-data:

My Dockerfile which is build with the docker build command . -f chemin/Dockerfile -t peedro07/app

FROM php:8.1-apache

ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

RUN chmod +x /usr/local/bin/install-php-extensions && 
    install-php-extensions pdo_mysql intl

RUN curl -sSk https://getcomposer.org/installer | php -- --disable-tls && 
   mv composer.phar /usr/local/bin/composer


COPY . /var/www/

COPY ./docker/php/apache.conf /etc/apache2/sites-available/000-default.conf

RUN cd /var/www && 
    composer install

WORKDIR /var/www/

#ENTRYPOINT ["bash", "./docker/docker.sh"]

EXPOSE 80

My phpunit.xml.dist

<?xml version="1.0" encoding="UTF-8"?>

<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
         backupGlobals="false"
         colors="true"
         bootstrap="tests/bootstrap.php"
         convertDeprecationsToExceptions="false"
>
    <php>
        <env name="SYMFONY_DEPRECATIONS_HELPER" value="weak"/>
        <ini name="display_errors" value="1"/>
        <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="9.5"/>
    </php>

    <testsuites>
        <testsuite name="Project Test Suite">
            <directory>tests</directory>
        </testsuite>
    </testsuites>

    <coverage processUncoveredFiles="true">
        <include>
            <directory suffix=".php">src</directory>
        </include>
    </coverage>

    <listeners>
        <listener class="SymfonyBridgePhpUnitSymfonyTestsListener"/>
    </listeners>

    <!-- Run `composer require symfony/panther` before enabling this extension -->
    <!--
    <extensions>
        <extension class="SymfonyComponentPantherServerExtension" />
    </extensions>
    -->

    <extensions>
        <extension class="DAMADoctrineTestBundlePHPUnitPHPUnitExtension"/>
    </extensions>
</phpunit>

In my .env :

DATABASE_URL="mysql://root:root@database:3306/app"

In my env.test

KERNEL_CLASS='AppKernel'
APP_SECRET='$ecretf0rt3st'
SYMFONY_DEPRECATIONS_HELPER=999999
PANTHER_APP_ENV=panther
PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots
DATABASE_URL="mysql://root:root@database:3306/app"

2

Answers


  1. Chosen as BEST ANSWER

    Thank you for your response. It was simply a docker problem. I had to add a volume to my service app. I then killed my containers, and restarted docker. After reading several documentations, I also noticed that the mysql 5.7 image had some configuration problems, so I switched to the mariadb image which works perfectly with mysql (even if I find this behavior a bit weird ...) Thanks to all :) My new docker-compose.yml :

    database:
            image: 'mariadb'
            environment:
                MYSQL_ROOT_PASSWORD: root
                MYSQL_DATABASE: app
            command: ["mysqld", "--ignore-db-dir=lost+found", "--explicit_defaults_for_timestamp"]
            restart: always
            ports:
                - '3306:3306'
            volumes:
                - db-data:/var/lib/mysql/data:rw
    
        app:
            image: peedro07/app:latest
            restart: always
            ports:
              - "8080:80"
            environment:
                DATABASE_URL: mysql://root:root@database:3306/app
            volumes:
                - app-data:/var/www
    

  2. Symfony is usually adding a suffix to the database name in the test environment.

    You can verify that with the php bin/console debug:config doctrine --env=test command and look for the doctrine.dbal.connections.dbname_suffix config.

    Or you can look in one of these files depending on which version of Symfony you are using.

    Older:
    config/packages/test/doctrine.yaml

    doctrine:
        dbal:
            # "TEST_TOKEN" is typically set by ParaTest
            dbname: 'main_test%env(default::TEST_TOKEN)%'
    

    Newer:
    config/packages/doctrine.yaml

    when@test:
        doctrine:
            dbal:
                # "TEST_TOKEN" is typically set by ParaTest
                dbname_suffix: '_test%env(default::TEST_TOKEN)%'
    

    This config is useful to make sure you are not testing on "real data" aka corrupting the prod database.

    And the token might be useful should you have parallel testing.

    What I would usually do is:

    1. Create the tests database with php bin/console doctrine:database:create --env=test
    2. Make sure my tests load fixtures to have a predictable dataset between each test
    3. Run my tests
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search