所有早期的答案都是旧的,现在它直接在 _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 文件登录一次,您可以使用实现 Registry 设计模式的全局 Registry 类(参见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 来获得完全相同的结果。