首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用Laravel dusk只迁移一次

使用Laravel dusk只迁移一次
EN

Stack Overflow用户
提问于 2017-02-01 20:58:55
回答 3查看 3.1K关注 0票数 6

根据to the "Database Testing" documentation,我可以在每次测试后重置数据库(第一个选项)。第二种选择是使用事务运行测试。对我来说,这似乎是一种更好的方法,但如果我想使用事务运行,迁移就不会运行。

有没有办法在所有测试过程中运行一次迁移?

换句话说,我想运行迁移,使用transaction运行每个测试,然后回滚。我尝试了文档中所说的内容,但我认为缺少了一些东西。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-02-07 06:36:49

今天,这个问题已经争论了一段时间,结合迁移运行迁移似乎可以做到这一点。我的测试快照如下:

代码语言:javascript
复制
<?php

namespace Tests\Browser;

use App\User;
use Tests\DuskTestCase;

use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class DefaultTest extends DuskTestCase
{
    use DatabaseMigrations, DatabaseTransactions;

    /**
     * A Dusk test example.
     *
     * @return void
     */
    public function test_something()
    {
        //Add test stuff here
    }
}

在我的实际测试中,我有几个工厂,它们似乎在迁移过程中运行,数据在测试后被销毁,正如预期的那样。

票数 2
EN

Stack Overflow用户

发布于 2017-06-23 16:58:03

据我所知,我认为事务在使用dusk时是不会工作的,因为dusk中的每个浏览器请求都会创建一个单独的laravel应用程序实例。

以前,phpunit会在内存中创建一个新的应用程序(在setUp / createApplication方法中),然后对该测试应用程序进行测试,然后销毁它并设置下一个应用程序。因此,在为下一个测试启动新的数据库连接之前,可以将事务包装在该应用程序的创建和销毁部分中(或仅在其中)。

对于dusk,它是真正的端到端测试(包括浏览器、伪造的用户交互、本地机器上的路由等),这意味着它并不像通常在phpunit中那样包含在运行测试的环境中。

Dusk执行以下操作:

  • 复制您的.env.dusk.*并启动chromedriver (或您使用的任何类似selenium的东西)
  • 触发phpunit shell命令(即。新命令,新进程)
  • phpunit命令运行您的dusk测试,每个测试打开一个浏览器窗口并发出请求(每个请求启动一个新的php-fpm和php进程(对于nginx)) -就像您自己发出这些请求一样。它们中的每一个都有到数据库的单独连接,因此不能与彼此的transactions.

交互

还值得注意的是,DatabaseTransactions特征在基础包中,而不是黄昏包中,因此它的构建/打包并不是考虑到黄昏。

这也解释了为什么内存中的sqlite不能与dusk一起工作,因为一个进程不能访问另一个进程的内存。

票数 1
EN

Stack Overflow用户

发布于 2019-03-01 04:11:25

这里的是一种非常可移植和可重用的方式:

代码语言:javascript
复制
abstract class DuskTestCase extends BaseTestCase {

   ...

    /**
     * @param int $batchCounter
     * @param string $className
     * @param int $threshold
     */
    public function refreshDb(&$batchCounter, $className = '', $threshold = 0) {
        if ($batchCounter <= $threshold) {
            //TODO: Here is where you'll want to run migrations and seeds and whatnot.
            $batchCounter++;
            $this->consoleOutput(trim($className . ' called refreshAndSeedTestingDb and $batchCounter++. $batchCounter=' . $batchCounter));
        }
    }

   /**
    * @param string $msg
    */
   public function consoleOutput($msg) {
       Log::debug($msg);
       $output = new \Symfony\Component\Console\Output\ConsoleOutput();
       $output->writeln($msg);
   }

然后在每个测试文件中:

代码语言:javascript
复制
class ExampleBrowserTest extends DuskTestCase {

    protected static $countDbRefreshed = 0;

    public function setUp() {//runs before every test function in this class
        parent::setUp();
        $this->refreshDb(self::$countDbRefreshed, __CLASS__); //inside uses a property to run only once per class
    }
...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41980432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档