0

I'm running Laravel 9 feature tests with the RefreshDatabase trait in GitHub Actions. Locally, everything works fine, but on CI, it seems that RefreshDatabase tries to connect with the wrong database or user. But actually i tryied to log it when workflow was running and its connecting correctly to postgre user.. Here's my setup:

phpunit.ci.xml

<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
         bootstrap="vendor/autoload.php"
         colors="true">
    <testsuites>
        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
            <exclude>./tests/Unit/PaymentManagement</exclude>
        </testsuite>
        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
            <exclude>./tests/Feature/Machines</exclude>
        </testsuite>
        <testsuite name="Modules">
            <directory suffix="Test.php">./Modules/*/Tests/Feature</directory>
            <directory suffix="Test.php">./Modules/*/Tests/Unit</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
        </whitelist>
    </filter>
    <php>
        <server name="APP_ENV" value="testing.ci"/>
        <server name="BCRYPT_ROUNDS" value="4"/>
        <server name="CACHE_DRIVER" value="array"/>
        <server name="MAIL_DRIVER" value="array"/>
        <server name="QUEUE_CONNECTION" value="sync"/>
        <server name="SESSION_DRIVER" value="array"/>
        <server name="TELESCOPE_ENABLED" value="false"/>
        <server name="DB_CONNECTION" value="pgsql"/>
        <server name="DB_HOST" value="127.0.0.1"/>
        <server name="DB_PORT" value="5432"/>
        <server name="DB_DATABASE" value="main_testing"/>
        <server name="DB_USERNAME" value="postgres"/>
        <server name="DB_PASSWORD" value="secret"/>

        <server name="DB_DATABASE_WAM" value="maw_testing"/>
        <server name="DB_USERNAME_WAM" value="postgres"/>
        <server name="DB_PASSWORD_WAM" value="secret"/>

        <server name="DB_DATABASE_VISITOR" value="visitor_testing"/>
        <server name="DB_USERNAME_VISITOR" value="postgres"/>
        <server name="DB_PASSWORD_VISITOR" value="secretx"/>
        <server name="DB_DATABASE_VISITOR" value="warehouse_testing"/>
        <server name="DB_USERNAME_VISITOR" value="postgres"/>
        <server name="DB_PASSWORD_VISITOR" value="secretx"/>
        <server name="DB_DATABASE_VISITOR" value="import_testing"/>
        <server name="DB_USERNAME_VISITOR" value="postgres"/>
        <server name="DB_PASSWORD_VISITOR" value="secretx"/>
        <ini name="output_buffering" value="0"/>
        <ini name="implicit_flush" value="1"/>
    </php>
</phpunit>

This is .env.testing.ci

APP_NAME=testapp
APP_ENV=testing
APP_URL=http://localhost
APP_DEBUG=true
LOG_CHANNEL=stack

DB_CONNECTION=pgsql

MY_DB_HOST=127.0.0.1
MY_DB_PORT=3308
MY_DB_DATABASE=media_testing
MY_DB_USERNAME=root
MY_DB_PASSWORD=

DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=main_testing
DB_USERNAME=postgres
DB_PASSWORD=secret

DB_DATABASE_WAM=maw_testing
DB_USERNAME_WAM=postgres
DB_PASSWORD_WAM=secret

DB_DATABASE_VISITOR=visitor_testing
DB_USERNAME_VISITOR=postgres
DB_PASSWORD_VISITOR=secret

DB_DATABASE_STORE=warehouse_testing
DB_USERNAME_STORE=postgres
DB_PASSWORD_STORE=secret

DB_DATABASE_ORDERS_IMPORT=import_testing
DB_USERNAME_ORDERS_IMPORT=postgres
DB_PASSWORD_ORDERS_IMPORT=secret 

And this is workflow

on: workflow_dispatch


