NIJIBOX

入社して2ヶ月の超初心者が、Laravelテストでつまずいた点を話します

更新日 2019.11.13
入社して2ヶ月の超初心者が、Laravelテストでつまずいた点を話します

Laravelテスト記事のサムネイル画像
[markdown]
こんにちは!
ニジボックスに7月末より入社している@tadoumaです。

エンジニアになって2ヶ月、テストを書き出して1ヶ月半、
超初心者の私がLaravelテストを書いてつまずいた点を書いてみます。

こんなの知ってるよ!となるかもしれませんが、、

温かい目で見守ってください。

自己紹介

・エンジニアになって2ヶ月の超初心者(文系出身で、プログラミングに触れた経験ほぼなし)
・前職は営業
・もちろんテスト書くのも初めて
・猫が好き

それでは、早速まとめてみようと思います!

目次

1.assertSee/assertDontSee
2.リダイレクト後のテスト
3.フィールド名の変更とテストの書き方
4.テスト名とアノテーション
5.Factory、RefreshDatabase、IDオートインクリメント
6.最後に

それでは、1つずつ見ていきましょう!

1.assertSee/assertDontSee

“`
php:AssertSee.php
$res = $this->get(“url”);
$res->assertStatus(200)
->assertDontSee(‘ネコちゃん’);
“`

仕様変更に伴い、このテストが通らなくなりました。

状況

・変更前
    if文で分岐し、条件Aに当てはまるユーザーには「ネコちゃん」を表示。
    上記のテストでは、条件Aに当てはまらないユーザーの時、
    「ネコちゃん」が出ないことを確認していた。

・変更後
    if文ではない箇所で、「ネコちゃん」という文面が追加された。
    そのため、どんな条件のユーザーでも「ネコちゃん」が出るようになった。

どうにかして、if文で出し分けている方の「ネコちゃん」だけが
見えていないことを確認したい。
ただ、

`assertDontSee(‘ネコちゃん’)` にすると、通らない。

解決策

“`php:AssertSeeResolve.php
$res = $this->get(“url”);
$res->assertStatus(“200”)
->assertDontSee(‘

  • ネコちゃん
  • ‘)
    ->assertSee(‘ネコちゃん’);
    “`

    if文の方の「ネコちゃん」は、liタグに囲まれているため、
    これを含めて`assertDontSee`で調べると、うまくいきました!

    なぜ?

    下記はテストを実行し、エラーが出てきた画面。
    if文で出し分けているほうが、`

  • ネコちゃん
  • `です。

    “`

    ネコちゃん\n

  • ネコちゃん
  • \n

    \n
    “`

    Laravelドキュメントを見ると、`assertSee`や`assertDontSee`の定義は、
    「指定したテキストが、ページ上に存在することを宣言します。」と書いてあります。

    ページ上に存在する というのが何を表しているのか分からなかったのですが、
    どうやらレスポンスとして返ってきたHTMLソースを見ているようでした。
    そのため、タグを含めて調べるとうまくいきました。

    ちなみに・・・

    上記のような場面以外でも、
    例えば想定結果が「1」の時、`assertSee(“1”)`なんかやっても
    「1」なんかどこにでもありますよね。

    そういった場合は下記のように、表示されている前後の文字列も含めて書いてあげると、
    正確な`AssertSee/assertDontSee`ができます。

    “`php:AssertSeeResolve.php
    //$hogeNumberはある処理の結果。今回は1の想定
    $res = $this->get(“url”);
    $res->assertSee(“結果は”.$hogeNumber.”件です”);
    “`

    2.リダイレクト後のテスト

    バリデーションエラーの文言がきちんと出ているか調べるため、
    リダイレクト後に`assertSee`が効いているか見ようとしました。
    最初に書いたコードがこちら。

    “`php:RedirectTest.php
    $res->assertRedirect(‘url’)
    ->assertSee(“内容を入力してください。”);
    “`

    これを実行すると、下記のようにエラーが返ってきました。

    “`
    Failed asserting that ‘\n
    \n
    \n
    \n
    \n
    \n
    Redirecting to http://url\n
    \n
    \n
    Redirecting to http://url.\n
    \n
    ‘ contains “内容を入力してください。”.
    “`
    ↓かなり省略して書くと、
    `Failed asserting that ‘(ここにレスポンス)’contains “内容を入力してください。”.`
    =つまり、レスポンスの中に「内容を入力してください。」という文字が入っていない、と言っています。

    何が返っているのか?

    なぜ上記だとできないのか。
    リダイレクト処理では何が返ってくるのか、が鍵になります。

    リダイレクトとはつまり・・・
    >HTTPヘッダにあるHTTPステータスコードにてリダイレクトの種類を伝え、Location:ヘッダで移動先を伝える

    というもの。
    つまり、リダイレクトして直接“`assertSee“`しても、
    リダイレクトのレスポンス(≒移動先を伝えているところ)しか見ていない、ということになります。

    解決策

    “`php:RedirectTestResolve.php
    $res = $this->post(‘url’,[‘content’ => ”]);
    $res->assertRedirect(‘url2’);
    $this->get(‘url2’)
    ->assertSee(“内容を入力してください。”);
    “`

    こうすれば、リダイレクト後にgetしていることになるので、
    バリデーション文言がしっかり取れます!

    3.フィールド名の変更とテストの書き方

    “`php:FieldName.php
    $res = $this->post(‘url’, [
    ‘content’ => ‘ニャ〜〜〜ン’,
    ]);
    $this->assertEquals(“1”, Hoge::count());
    “`
    上記は、postした内容がきちんとDBに反映されているか見ているテストです。
    ある時、フィールド名を変更したところ、上記がエラーになってしまいました。

    フィールド名の変更は下記の通りです。

    変更前

    “`