Setting up integration tests in laravel package

We are currently trying to set up integration tests in a package I am writing.

For integration tests, I will need to have access to the Laravel environment so that I can access things like Artisan :: call ('migrate') and access the database.

My current guess is that I need any tests to extend the Laravel TestCase class by loading the Laravel framework. Although I can't practice how can I name this file in my package.

Second, when developing packages in the workbench, I will need to use Artisan :: call ('migrate', '--bench =' vendor / package '') or Artisan :: call ('migrate', '--package = " vendor / package "'), this is confusing.

+3


source to share


2 answers


We need to create a Laravel instance along with a database available for PHPUnit to run tests against real datasets. Not fragile ridicule. First, you must develop your packages separately for a number of reasons, one of which is a workbench in Laravel 5.

So, first we need dev-require

a Laravel framework in our project:

"require-dev": {
    "phpunit/phpunit": "~4.0",
    "phpspec/phpspec": "~2.1",
    "laracasts/testdummy": "~2.0",
    "laravel/laravel": "dev-develop"
},   

      

Now we can create an abstract class with a name DbTestCase

from which all our tests will pass. In this class, we will be deploying a Laravel instance and an in-memory SQLite database for speed.

If we extend our own Laravel test class Illuminate\Foundation\Testing\TestCase

, then some of the work has already been done by us. We just need to create a method that returns an instance Illuminate\Foundation\Application

.

/**
 * Boots the application.
 *
 * @return \Illuminate\Foundation\Application
 */
public function createApplication()
{
    $app = require __DIR__.'/../vendor/laravel/laravel/bootstrap/app.php';

    $app->register('Path\To\Your\PackageServiceProvider');

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

    return $app;        
}

      

Pay attention to the line $app->register('Path\To\Your\PackageServiceProvider');

, this is important. Include the service package provider path here, so we'll register it with our Laravel instance that lives in our folder /vendor

.



We now have a Laravel application, we need to set up an in-memory SQLite database. Simple, Laravel TestCase

has a function setUp()

that runs before the test starts to do this:

/**
 * Setup DB before each test.
 *
 * @return void  
 */
public function setUp()
{ 
    parent::setUp();

    $this->app['config']->set('database.default','sqlite'); 
    $this->app['config']->set('database.connections.sqlite.database', ':memory:');

    $this->migrate();
}

      

I won't give a big explanation as its quite readable. As you can see on the last line, we also call $this->migrate()

, which obviously does our migrations every time we run the test, giving us a new DB to test. Let's see how it works:

/**
 * run package database migrations
 *
 * @return void
 */
public function migrate()
{ 
    $fileSystem = new Filesystem;
    $classFinder = new ClassFinder;

    foreach($fileSystem->files(__DIR__ . "/../src/Migrations") as $file)
    {
        $fileSystem->requireOnce($file);
        $migrationClass = $classFinder->findClass($file);

        (new $migrationClass)->up();
    }
}

      

Without going into details, basically what we're doing here is finding the src/Migrations

package folder that requires all the files and then migrating them. Its a rough situation and requires a lot of security checks (I will do this in the future), but it works.

Why not Artisan :: call ('migrate') ??

Simple! The command is php artisan migrate --package='vendor/package'

deprecated in Laravel 5 . Developers are now expected to create their own commands to create and move migration files to the desired location in the application. This is a much more flexible approach.

+7


source


While this question already has an accepted answer, I highly recommend using orchestra / testbench .

Add this package to require-dev

your package section composer.json

and remember to extend the testing class from that package TestCase

as described in the README.



This package is capable of loading custom service providers, registering custom aliases, etc., and creating a complete Laravel testing environment.

+7


source







All Articles