在 laravel 包中设置集成测试

Setting up Integration tests in a laravel package

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

对于集成测试,我需要访问 Laravel 环境,以便我可以访问诸如 Artisan::call('migrate') 之类的内容并访问数据库。

目前我猜我需要有任何测试扩展 Laravel TestCase 类,引导 Laravel 环境。虽然我不知道如何将这个文件调用到我的包中。

其次,在 workbench 中开发软件包时,我需要使用 Artisan::call('migrate', '--bench="vendor/package"') 还是 Artisan::call ('migrate', '--package="vendor/package"') 这令人困惑。

我们需要创建 Laravel 的实例,以及 PHPUnit 可以访问的数据库 运行 针对真实世界数据集的测试。不是脆弱的嘲笑。首先,出于多种原因,您应该独立开发包,其中一个原因是 workbench 现在已在 Laravel 5.

中弃用

所以首先我们需要dev-require Laravel 框架到我们的项目中:

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

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

如果我们扩展本机 Laravel 测试 class Illuminate\Foundation\Testing\TestCase 一些工作已经为我们完成了。我们只需要创建一个 returns 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 应用程序 运行ning,我们需要设置内存中的 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' 已被弃用。开发人员现在需要创建自己的命令来生成迁移文件并将其移动到应用程序中的适当位置。这是一种更加灵活的方法。

虽然这个问题已经有了公认的答案,但我强烈建议使用 orchestra/testbench 包。

将此包添加到您的包 composer.jsonrequire-dev 部分,并确保按照 README 中的描述从该包的 TestCase 扩展任何测试 class。

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