LaravelでHTTPテスト


#環境
Laravel : 5.5.4

#参考URL
[Testing: Getting Started](https://laravel.com/docs/5.5/testing)
[HTTP Tests](https://laravel.com/docs/5.5/http-tests)

#設定ファイル
テストを行う際に本番DBを触らないようにテスト用のDBを見るようにします。
通常DB設定は`.env`ファイルに記述すると思うのですが
テスト用のDB設定としてLaravelプロジェクト直下に`.env.testing`ファイルを作成すると、テストの際はそちらを見るようになります。

> You may also create a .env.testing file. This file will override values from the .env file when running PHPUnit tests or executing Artisan commands with the --env=testing option.

[Environment Configuration](https://laravel.com/docs/5.5/configuration#environment-configuration)

##APP_ENVに関して
>When running tests via phpunit, Laravel will automatically set the configuration environment to  testing because of the environment variables defined in the phpunit.xml file. Laravel also automatically configures the session and cache to the array driver while testing, meaning no session or cache data will be persisted while testing.

参考URL
[Creating & Running Tests](https://laravel.com/docs/5.5/testing#environment)

env.testingはphpunitがAPP_ENVをtestingにするようなので、testingにしなくても大丈夫らしいです。

##DB_DATABASE
本番用のDBを触らないようにテスト用のDBを作成した上でテストDB名を記述します


#HTTPテストファイルを作成
参考URL
[Creating & Running Tests](https://laravel.com/docs/5.5/testing#creating-and-running-tests)

今回はHTTPテストを行うので

```
// Create a test in the Feature directory...
$ php artisan make:test Test1
```

上記を実行すると
`Laravelプロジェクト/tests/Feature`の配下に`Test1.php`というファイルができます。

#テストコード
##Database Migration trait
前にメモとして以下でも少し書いたのですが、
[Laravel DuskでDBデータが飛んだって話(メモ)](https://qiita.com/Frog_woman/items/6f3581809a38dfe655e4)

Laravelのデータベースマイグレーションのトレイトとして`DatabaseTransactions`と`DatabaseMigrations`があり、Laravel5.5から`RefreshDatabase`が追加され

RefreshDatabaseを使うことでテスト前に`Migration`と`Seeder`が実行され、
`テスト後にはテーブルのみが残ってmigrationsテーブル以外の挿入データは削除されている状態`になってました。

正直この辺はあまり理解していないのですが
Laravel5.5公式の方には`DatabaseMigrations`の記述しかなく、
テスト作成コマンドで作成されるテンプレにもDatabaseMigrationsのみが書かれているので
これからは`DatabaseMigrations`を使っていくのが正しいのかなって感じです

```
use Illuminate\Foundation\Testing\RefreshDatabase;

class Test1 extends TestCase
{
    use RefreshDatabase;
```

##軽いサンプル
[Available Assertions](https://laravel.com/docs/5.5/http-tests#available-assertions)
軽い感じのテストサンプルを書いておこうと思います

###注意 visit()は使えない
代わりにget()を使用

参考URL
[Laravel5.5: 単体テストの例](https://qiita.com/sutara79/items/81cf687588c00df0f847#余談-visitメソッドはlaravel53まで)

###URLテスト
```
$response = $this->get('/');
$response->assertSuccessful();
```

###異常系のテスト。エラーになるか
```
$response = $this->get('/test')
          ->assertStatus(404);
```

###リダイレクトテスト
```
$response = $this->get('/user')
			->assertRedirect('/login');
```

###認証を利用
`factory`でユーザデータを作成し、`actingAs()`を利用することでそのユーザデータで認証済み状態にし、通常ログイン状態でないと遷移できないページのテストを行えます。

また、`actingAs`の第2引数に認証用でどのguardを使うか指定することができます。
>You may also specify which guard should be used to authenticate the given user by passing the guard name as the second argument to the actingAs method:

>`$this->actingAs($user, 'api')`
[Session / Authentication](https://laravel.com/docs/5.5/http-tests#session-and-authentication)

デフォルトのguardだと省略できます。

guardに関しての参考URL
[ユーザー認証（１０）Laravel 5.2 マルチ認証](http://www.larajapan.com/2016/01/18/ユーザー認証（１０）laravel-5-2-マルチ認証/)

>config/auth.php
>
>	/* 認証のガードを定義 */                                                  
>	'guards' => [
>	    'web' => [
>	        'driver' => 'session',
>	        'provider' => 'users',
>	    ],
>	 
>	'api' => [
>				'driver' => 'token',
>				'provider' => 'users',
>		    ],
>	],


上記を踏まえて

```
//ユーザの作成・認証
$user     = factory(User::class)->create();
$response = $this->actingAs($user);

//マイページトップ
$response -> get('/mypage')
         ->assertSuccessful();

//会員用ニュースページ
$response -> get('/mypage/news')
          ->assertSuccessful();
```

###新規データを作成して利用
例として、新規ニュースを作成し、作成したニュースのidを取得し、遷移チェックをする
assertSuccessful()ばかり使ってたので今回はassertSee('テキスト')でチェックするページに`テキスト`存在するかassertさせてみます

```
use App\User;
use App\News;

(省略)

$data = [
    'title'       => 'テストタイトル',
    'date'        => new Carbon()
];

//ニュース
$news = News::create($data);

$response -> get('/mypage/news/'.$news->id)
            ->assertSee('会員用ニュース');
```


#実行
実行方法ですが、[公式](https://laravel.com/docs/5.5/http-tests)にも特に書いておらず
[](https://laravel.com/docs/5.5/structure#the-root-directory)
Laravelプロジェクト配下に移動し

```
vendor/bin/phpunit
```

ファイルを指定してテストを行いたい場合は

```
vendor/bin/phpunit tests/Feature/Test1.php
```

---

何かしら間違い等がありましたらコメントして下さると助かります