TravisCIでLaravel用パッケージを複数のLaravelバージョンで自動テストする

# 概要
Testing Laravel Package Against Multiple Laravel Versions.  
Laravel用のパッケージを開発する際に、Travisを利用して複数のLaravelバージョンでテストを回すための設定ファイル.travis.yml について。

（検索のワードが良くないのか、イマイチ日本語の情報が出てこなかったので残しておく。）



## 主要な目的
- Laravel用パッケージに対する自動テストをTravisで回す  ※Laravel本体を使ったアプリケーションのテストではなく、パッケージのテストである点に注意 
- php、Laravelの各バージョンを組み合わせてのテストを回す ※本稿ではPHP7.2～7.4、Laravel6～8を対象とする
 
## 結論
```yaml
language: php
matrix:
  include:
    - php: '7.2'
      env: 'ORCHESTRA_VERSION=4.*'
    - php: '7.2'
      env: 'ORCHESTRA_VERSION=5.*'
    - php: '7.3'
      env: 'ORCHESTRA_VERSION=6.*'
    - php: '7.4'
      env: 'ORCHESTRA_VERSION=6.*'

install:
  - 'composer config github-oauth.github.com ${GH_TOKEN};'
  - 'composer remove --dev --no-update orchestra/testbench'
  - 'composer require --dev --prefer-dist --no-interaction orchestra/testbench $ORCHESTRA_VERSION'
  - 'composer install'

script: 'vendor/bin/phpunit'
```

# 本論
## orchestral/testbench のバージョンについて

Laravel用パッケージのテストについては、[https://github.com/orchestral/testbench](https://github.com/orchestral/testbench) の利用がスタンダードであるので、これを利用する。まず、Laravel5.5以降のバージョンとorchestral/testbenchバージョンの対応について整理する。

| orchestral/testbench | Laravel | PHP   | 備考                                                         |
| :------------------- | :------ | :---- | :----------------------------------------------------------- |
| 3.5                  | 5.5     | 7.0   |                                                              |
| 3.6                  | 5.6     | 7.1   |                                                              |
| 3.7                  | 5.7     | 7.1   |                                                              |
| 3.8                  | 5.8     | 7.1   |                                                              |
| 3.9                  | 6.0     | 7.2   |                                                              |
| 4.0                  | 6.0     | 7.2   | Laravelが6系からセマンティックバージョンを採用したためと思われる |
| 4.*                  | 6.*     | 7.2   |                                                              |
| 5.*                  | 7.*     | 7.2.5 | Laravel7系はPHP7.2.5以上                                     |
| 6.*                  | 8.*     | 7.3   |                                                              |
| 7.*                  | 9.*     | 8.0   | testbench、Laravelともにdev（2021-08-01現在）                |

Travisのテスト設定は、上記に基づいて考えていけばよい。

## 複数バージョンテストのためのcomposer.json
Travisのためにcomposer.json を色々といじりまわすのは面倒なので、とりあえずrequire-dev の項目のバージョン指定を曖昧（*）にしておく。

```json
    "require-dev": {
        "phpunit/phpunit": "*",
        "mockery/mockery": "*",
        "vimeo/psalm": "*",
        "infection/infection": "*",
        "maglnet/composer-require-checker": "*",
        "slevomat/coding-standard": "*",
        "squizlabs/php_codesniffer": "*",
        "jakub-onderka/php-parallel-lint": "*",
        "orchestra/testbench": "*",
        "phpmetrics/phpmetrics": "*",
        "pdepend/pdepend": "*"
    },
```

こんな感じ。これで、基本的にはビルドした環境で使えるものが入るはず。

## 複数バージョンテストのための.travis.yml

バージョン対応表に基づいて、使用するPHPバージョン、testbenchのバージョンを設定ファイルに書いていく。下記の要領。

```yaml
matrix:
  include:
    - php: '7.2'
      env: 'ORCHESTRA_VERSION=4.*'
    - php: '7.2'
      env: 'ORCHESTRA_VERSION=5.*'
    - php: '7.3'
      env: 'ORCHESTRA_VERSION=6.*'
    - php: '7.4'
      env: 'ORCHESTRA_VERSION=6.*'
```

次に、リポジトリに同梱してあるcomposer.jsonの内容をテストのために必要最低限だけ書き換える。  

今回は、orchestra/testbench のバージョンだけ明示的にコントロールしたいので  

```yaml
install:
  - 'composer remove --dev --no-update orchestra/testbench'
  - 'composer require --dev --prefer-dist --no-interaction orchestra/testbench $ORCHESTRA_VERSION'
  - 'composer install'
```

こんな感じ。composer.json に書いてある orchestra/testbench を一旦削除して、明示的にバージョンを指定する。  

最後に、composerでinstallした、ビルド環境にあっているphpunitを叩く必要があるので、

```yaml
script: 'vendor/bin/phpunit'
```

こう。

### 所感

.travis.yml については、試行錯誤しながら実施したら結構すんなり行けた。過去に、複数のPHPバージョンでテストを回したことがある人なら、特に困る箇所は無いだろうと思う。

TravisCIの画面から環境変数追加できるの知らなかった・・・  
めちゃ便利やん

### トラブルシューティング

発生したトラブルとしては主に以下の3点。

- おそい（PHP7.2以下の環境だとビルドが遅い。）

  =>未解決、しょうがない気がする

- Laravel5系で、テストが失敗する（App::makePartial() が定義されていない、というエラー）

  =>一応解決（Laravel5系は対応バージョンから外した）

- composer require 時にgithubから怒られる（Could not authenticate against github.com ）

  =>解決（personal token 使いましょう）





# 参考URL 
Laravel Package Development: Testing Against Multiple Laravel Versions
https://medium.com/homesteading-like-an-artisan/laravel-package-development-testing-against-multiple-laravel-versions-3485cb5762e2

Testing Laravel packages for backward compatibility using Travis
https://medium.com/@remi_collin/testing-laravel-packages-for-backward-compatibility-using-travis-cabc3210e120

orchestral / testbench
https://github.com/orchestral/testbench

Github auth token on TravisCI
https://blog.wyrihaximus.net/2015/09/github-auth-token-on-travis/

api-rate-limit-and-oauth-tokens
https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens