Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Codeception:保持登录状态_Php_Selenium_Codeception - Fatal编程技术网

Php Codeception:保持登录状态

Php Codeception:保持登录状态,php,selenium,codeception,Php,Selenium,Codeception,我想在大多数测试之前保留或运行登录。但是如果我试图在登录代码失效之前将其移动到_,因为我没有可用的webguy实例 在多个测试之间保持会话的最佳方式是什么?这是我到目前为止的代码,希望能得到一些帮助。我在谷歌上搜索并查看了文档,但我找不到任何关于会话内容的信息 <?php use \WebGuy; class ProductCest { private $product_id = '1'; public function _before() { }

我想在大多数测试之前保留或运行登录。但是如果我试图在登录代码失效之前将其移动到_,因为我没有可用的webguy实例


在多个测试之间保持会话的最佳方式是什么?这是我到目前为止的代码,希望能得到一些帮助。我在谷歌上搜索并查看了文档,但我找不到任何关于会话内容的信息

<?php
use \WebGuy;

class ProductCest
{

    private $product_id = '1';

    public function _before()
    {
    }

    public function _after()
    {
    }

    // tests
    public function login(WebGuy $I) {
        $I->seeInCurrentUrl('/auth/login');
        $I->fillField("//input[@type='email']", "username@email.com");
        $I->fillField("//input[@type='password']", "1234");
        $I->click('#signIn .submit');
        $I->wait(500);

        $I->seeInCurrentUrl('/account');
    }

    /**
     * @depends login
     */
    public function chooseProduct(WebGuy $I) {
        $I->wantTo('go to products and choose one');
        $I->amOnPage('/?product=' . $this->client_id);
    }

}

我认为@Sinisa的答案是“有效的”,但不是“正确的”

您想要的不是@depends注释,而是@before

区别在于使用@depends不保留当前上下文,而在保留上下文之前使用@before

public function foo(WebGuy $I)
{
    $I->amOnPage('/foobar');
}

/**
 * @depends foo
 */
public function bar(WebGuy $I)
{
    $I->seeInCurrentUrl('foobar'); // Wil fail
}

/**
 * @before foo
 */
public function baz(WebGuy $I)
{
    $I->seeInCurrentUrl('foobar'); // Will pass
}

我认为公认的答案是实现它的一种方式,但不是最好的。要做到这一点,当您只需要共享用户会话时,您将始终必须重复登录系统的所有步骤。我认为抓取会话cookie并通过所需的用户日志测试会更好。为此,您需要创建一个登录函数,获取cookie,并使您的测试首先依赖于登录测试:

<?php
use \AcceptanceTester;

class testingCest
{
    private $cookie = null;

    public function _before(AcceptanceTester $I)
    {
    }

    public function _after(AcceptanceTester $I)
    {
    }


    // tests
    public function login(AcceptanceTester $I)
    {
        $I->wantTo('entrar al sistema');
        $I->amOnPage('/');
        $I->seeInCurrentUrl('/admin/login');
        $I->fillField('user','perry');
        $I->fillField('pass','pass-perry');
        $I->click('Login');
        $I->see('You\'re logged!');
        $this->cookie   = $I->grabCookie('your-session-cookie-name');
    }

    /**
     * @depends login
     */
    public function listUsers(AcceptanceTester $I)
    {
        $I->setCookie( 'your-session-cookie-name', $this->cookie );
        $I->amOnPage('/admin/users');
        $I->seeInCurrentUrl('/admin/users/1');
    }

    /**
     * @depends login
     */
    public function listRols(AcceptanceTester $I)
    {
        $I->setCookie( 'your-session-cookie-name', $this->cookie );
        $I->amOnPage('/admin/rols');
        $I->seeInCurrentUrl('/admin/rols/1');
    }
}

所有早期的答案都是旧的,现在它直接在以Actor类为参数的_-before方法中完成

<?php

namespace Test\Api;

use ApiTester;

class TrainingCest
{
    public function _before(ApiTester $I)
    {
        $I->amLoggedInAs('kgkg');
    }

    public function _after(ApiTester $I)
    {
    }

    // tests
    public function testForLoggedInUser(ApiTester $I)
    {
    }

    public function anotherTestForLoggedInUser(ApiTester $I)
    {
    }

}
这段代码基本上是在用户首次登录后将accessToken和一些附加数据存储在注册表中。如果调用了另一个对$I->amLoggedInAs('kgkg')的调用,它将从注册表获取这些值。通过这种方式,您可以拥有许多已登录的用户,每个用户在每个套件中只登录一次

您可以使用另一种方法进行自动化,而不是自定义标记,逻辑仍然相同


如果您使用的是WebDriver(不是PhpBrowser),也可以使用loadSessionSnapshot和saveSessionSnapshot而不是Registry来获得完全相同的结果

需要注意的是,如果您正在测试WordPress,WP浏览器模块有“sugar”登录方法:

loginAsAdmin();
loginAs($username, $password);

现在Codeception通过和loadSessionSnapshot方法解决了这一问题

<?php
// inside AcceptanceTester class:

public function login()
{
     // if snapshot exists - skipping login
     if ($I->loadSessionSnapshot('login')) return;

     // logging in
     $I->amOnPage('/login');
     $I->fillField('name', 'jon');
     $I->fillField('password', '123345');
     $I->click('Login');

     // saving snapshot
     $I->saveSessionSnapshot('login');
}
?>

请记住,如果使用SaveSessionSnapshot,则必须确保在登录完成后调用该函数。这意味着,如果您的登录需要一些时间(ldap登录或安全检查),则会在登录完成之前执行SaveSessionSnapshot,并保存一个空会话。
如果是这样,你必须告诉你的程序等待($I->wait()),或者检查登录是否完成。

在2021年,在我的情况下,只需在.yml文件中将
清除cookies
设置为false

Codeception在测试之间删除Cookie,因为作为最佳实践,您应该在测试之间保持登录

但如果要持久化cookie,只需声明以下内容:

actor: AcceptanceTester
modules:
    enabled:
        - WebDriver:
              clear_cookies: false

在多个测试之间保持会话的最佳方法-你是说像谷歌一样吗?你想在两个站点之间保持会话a的活动吗?或者请提供更多详细信息以了解更多信息。测试的目的是每次都尝试所有步骤。这是说,您的网络人员需要在每次运行测试时登录,正如@sinisa valentic的答案所示。谢谢,我尝试过做类似于您在这里演示的事情,但我以前失败了。有没有办法跳过第一个executeLogin,让它只在被其他方法调用时运行?我真的不需要它作为测试运行:)如果不需要登录,您只需不调用execute login方法即可。使用此代码,您可以在任何时候与登录的用户检查页面时始终执行所有登录步骤,这可能会非常慢。我更喜欢共享会话cookie,只使用@depends运行测试(参见下面的答案)。是的,有更好的方法,例如:我认为这应该是可以接受的答案,因为它更快。这更简单。谢谢。现在,我有很多不同的概念-我如何在多个概念上共享一个登录?我对每一个“财产”都有一个概念,以及大约40个可以管理的不同财产。这意味着,如果我运行完整的套件,我还必须登录40次。@RobQuist,您可以修改登录并将cookie存储在会话变量中,在执行整个登录之前,将对该会话变量进行检查。如果有var,只需跳过登录,如果没有,则转到登录。然后,您应该在不同的cept之间共享login方法:要么创建父类,要么在类中使用trait()和login方法;你介意看一看吗?Codeception中的全局注册表类是什么?它不是Codeception的一部分。我的意思是注册表类实现注册表设计模式。看见感谢您指出这一点-更新了我的答案。现在,简单地将yml文件中的clear_Cookie设置为false似乎是一个难题,但在我的情况下,只有通过参数
$I->login($I)
感谢上帝,这个答案在这个框架中失去了希望。。默认情况下不维护意外会话信息。。这应该是某个yml文件中的一个选项
<?php
// inside AcceptanceTester class:

public function login()
{
     // if snapshot exists - skipping login
     if ($I->loadSessionSnapshot('login')) return;

     // logging in
     $I->amOnPage('/login');
     $I->fillField('name', 'jon');
     $I->fillField('password', '123345');
     $I->click('Login');

     // saving snapshot
     $I->saveSessionSnapshot('login');
}
?>
public function _before(AcceptanceTester $I)
{
    $I->login();
}
actor: AcceptanceTester
modules:
    enabled:
        - WebDriver:
              clear_cookies: false