在laravel包中设置集成测试

时间:2015-01-03 20:40:31

标签: php laravel phpunit package integration-testing

目前正努力在我正在撰写的软件包中设置集成测试。

对于集成测试,我需要访问Laravel环境,这样我就可以访问Artisan :: call('migrate')等内容并访问数据库。

目前我猜我需要进行任何测试扩展Laravel TestCase类,引导Laravel环境。虽然我无法锻炼如何将这个文件调用到我的包中。

其次,在工作台中开发包时,我需要使用Artisan :: call('migrate',' - bench =“vendor / package”')或Artisan :: call('migrate',' - package = “vendor / package”')这令人困惑。

2 个答案:

答案 0 :(得分:8)

我们需要创建一个Laravel实例,以及一个PHPUnit可以访问的数据库来运行针对实际数据集的测试。不脆弱的嘲笑。首先,您应该单独开发包,原因有很多,其中一个工作台现在已在Laravel 5中弃用。

首先,我们需要将dev-require Laravel框架纳入我们的项目:

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

现在我们可以创建一个名为DbTestCase的抽象类,我们所有的测试都将从中扩展。在这个类中,我们将启动一个Laravel实例和一个 in memory SQLite数据库以提高速度。

如果我们扩展原生Laravel测试类Illuminate\Foundation\Testing\TestCase,我们已经完成了一些工作。我们只需要创建一个返回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;        
}

注意第$app->register('Path\To\Your\PackageServiceProvider');行这很重要。在此处包含您的包服务提供者路径,因此我们将其注册到我们的包/vendor文件夹中的Laravel实例。

现在我们运行了一个Laravel应用程序,我们需要设置内存中的SQLite数据库。很简单,Laravel的TestCase有一个setUp()函数在运行之前运行,让我们在那里执行:

/**
 * 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();
}

由于其可读性,我不会给出太多解释。正如您在最后一行所看到的那样,我们也调用了$this->migrate(),这显然会在每次运行测试时运行我们的迁移,从而为我们提供一个新的数据库来进行测试。让我们看看它是如何工作的:

/**
 * 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();
    }
}

不要过多详细说明,基本上我们在这里做的是查看需要所有文件的包的src/Migrations文件夹,然后运行他们的迁移。它粗糙,需要更多的安全检查(我将在未来这样做),但它的确有效。

为什么不是Artisan :: call(' migrate')??

简单!在Laravel 5中,命令php artisan migrate --package='vendor/package'已被弃用。现在,开发人员需要创建自己的命令,以生成迁移文件并将其移动到应用程序中的适当位置。这是一种更灵活的方法。

答案 1 :(得分:7)

虽然这个问题已经得到了答案,但我强烈建议您使用orchestra/testbench包。

将此软件包添加到软件包require-dev的{​​{1}}部分,并确保从此软件包composer.json中扩展任何测试类,如自述。

此软件包能够加载自定义服务提供程序,注册自定义别名等,同时启动完整的Laravel环境进行测试。