17

我开始使用 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.');
    });
}

见评论。第一个函数运行良好,但是当涉及到第二个函数时,我必须先注销,因为运行第一个函数后用户已经登录。这让我感到惊讶,因为我认为单元测试是完全独立的,会话数据会自动销毁。

有没有更好的方法来做到这一点 - 一些我可能错过的 Dusk 方法 - 而不是必须调用$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. 创建第二个浏览器实例而不是使用拆卸方法有哪些明显的优点/缺点?
4

7 回答 7

22

就我而言,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。

于 2018-03-23T13:49:04.950 回答
10

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

 $browser->visit('/login')
     ->loginAs(\App\User::find(1))
     ...
     some assertions
     ...
     ->logout();
于 2018-02-01T11:20:32.537 回答
8

您可以在方法中刷新会话tearDown()

class LoginTest extends DuskTestCase
{
    // Your tests

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

        parent::tearDown();
    }
}
于 2017-07-04T13:30:42.053 回答
6

如果万一它帮助别人。您可以使用tearDown方法清除所有 cookie。以下是这样做的示例,您可以在 DuskTestCase.php 文件中添加此方法

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

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

我希望这将有所帮助。

于 2018-01-13T05:44:09.103 回答
4

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

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

它可能看起来像下一个方式:

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
  });
}
于 2018-05-11T13:05:53.173 回答
4

你可以打电话

$this->logout();

InteractsWithAuthentication - Github

编辑:

这是 Dusk 测试用例的行为,主浏览器实例保留用于其他测试。

第二种方案,创建第二个浏览器实例,单次测试后销毁

见 Dusk/TestCase #L103

于 2017-07-04T13:14:07.910 回答
0

如果您只对注销当前用户感兴趣,您可以通过这样做来实现

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

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

于 2020-12-01T07:02:29.520 回答