我开始使用 Laravel Dusk 进行浏览器测试,并创建了几个测试来测试我的登录表单。我有以下代码:
class LoginTest extends DuskTestCase
{
public function testLogin()
{
$this->browse(function (Browser $browser) {
$browser->visit('/admin')
->type('email', '[email protected]')
->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', '[email protected]')
->type('password', 'somefakepasswordthatdoesntwork')
->press('Login')
->assertSee('These credentials do not match our records.');
});
}
看评论。第一个函数运行良好,但是当涉及第二个函数时,我必须先注销,因为运行第一个函数后用户已经登录。这让我感到惊讶,因为我认为单元测试是完全独立的,会话数据会自动销毁。
有没有更好的方法来做到这一点 - 也许我缺少一些 Dusk 方法 - 而不是必须调用
$browser->visit('/admin/logout');
?
谢谢
编辑感谢到目前为止的两个答案,这两个答案似乎都是有效的解决方案。我已将第二个函数更新为以下内容:
public function testLoginFailure(){
$this->createBrowsersFor(function(Browser $browser){
$browser->visit('/admin')
->type('email', '[email protected]')
->type('password', 'somefakepasswordthatdoesntwork')
->press('Login')
->assertSee('These credentials do not match our records.');
});
}
这可以完成工作。所以
就我而言,
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。
您可以使用
tearDown()
方法刷新会话:
class LoginTest extends DuskTestCase
{
// Your tests
public function tearDown()
{
session()->flush();
parent::tearDown();
}
}
如果您只想注销已登录的用户,在登录测试后,只需使用:
$browser->visit('/login')
->loginAs(\App\User::find(1))
...
some assertions
...
->logout();
您可以使用
tearDown
方法清除所有cookie。以下是这样做的示例,您可以在 DuskTestCase.php 文件中添加此方法
public function tearDown()
{
parent::tearDown();
$this->browse(function (Browser $browser) {
$browser->driver->manage()->deleteAllCookies();
});
}
我不确定这是否是您正在寻找的答案,但您可以创建多个浏览器来执行需要干净历史记录/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
});
}
您可以拨打电话
$this->logout();
InteractsWithAuthentication - Github
编辑:
这是 Dusk 测试用例的行为,主浏览器实例保留用于其他测试。
第二种解决方案,创建第二个浏览器实例,该实例将在单次测试后销毁
您可以在
setUp
实例上将 logout
方法与 Dusk 的 Browser
方法配对:
/**
* Log the user out before each test.
*
* @return void
*/
protected function setUp(): void
{
parent::setUp();
$this->browse(
fn (Browser $browser) => $browser->logout()
);
}
如果您只想注销当前用户,您可以通过以下方式实现
$this->browse(function($browser) {
$browser->visit('/logout')
->waitForText('Sign Into Your Account');
});
注意:请将“登录您的帐户”更改为登录页面上显示的文本。