jobs:
  testapp-test:
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: secret
          POSTGRES_DB: main_testing
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 3

      redis:
        image: redis:7
        ports:
          - 6379:6379
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 3

    steps:
      - uses: actions/checkout@v3

      - name: Set up PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
          extensions: pgsql, redis, bcmath, gd, intl, mbstring, pdo, tokenizer, xml, curl
          ini-values: post_max_size=256M, upload_max_filesize=256M, memory_limit=512M
          tools: composer:v2

      - name: Configure composer auth
        run: composer config --global --auth github-oauth.github.com ${{ secrets.MOPS_TEST_COMPOSER_TOKEN }}          

      - name: Install dependencies
        run: composer install --prefer-dist --no-progress

      - name: Copy .env
        run: cp .env.testing.ci .env

      - name: create extra databases
        env:
          PGPASSWORD: secret
        run: |
          psql -h 127.0.0.1 -U postgres -c "CREATE DATABASE maw_testing;"
          psql -h 127.0.0.1 -U postgres -c "CREATE DATABASE visitor_testing;"
          psql -h 127.0.0.1 -U postgres -c "CREATE DATABASE warehouse_testing;"
          psql -h 127.0.0.1 -U postgres -c "CREATE DATABASE import_testing;"
          
      - name: Run migrations
        run: php artisan migrate --force

      - name: Run tests
        run: php artisan test --configuration=phpunit.ci.xml

example of test

<?php

namespace Tests\Feature\ProductionDashboard;

use Mockery;
use App\Models\Machine;
use Tests\TestCase;
use App\Models\ProductionDashboard;
use App\Enums\ProductionDashboardType;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Libraries\ProductionDashboardLibrary\MachineJobAggregator;

class ProductionDashboardCrudTest extends TestCase
{
    use RefreshDatabase, WithFaker;

    protected function tearDown(): void
    {
        Mockery::close();
        parent::tearDown();
    }


    public function test_grid_returns_json()
    {
        $machine = Machine::factory()->create();

        $aggregatorMock = Mockery::mock('alias:' . MachineJobAggregator::class);
        $aggregatorMock->shouldReceive('initializeMachineData')
            ->andReturn([
                'ready_jobs' => [
                    ['job' => 1, 'jobjobmachine' => 1, 'producttype' => 'Test']
                ]
            ]);
        $aggregatorMock->shouldReceive('aggregate')
            ->andReturn(['total' => 1]);

        $url = '/api/production-dashboard/grid/ready_jobs?params[machine_id]=' . $machine->id;
        $response = $this->getJson($url);

        $response->assertStatus(200)
            ->assertJsonStructure([
                'data',
                'links',
                'meta',
            ]);
    }

When i remove trait for RefreshDatabase it works well. Or it works well even with DatabaseTransaction trait, but I wasnt able figure out how solve problem with RefreshDatabse trait. With presence of RefreshDatabase trai all test alway fails, not just example above.

1 Answer 1

0
  • Remove all DB-related <server> variables from phpunit.ci.xml.
    Keep only the generic ones like BCRYPT_ROUNDS, CACHE_DRIVER, etc.
    Example slimmed-down phpunit.ci.xml:

    <phpunit bootstrap="vendor/autoload.php" colors="true">
        <testsuites>
            <testsuite name="Feature">
                <directory suffix="Test.php">./tests/Feature</directory>
            </testsuite>
            <testsuite name="Unit">
                <directory suffix="Test.php">./tests/Unit</directory>
            </testsuite>
        </testsuites>
        <php>
            <server name="APP_ENV" value="testing"/>
            <server name="BCRYPT_ROUNDS" value="4"/>
            <server name="CACHE_DRIVER" value="array"/>
            <server name="QUEUE_CONNECTION" value="sync"/>
            <server name="SESSION_DRIVER" value="array"/>
            <ini name="output_buffering" value="0"/>
            <ini name="implicit_flush" value="1"/>
        </php>
    </phpunit>
    
    
  • In your GitHub Actions workflow, copy the CI env file to the right name so Laravel actually loads it:

    - name: Copy .env.testing.ci
      run: cp .env.testing.ci .env.testing
    
    
  • Run tests explicitly with the testing environment (so RefreshDatabase reads .env.testing):

    - name: Run tests
      run: php artisan test --env=testing --configuration=phpunit.ci.xml
    
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.