简体   繁体   English

在laravel包中设置集成测试

[英]Setting up Integration tests in a laravel package

Currently struggling to setup integration tests within a package I'm writing. 目前正努力在我正在编写的包中设置集成测试。

For the integrations tests I will need to have access to a Laravel environment so I can access things such as Artisan::call('migrate') and access the database. 对于集成测试,我需要访问Laravel环境,以便我可以访问诸如Artisan :: call('migrate')之类的东西并访问数据库。

Currently I'm guessing I need to have any tests extend the Laravel TestCase class, bootstrapping a Laravel environment. 目前我猜我需要进行任何测试扩展Laravel TestCase类,引导Laravel环境。 Although I cannot workout how I can call this file into my package. 虽然我无法锻炼如何将这个文件调用到我的包中。

Secondly while developing packages in workbench would I need to use Artisan::call('migrate', '--bench="vendor/package"') or Artisan::call('migrate', '--package="vendor/package"') this is confusing. 其次,在工作台中开发包时,我需要使用Artisan :: call('migrate',' - bench =“vendor / package”')或Artisan :: call('migrate',' - package =“vendor /包“')这令人困惑。

We need to create an instance of Laravel, along with a database that PHPUnit can access to run the tests against real-world data sets. 我们需要创建一个Laravel实例,以及PHPUnit可以访问的数据库,以针对实际数据集运行测试。 Not brittle mocks. 不脆弱的嘲笑。 Firstly you should be developing your packages in isolation for a number of reasons, one being workbench is now deprecated in Laravel 5. 首先,您应该单独开发包,原因有很多,其中一个工作台现在已在Laravel 5中弃用。

So firstly we need to dev-require the Laravel framework into our project: 首先,我们需要dev-require Laravel框架到我们的项目中:

"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 called DbTestCase that all our tests will extend from. 现在我们可以创建一个名为DbTestCase的抽象类,我们所有的测试都将从中扩展。 Within this class we will be spinning up an instance of Laravel and an in memory SQLite database for speed. 在这个类中,我们将启动一个Laravel实例和一个内存 SQLite数据库以提高速度。

If we extend the native Laravel test class Illuminate\\Foundation\\Testing\\TestCase some of the work has already been done for us. 如果我们扩展原生Laravel测试类Illuminate\\Foundation\\Testing\\TestCase ,我们已经完成了一些工作。 We simple need to create a method that returns an instance of Illuminate\\Foundation\\Application . 我们只需要创建一个返回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;        
}

notice the line $app->register('Path\\To\\Your\\PackageServiceProvider'); 注意$app->register('Path\\To\\Your\\PackageServiceProvider'); this is important. 这个很重要。 Include your package service provider path here, so we register it with our Laravel instance that lives in our packages /vendor folder. 在此处包含您的包服务提供者路径,因此我们将其注册到我们的packages /vendor文件夹中的Laravel实例。

Now we have a Laravel application running, we need to setup the in-memory SQLite database. 现在我们运行了一个Laravel应用程序,我们需要设置内存中的SQLite数据库。 Simple, Laravel's TestCase has a setUp() function that is run before ever test, lets do it there: 简单来说,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();
}

I won't give to much explanation as its quite readable. 我不会给出太多解释,因为它非常易读。 As you can see on the last line we are also calling $this->migrate() which obviously runs our migrations each time we run a test giving us a fresh DB to test against. 正如你在最后一行所看到的那样,我们也在调用$this->migrate() ,这显然会在每次运行测试时运行我们的迁移,从而为我们提供一个新的DB来测试。 Lets look at how that 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();
    }
}

Not to go into too much detail, basically what we are doing here is looking into the src/Migrations folder of the package requiring all the files and then running their migrations. 不要过多细节,基本上我们在这里做的是查看需要所有文件然后运行其迁移的包的src/Migrations文件夹。 Its rough and needs more safety checks (i will do that in the future) but it works. 它粗糙,需要更多的安全检查(我将在未来这样做),但它的工作原理。

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

Simple! 简单! In Laravel 5 the command php artisan migrate --package='vendor/package' has been deprecated. 在Laravel 5中,命令php artisan migrate --package='vendor/package'已被弃用。 Developers are now expected to create their own commands to generate and move migration files to the proper location in the application. 现在,开发人员需要创建自己的命令,以生成迁移文件并将其移动到应用程序中的适当位置。 This is a much more flexible approach. 这是一种更灵活的方法。

Although this question already has an accepted answer, I strongly recommend to use the orchestra/testbench package. 虽然这个问题已经得到了答案,但我强烈建议使用orchestra / testbench软件包。

Add this package in the require-dev section of your package's composer.json and make sure to extend any test class from this package's TestCase as described in the README. 在包的composer.jsonrequire-dev部分添加此包,并确保从README中描述的此包的TestCase扩展任何测试类。

This package is able to load custom Service Providers, register custom aliases, etc. while spinning up a complete Laravel environment for testing. 该软件包能够加载自定义服务提供程序,注册自定义别名等,同时启动完整的Laravel环境进行测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM