KAROUSHI -Japanese Engineer Blog-

コボルドからドラゴンへ -Kobold to Dragon-

システムエンジニアのブログです。サイト名は「雑魚キャラからボスキャラへレベルアップしたい!」という思いを込めて命名しました。自分はやっとリザードマンになったくらいです。

CodeceptionのRESTでsetCookieを実行したい

CodeceptionのRESTでsetCookieをしようとするとsetCookieがないというエラーがでる。こんな感じ。

  [RuntimeException] Call to undefined method ApiTester::setCookie  

よくよく公式サイトを調べてみると、確かにRESTはsetCookieメソッドが存在しない。
REST - Codeception - Documentation

でもRESTでCookieを設定するテストがあるため、どうにかできないか悩んでアレコレやっていたらHelperに自作メソッドを作るしかない!という感じになりました。
が、、、、これも日本語のサイトでドンピシャな内容が全然ないため、すっごい悩んでたら今さっきやっと解決したので載せておきます。

目次

RESTでsetCookieを呼び出す方法

前提

プロジェクト名: api

yamlにHelperを記述

yamlファイルに以下のようににHelperを記述する。(プロジェクト生成時にデフォルトで記載されている)
このHeplerにsetCookieメソッドを作成する。

$ vim tests/api.suite.yml
actor: ApiTester
modules:
    enabled:
        - REST:
            url: http://localhost/
            depends: PhpBrowser
            part: Json
        - \Helper\Api

setCookieメソッドを作成

setCookieメソッドも1から作る必要はありません。getModule()を使えば他モジュールのメソッドを呼び出すことができるようになります。あとはPhpBrowserのものを同じメソッド名でラッパーするだけです。

$ vim tests/support/Helper/Api.php
<?php
namespace Helper;

// here you can define custom actions
// all public methods declared in helper class will be available in $I

class Api extends \Codeception\Module
{
  function setCookie($name, $value) {
    $this->getModule('PhpBrowser')->setCookie($name, $value);
  }
}

クッキーをセットしてGET送信

今回実行する受け入れテストは以下のようなもの。

$ vim tests/api/SampleTestCept.php
<?php
$I = new ApiTester($scenario);
$I->wantTo('perform actions and see result');
$I->setCookie('sessionid', 'el4ukv0kqbvoirg7nkp4dncpk3');
$I->sendGET('/');
$I->seeResponseCodeIs(200);

debugモードで実行してリクエストの中身を確認してみます。

$ php codecept run api --debug
・・・中略・・・
SampleTestCept: Perform actions and see result
Signature: SampleTestCept
Test: tests/api/SampleTestCept.php
Scenario --
 I set cookie "sessionid","el4ukv0kqbvoirg7nkp4dncpk3"
  [Cookie Jar] ["sessionid=el4ukv0kqbvoirg7nkp4dncpk3; path=/; httponly"]
 I send get "/"
・・・中略・・・

念のためnginxのログも事前にログフォーマットで"sessionid"のCookieを表示するように設定しておき、ちゃんと受信できているか確認してみます。
nginxのコンフィグ設定はこんな感じ。

$ sudo vim /etc/nginx/nginx.conf
http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$cookie_sessionid"';

    access_log  /var/log/nginx/access.log  main;

ログを確認結果。

$ sudo tail /var/log/nginx/access.log 
127.0.0.1 - - [14/Feb/2018:16:37:44 +0000] "GET // HTTP/1.1" 200 3770 "-" "Symfony BrowserKit" "-" "el4ukv0kqbvoirg7nkp4dncpk3"