Laravel Dusk,如何破坏测试之间的会话数据

时间:2017-07-04 13:01:37

标签: php laravel unit-testing laravel-dusk

我开始使用Laravel Dusk进行浏览器测试,并创建了几个测试来测试我的登录表单。我有以下代码:

class LoginTest extends DuskTestCase
{

public function testLogin()
{
    $this->browse(function (Browser $browser) {
        $browser->visit('/admin')
            ->type('email', 'inigo@mydomain.co.uk')
            ->type('password', 'MyPass')
            ->press('Login')
            ->assertSee('Loading...');
    });
}

public function testLoginFailure(){
    $this->browse(function (Browser $browser){

        $browser->visit('/admin/logout'); // I have to add this to logout first, otherwise it's already logged in for this test!

        $browser->visit('/admin')
            ->type('email', 'someemail@afakedomain.com')
            ->type('password', 'somefakepasswordthatdoesntwork')
            ->press('Login')
            ->assertSee('These credentials do not match our records.');
    });
}

查看评论。第一个函数运行正常,但是当涉及第二个函数时,我必须先注销,因为用户已经因运行第一个函数而登录。这让我感到意外,因为我认为单元测试完全独立,会话数据会自动销毁。

有没有一种更好的方法可以做到这一点 - 我可能缺少一些黄昏方法 - 而不是打电话给$browser->visit('/admin/logout');

由于

编辑感谢目前为止的2个答案,这两个答案似乎都是有效的解决方案。我已将第二个函数更新为以下内容:

public function testLoginFailure(){
    $this->createBrowsersFor(function(Browser $browser){
        $browser->visit('/admin')
            ->type('email', 'someshit@afakedomain.com')
            ->type('password', 'somefakepasswordthatdoesntwork')
            ->press('Login')
            ->assertSee('These credentials do not match our records.');
    });
}

这项工作是做什么的。所以

  1. 我可以放心地假设第二个浏览器仅在此单个函数的持续时间内存在,对吗?
  2. 创建第二个浏览器实例而不是使用拆解方法有哪些明显的优点/缺点?

7 个答案:

答案 0 :(得分:8)

就我而言,tearDown()还不够,出于某种原因,记录的用户仍然在测试之间保留,因此我将deleteAllCookies()放在了setUp()

所以,在我的 DuskTestCase.php 中我添加了:

/**
 * Temporal solution for cleaning up session
 */
protected function setUp()
{
    parent::setUp();
    foreach (static::$browsers as $browser) {
        $browser->driver->manage()->deleteAllCookies();
    }
}

这是我可以在所有测试中刷新会话的唯一方法。我希望它有所帮助。

注意:我使用的是Homestead和Windows 10。

答案 1 :(得分:5)

您可以使用tearDown()方法刷新会话:

class LoginTest extends DuskTestCase
{
    // Your tests

    public function tearDown()
    {
        session()->flush();

        parent::tearDown();
    }
}

答案 2 :(得分:5)

如果您只想注销登录用户,请在登录测试后使用:

 $browser->visit('/login')
     ->loginAs(\App\User::find(1))
     ...
     some assertions
     ...
     ->logout();

答案 3 :(得分:3)

你可以打电话

$this->logout();

InteractsWithAuthentication - Github

修改

这是Dusk Test案例的行为,主浏览器实例仍然用于其他测试。

第二个解决方案,创建第二个浏览器实例,在单次测试后将销毁该实例

See Dusk/TestCase #L103

答案 4 :(得分:3)

如果有助于其他人的话。您可以使用tearDown方法清除所有Cookie。以下是这样做的示例,您可以在DuskTestCase.php文件中添加此方法

public function tearDown()
{
    parent::tearDown();

    $this->browse(function (Browser $browser) {
        $browser->driver->manage()->deleteAllCookies();
    });
}

我希望这会有所帮助。

答案 5 :(得分:2)

我不确定您是否正在寻找答案,但您可以创建多个浏览器来执行需要干净历史记录/ Cookie /缓存的测试。

例如,如果您有许多测试用户应该登录并且您不想只注册一个检查重置密码表单的测试,那么您可以为这个确切的案例创建一个额外的浏览器,移动到下一个测试时切换到上一个浏览器。

看起来可能是下一个方式:

public function testfirstTest()
{
  $this->browse(function ($browser) {
    //some actions where you login etc
  });
}

public function testSecondTestWhereYouNeedToBeLoggedOut()
{
  $this->browse(function ($currentBrowser, $newBrowser) {
  //here the new browser will be created, at the same time your previous browser window won't be closed, but history/cookies/cache will be empty for the newly created browser window
    $newBrowser->visit('/admin')
    //do some actions
    $newBrowser->quit();//here you close this window
  });
}

public function testWhereYouShouldContinueWorkingWithUserLoggedIn()
{
  $this->browse(function ($browser) {
    $browser->doSomething()//here all actions will be performed in the initially opened browser with user logged in
  });
}

答案 6 :(得分:0)

如果您只想注销当前用户,则可以这样做

     $this->browse(function($browser) {
        $browser->visit('/logout')
                ->waitForText('Sign Into Your Account');
    });

注意:请通过登录页面上显示的文本更改“登录到您的帐户”文本。