Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly change testing environment vars - Codeception and Laravel 5.1

I am trying to use a sqlite db for testing purposes, as I don't want to touch my actual database:

In my unit.suite.yml file:

class_name: UnitTester
modules:
    enabled: [Asserts, UnitHelper]
    config:
        Db:
            dsn: 'sqlite:app/tests/_data/testdb.sqlite'
            user: ''
            password: ''
            dump: app/tests/_data/dump.sql

In my TestCase.php file I have a function which resets and migrates and seeds the db for testing:

        Artisan::call('migrate:reset');
        Artisan::call('migrate');
        Artisan::call('db:seed');

I also added the sqlite settings to app/config/testing/database.php:

<?php
// Codeception testing environment uses SQLITE

return [

    'default' => 'sqlite',

    'connections' => [
        'sqlite' => [
            'driver' => 'sqlite',
            'database' => 'app/tests/_data/testdb.sqlite',
            'prefix' => ''
        ],
    ]
];

I can verify that the database.php file is being read but something still prevents sqlite from being used, and I still end up hosing my REAL database (MySQL). How do I force Laravel/Codeception to use my test db?

like image 858
Joel Joel Binks Avatar asked Jun 25 '15 22:06

Joel Joel Binks


Video Answer


2 Answers

copying a part of my blog here ...

After searching around a bit, we suppose to include variables inside phpunit.xml. There are some preincluded ones

<php>
    <env name="APP_ENV" value="testing"/>
    <env name="CACHE_DRIVER" value="array"/>
    <env name="SESSION_DRIVER" value="array"/>
    <env name="QUEUE_DRIVER" value="sync"/>
</php>

However I wanted to use .env files. So there is always a way :)

All you need to do now is call applications loadEnvironmentFrom($file) with proper env file. Since I only needed it for testing I added .env.testing.example and .env.testing (that is excluded from git). I added a call to method in /tests/TestCase.php

public function createApplication()
{
    $app = require __DIR__.'/../bootstrap/app.php';

    //THIS IS IT :)
    $app->loadEnvironmentFrom('.env.testing');

    $app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();

    return $app;
}
like image 156
Miha Trtnik Avatar answered Sep 27 '22 18:09

Miha Trtnik


TL;DR:

APP_ENV=testing php artisan serve

If you run "php artisan help" you will see:

--env[=ENV]       The environment the command should run under.
  • --env=testing does not change the .env file anymore. So this information is incomplete.
  • Files like config/testing/database.php worked on Laravel 4.2, won't work on Laravel 5
  • PHPUnit sets environment variables through phpunit.xml, but it won't work with Codeception.
  • Codeception has a module for Laravel 5, there you can set environment_file to be .env.testing and then you can use this file for your tests. However it won't work on acceptance tests, since these tests open a browser. In this case you could customize your app.php and add this before return $app:

if (!empty($argv) && in_array('--env=testing', $argv)) { $app->loadEnvironmentFrom('.env.testing'); }

And then you can start your server with "php artisan serve --env=testing"

This is a workaround and i hope soon enough someone from Laravel will define the right way to do this.

UPDATE: This way is less messy:

APP_ENV=testing php artisan serve

And then:

if (getenv('APP_ENV') === 'testing') { 
    $app->loadEnvironmentFrom('.env.testing');
}

UPDATE 2: it seems you don't need the condition above in 5.2, or maybe never needed?

like image 33
carlosvini Avatar answered Sep 27 '22 18:09

carlosvini