(Codeception + Symfony2) セキュアなページに対するFunctional Test
How to simulate Authentication with a Token in a Functional Test (current) - Symfony に書かれている内容をCodeceptionではどのように実現するか。
1. 専用のHelperを書く
<?php namespace Codeception\Module; // here you can define custom functions for TestGuy use Symfony\Component\BrowserKit\Client; use Symfony\Component\BrowserKit\Cookie; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; class TestHelper extends \Codeception\Module { public function amLoggedInAs($username) { $client = $this->getModule('Symfony2')->client; $container = $client->getContainer(); $doctrine = $container->get('doctrine'); $user = $doctrine ->getRepository('VendorSampleBundle:User') ->findOneBy(['username' => $username]); $firewall = 'secured_area'; $token = new UsernamePasswordToken($user, null, $firewall, $user->getRoles()); $session = $container->get('session'); $session->set('_security_' . $firewall, serialize($token)); $session->save(); $cookie = new Cookie($session->getName(), $session->getId()); $client->getCookieJar()->set($cookie); } }
2. GuyをBuildする
bin/codecept build
3. Helperを使う
<?php $I = new TestGuy($scenario); $I->wantToTest('secured area.'); $I->amOnPage('/'); $I->see('Hello Guest!!'); $I->amLoggedInAs('Mike'); $I->amOnPage('/'); $I->see('Hello Mike!!');
備考
上記の解決策は、OAuth認証などアプリ側に認証用のフォームが用意されていない場合や、少しでもテストを早く実行させたい場合に有効になると思います。
テスト対象のアプリがログイン用のフォームを提供している場合は、基本的にはFunctional Testsで説明されている以下のコードのように記述すれば良いです。
<?php $I = new TestGuy($scenario); $I->amOnPage('/'); $I->click('Login'); $I->fillField('Username','Miles'); $I->fillField('Password','Davis'); $I->click('Enter'); $I->see('Hello, Miles', 'h1'); ?>
ログイン処理がテストの中で頻繁に必要となる場合は、再利用性を高める仕組みである StepObject が1.6.4から導入されています。
以上です