资讯专栏INFORMATION COLUMN

Laravel数据库测试的另一种方案-SQLite

rottengeek / 1775人阅读

摘要:数据库测试在测试方面,内置使用提供了非常方便的解决方案。方案优缺点该方案关键点在于使用内置的一个内存数据库,因此速度比较快,有很好的隔离性,也不会对我们的开发数据库有任何的影响。

Laravel数据库测试

在测试方面,Laravel内置使用PHPUnit提供了非常方便的解决方案。而对于数据库增删改查的测试,要解决的一个很重要的问题就是如何在测试完成之后,恢复数据库的原貌,例如要测试一个用户注册的方法,需要插入一条用户记录到数据库,但是测试完成之后,我们并不想让这条测试用例保存在数据库里。为了解决这个问题,Laravel提供了非常方便的方案:

使用迁移:DatabaseMigrations

使用事务:DatabaseTransactions

参考资料:https://laravel.com/docs/5.3/database-testing#resetting-the-database-after-each-test
另外一种解决方案:使用SQLite的内存数据库:memory:

Laravel提供的两种解决方案,仍然对数据库进行了读写操作,某些时候你可能并不想这样(例如多人共享一个线上开发数据库),此时,还可以用一种更为优雅的方式:SQLlite,逻辑其实也非常简单:就是在跑测试用例的时候,将数据库的连接替换为SQLite

使用示例

例如我们有以下测试类(该事例并不具有代表性,仅用于说明问题,并假设本机已经安装SQLite):

class HomePageTest extends TestCase {
    
    public function testHomePage() 
    {
        // 创建一个测试用户,并保存
        $user = factory(AppUser::class)->create();
        $this->actingAs($user)->visit("/home")->see("Dashboard");
    }
}

首先在Laravel的数据库配置文件,即config/database.phpconnections数组中添加一个新的数据库连接

"sqlite" => [
    "driver" => "sqlite",
    "database" => ":memory:",
    "prefix" => "",
],

这里一个非常重要的参数就是"database" => ":memory:":memory:数据库是SQLite中内置的一个内存数据库,每次运行测试用例的时候都会在内存中创建一个新的数据库,并在测试完成关闭数据库连接后,自动清除掉,具有良好的隔离性,又因为是在内存中的,所以速度也很快,这些特性对于测试非常方便,这也是我们选用SQLite数据库作为测试库的一个非常重要的原因。有关详细解释,点击这里。

然后需要修改PHPUnit的配置文件,在phpunit.xml中,将数据库连接改为刚刚定义的SQLite连接


    
    
    
    
    
    
    

这会覆盖.env中定义的数据库连接DB_CONNECTION=mysql,并告诉框架在运行测试的时候,用sqlite连接代替mysql连接。

最后需要在运行测试用例之前执行数据库迁移,在测试类的基类,即TestCase.php中添加setUp方法

public function setUp()
{
    parent::setUp();
    // 执行数据库迁移 
    $this->artisan("migrate");
}

这样在每次执行测试用例之前,都会向SQLite:memory:数据库中执行所有的迁移,生成业务逻辑所需的数据表。

方案优缺点

该方案关键点在于使用SQLite内置的一个内存数据库:memory:,因此速度比较快,有很好的隔离性,也不会对我们的开发数据库有任何的影响。

当然该方案也有缺点,假如项目的数据库庞大,有大量的数据表或者迁移文件,会消耗大量内存,当运行测试的时候可能会由于内存不足,导致测试中断。此时需要为PHP分配合适的内存,在php.ini中修改配置memory_limit = 128M

参考资料

https://laravel.com/docs/5.3/database-testing#resetting-the-database-after-each-test

http://blog.mauriziobonani.com/laravel-sql-memory-database-for-unit-tests/

https://www.sqlite.org/inmemorydb.html

https://laracasts.com/discuss/channels/testing/how-to-specify-a-testing-database-in-laravel-5

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/29038.html

相关文章

  • Laravel5.5新特性--邮件模板可以在浏览器中渲染

    摘要:正在开发的另一种测试方法是将电子邮件呈现给浏览器,以便您可以进行快速更改并获得几乎即时的反馈。 这个是即将在Laravel5.5中发布的新特性 当您构建自定义HTML电子邮件模板时,通常会对所有电子邮件客户端进行测试,并一并测试通常是一件麻烦事。有几个像Litmus这样的工具可以帮助解决这个问题,但服务是昂贵的。 正在开发的另一种测试方法是将电子邮件呈现给浏览器,以便您可以进行快速更改...

    worldligang 评论0 收藏0
  • PHPUnit 加速技巧分享

    摘要:接下来我们将会介绍一些可以快速实现的小技巧,让你的代码测试变得更快。该示例测试套件有意地模拟更广泛的测试集合,并突出改进的可行性。真实情况下,效率的提升可能有所差异。我认为相比通过提升一点速度带来的好处,保持生产环境一致更重要。 showImg(https://segmentfault.com/img/remote/1460000017962057?w=1440&h=736); 具备高...

    weizx 评论0 收藏0
  • 看吧,这就是现代化 PHP 该有的样子

    摘要:这大概是我没有及早使用,或多数开发者流连现状造成的。它就是,一个的框架。行为驱动开发是来自测试驱动开发的开发过程。简单的说,它就是经常可能一天几次将小块代码整合进基础代码当中的行为。 showImg(https://segmentfault.com/img/remote/1460000013769815); 这是一篇社区协同翻译的文章,已完成翻译,更多信息请点击 协同翻译介绍 。 文章...

    Tangpj 评论0 收藏0
  • 深入浅出 Laravel 的 Facade 外观系统

    摘要:外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。将使用者与子系统从直接耦合,转变成由外观类提供统一的接口给使用者使用,以降低客户端与子系统之间的耦合度。接下来将深入分析外观服务的加载过程。引导程序将在处理请求是完成引导启动。 本文首发于 深入浅出 Laravel 的 Facade 外观系统,转载请注明出处。 今天我们将学习 Laravel 核心架构中的另一个主题「Fac...

    KavenFan 评论0 收藏0
  • 13 个快速构建 Laravel 后台的扩展包

    摘要:值得一提的是扩展包不免费用于商业用途,作者用一种人类友好的方式说你使用这个扩展包就是应该去挣钱的,而不是免费的去工作这个扩展包收费美元。除了这些,还有五个没有全面的审查的扩展包。最后,还有三个优质的包选择于。 showImg(https://segmentfault.com/img/remote/1460000012312105?w=2200&h=1125); 开发者们都是懒惰的,不,...

    MiracleWong 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<