LaravelでのUnitテストざっくり入門

- Windows 10
- PHP 7.4.5
- Laravel Framework 7.9.2
- 10.4.11-MariaDB

参照：https://readouble.com/laravel/7.x/ja/testing.html


## テスト実行
プロジェクトフォルダで

```powershell
.\vendor\bin\phpunit
```
もしくは

```powershell
php artisan test
```

実行結果
Laravelインストール時のサンプルテストケースが実行される

```powershell
PHPUnit 8.5.4 by Sebastian Bergmann and contributors.

..                                                                  2 / 2 (100%)

Time: 424 ms, Memory: 24.00 MB

OK (2 tests, 2 assertions)
```

`php artisan test`実行時は、更に詳細なレポートが表示される

## テストケースクラス作成
**※テストケースのクラス名は、Testで終わらないと実行されない場合があります。**

Featureテスト
実際の通信を伴う機能テスト

```powershell
php artisan make:test [テストケースクラス名]
```
Unitテスト
PHPクラス単位の単体テスト

```powershell
php artisan make:test [テストケースクラス名] --unit
```

## テストケース作成
テストケース（関数）の名前は**`test`**で始める

```php:tests/Feature/ExampleTest 
<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
     * @return void
     */
    public function testBasicTest()
    {
        $response = $this->get('/');
        $response->assertStatus(200);
    }
}
```
**`@test`**を付けると関数名にtestをつけなくてもいい

```php:tests/Feature/ExampleTest 
    /**
     * @return void
     * @test
     */
    public function create_success()
    {
        $response = $this->get('/api/card/create');
        $response->assertStatus(200);
    }
```
日本語でも大丈夫

```php:tests/Feature/ExampleTest 
    /**
     * @return void
     * @test
     */
    public function 作成()
    {
        $response = $this->get('/api/card/create');
        $response->assertStatus(200);
    }
}
```

## データベースでのテスト


### 設定
1. テスト用のデータベースを作成する
2. .envをコピーして.env.testingを作成
3. .env.testingのデータベース設定をテスト用にする
4. .env.testing用のマイグレーション`php .\artisan migrate --env=testing`
5. phpunit.xmlの設定変更

```xml:phpunit.xml
        <server name="DB_CONNECTION" value="mysql"/>
        <server name="DB_DATABASE" value="[データベース名]"/>
```

### テストケース

`use RefreshDatabase;`を付けるとテストが終わったあとにデータを全部消してくれます

```php:tests/Feature/ExampleTest 
<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Card;
use App\UserToken;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

    /**
     * @test
     */
    public function insert_success()
    {
        $card = new Card();
        $card->name = "TestName";
        $result = $card->save();
        $this->assertTrue($result);
    }
}
```
データベースを使ったテストは、**`Tests\TestCase`**を継承したテストケースのクラスで実行できます。Featureで作成したテストケースのクラスは最初から**`Tests\TestCase`**を継承して作成されています。Unitテストにてデータベースのテストをする場合は、継承元のTestCaseを変更します。

```diff
-use PHPUnit\Framework\TestCase;
+use Tests\TestCase;

class ExampleUnitTest extends TestCase
```

## Factory と Faker

FactoryとFakerを使って、テスト用のダミーデータを楽に生成します

### Factoryの生成

```powershell
php artisan make:factory [ファクトリ名] --model=[対象のモデル名]
例）
php artisan make:factory CardFactory --model=Card
```
### Fakerを使ってデータ生成


Factoryを編集して、どのデータにどのようなダミーデータを入れるか指定します。
[Fakerの説明](https://github.com/fzaninotto/Faker)

```php:database/factories/CardFactory.php
<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Card;
use Faker\Generator as Faker;

$factory->define(Card::class, function (Faker $faker) {
    return [
        'name' => $faker->name(),
        'uuid' => $faker->uuid(),
        'user_id' => $faker->randomDigit(),
        'address' => $faker->address()
    ];
});

```
テストケースで、Factoryを使ってダミーデータ作成します

```php:tests/Feature/ExampleTest 
    /**
     * @test
     */
    public function insert_success()
    {
        $cards = factory(Card::class, 3)->create();
        $count = count($cards);
        $this->assertEquals(3, $count);
    }
```

app/config.phpに以下の設定をしておくと生成されるダミーデータが日本語になります。設定しないと英語です。

```php:config/app.php
'faker_locale' => 'ja_JP',
```