CakePHP3は公式サイトでテストケースの作成について紹介されています。
そこで認証が必要なページのテストケースについては記述方法が書かれていますが、ログインやログアウトといった処理自体のテストケースについて記載されていないので、今回作ってみます。
前提
クイックスタートガイドに従い作られた以下のような認証処理であること。
- Usersはemailカラムをログイン名、passwordカラムをパスワードとする
- パスワードはCakePHP3のデフォルトのbcryptでハッシュ化される
- Usersはemail、password以外にid、created、modifiedカラムを持つ
- ログイン/ログアウトメソッドはUsersControllerに作成される
また、テストに従い、PHPUnitの実行ができるようになっていること(PHPUnitのインストール、DBの設定等)。
テストデータの作成
UsersFixtureの編集
クイックスタートガイドに従ってbake all users
を実行していればtests\Fixture\UsersFixture.php
というファイルが存在していると思います。
そのファイルの下のほうにある$recodesを以下のように編集し、テストに使用するデータを定義します。
public $records = [
[
'id' => 1,
'email' => 'test_user',
'password' => '$2y$10$RDuyVB6AjZBb1eEa0Strwu8raIniMx1rhX5Mdl3KSAvfLw7SGBaHG',
'created' => '2017-05-21 05:39:51',
'modified' => '2017-05-21 05:39:51'
],
];
今回は、ユーザー名をtest_user、パスワードをpasswordとしました。
passwordカラムの値はpasswordをbcryptでハッシュ化した後の値です。
テストケース作成
テストケースはTestCase\Controller\UsersControllerTest.php
に作成されます。
以下では各テストケースのメソッドだけを示すので、Testファイルに追加してください。
表示処理
表示確認はステータスとLoginという文字列が含まれているかどうかを確認しています。
public function testLogin()
{
$this->get('/users/login');
$this->assertResponseOk(); //ステータスが200系である
$this->assertResponseContains('Login'); //ボディにLoginという文字列が含まれている
}
ログイン処理(正常系)
ログイン処理(正常系)のテストでは、DBに登録されているユーザー情報でログイン処理を実行させ、その結果としてセッションにログインユーザーの情報が格納されることを確認します。
use Cake\I18n\FrozenTime; //FrozenTimeを使用する(クラス外で宣言)
public function testLoginOk()
{
// ログイン処理の実行
$this->post('/users/login', [
'name' => 'test_user',
'password' => 'password'
]);
// ログイン後のユーザー情報(パスワード以外)
$user = [
'id' => 1,
'name' => 'test_user',
'created' => new FrozenTime('2017-05-21 05:39:51'),
'modified' => new FrozenTime('2017-05-21 05:39:51')
];
// セッションのユーザー情報と比較
$this->assertSession($user, 'Auth.User');
}
DATETIME型のカラムはCakePHPではFrozenTime型のオブジェクトになります。
また、ログイン後にセッションに登録されるユーザー情報にはセキュリティ上パスワードの情報が含まれないのでそれ以外のカラムの値を設定し、assertSessionメソッドで比較します。
ログイン処理(異常系)
ログイン処理(異常系)の処理では、DBに登録されていないデータを使ってログイン処理を行います。
ログインが失敗した場合はセッションのAuth.Userはnullになります。
また、リダイレクトしないことも確認します。
public function testLoginFail()
{
// ログイン処理の実行
$this->post('/users/login', [
'name' => 'wrong-test_user',
'password' => 'wrong-password'
]);
$this->assertNull($this->_requestSession->read('Auth.User')); // セッションのユーザー情報がNULL
$this->assertNoRedirect(); //リダイレクトしない
}
ログアウト処理
ログアウトの処理では、先にセッションにユーザー情報を設定してからログアウト処理を実行します。
ログアウト処理実行後にセッションのユーザー情報がNULLになっていればログアウトが成功しています。
public function testLogout() {
// セッションにユーザー情報を設定
$this->session([
'Auth' => [
'User' => [
'id' => 1,
'name' => 'test_user',
'created' => new FrozenTime('2017-05-21 05:39:51'),
'modified' => new FrozenTime('2017-05-21 05:39:51')
]
]
]);
$this->get('/users/logout'); // ログアウトの実行
$this->assertNull($this->_requestSession->read('Auth.User')); // セッションのユーザー情報がNULL
}
テストの実行
PHPUnitを実行して、各メソッドで.(テスト成功)が出ていればOKです。
UsersControllerTestデフォルトのテストメソッドが残ってる場合、いくつかIが出ると思います($this->markTestIncompleteを使っているため)