所有早期的答案都是旧的,现在它是直接用_before方法完成的,该方法将Actor类作为参数。
<?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)
{
}
}
如果您只想为所有CEST文件登录一次,则可以使用全局注册表类实现注册表设计模式(请参阅 https://dzone.com/articles/practical-php-patterns/basic/practical-php-patterns-0)以及一些延迟加载。以下是我在Actor类中定义的api集成测试的工作代码(在我的例子中是ApiTester):
public function amLoggedInAs($userLogin)
{
$I = $this;
if (Registry::getInstance()->exists($userLogin)) {
// get data from registry
$storedUserData = Registry::getInstance()->get($userLogin);
$newAccessToken = $storedUserData['accessToken'];
$playerId = $storedUserData['playerId'];
}
else {
// no registry data - log in and save data in registry
$I->tryToLogin($userLogin);
$newAccessToken = $I->grabDataFromResponseByJsonPath('data.newToken');
$playerId = (int)$I->grabDataFromResponseByJsonPath('data.userId');
Registry::getInstance()->set($userLogin, [
'accessToken' => $newAccessToken,
'playerId' => $playerId
]);
}
// finally set headers and some other data
$I->haveHttpHeader('X-Token', $newAccessToken);
$I->havePlayerId($playerId);
}
protected function tryToLogin($userLogin)
{
$I = $this;
$I->wantTo('login into api');
$I->amGoingTo('try to log to API using login and password');
$I->sendPOST('/system/login', ['login' => $userLogin, 'password' => self::getPassword($userLogin)]);
// ...some other checking if user was correctly logged in ...
}
此代码基本上在用户首次登录后将 accessToken 以及一些其他数据存储在注册表中。如果调用对$I->amLoggedInAs('kgkg')的另一个调用,它将从注册表中获取这些值。您可以通过这种方式拥有许多已登录的用户,每个用户每个套件仅记录一次。
您可以使用另一种方法进行自动化,而不是自定义令牌,逻辑仍将相同。
此外,如果您使用的是WebDriver(不是PhpBrowser),则可以使用loadSessionSnapshot和saveSessionSnapshot而不是Registry来获得完全相同的结果。