根据to the "Database Testing" documentation,我可以在每次测试后重置数据库(第一个选项)。第二种选择是使用事务运行测试。对我来说,这似乎是一种更好的方法,但如果我想使用事务运行,迁移就不会运行。
有没有办法在所有测试过程中运行一次迁移?
换句话说,我想运行迁移,使用transaction运行每个测试,然后回滚。我尝试了文档中所说的内容,但我认为缺少了一些东西。
发布于 2017-02-07 06:36:49
今天,这个问题已经争论了一段时间,结合迁移运行迁移似乎可以做到这一点。我的测试快照如下:
<?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
}
}
在我的实际测试中,我有几个工厂,它们似乎在迁移过程中运行,数据在测试后被销毁,正如预期的那样。
发布于 2017-06-23 16:58:03
据我所知,我认为事务在使用dusk时是不会工作的,因为dusk中的每个浏览器请求都会创建一个单独的laravel应用程序实例。
以前,phpunit会在内存中创建一个新的应用程序(在setUp
/ createApplication
方法中),然后对该测试应用程序进行测试,然后销毁它并设置下一个应用程序。因此,在为下一个测试启动新的数据库连接之前,可以将事务包装在该应用程序的创建和销毁部分中(或仅在其中)。
对于dusk,它是真正的端到端测试(包括浏览器、伪造的用户交互、本地机器上的路由等),这意味着它并不像通常在phpunit中那样包含在运行测试的环境中。
Dusk执行以下操作:
.env.dusk.*
并启动chromedriver (或您使用的任何类似selenium的东西)交互
还值得注意的是,DatabaseTransactions
特征在基础包中,而不是黄昏包中,因此它的构建/打包并不是考虑到黄昏。
这也解释了为什么内存中的sqlite不能与dusk一起工作,因为一个进程不能访问另一个进程的内存。
发布于 2019-03-01 04:11:25
这里的是一种非常可移植和可重用的方式:
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);
}
然后在每个测试文件中:
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
}
...
https://stackoverflow.com/questions/41980432
复制相似问题