laravelで初めるgitlab-ciを用いた開発

Share on:

ここではより実践的な例としてlaravelを用いたテストを行います。あんまりlaravelの詳細は語りません。多少わかってる方向け

前提

php 7.4でやっています。composerがシステムに入っていたりします。

php-xmlが必要なようです。まあ、あとt2.microだと厳しいかも。

最低限これだけあればなんとかなると思います。

プロジェクトの展開

gitlabで適当な名前のプロジェクトをしてcloneしときます。laravel-ciとか、まあ適当にどうぞ。

clone後cdしときます。

laravelの展開

1% composer create-project --prefer-dist laravel/laravel tmp

カレントディレクトリに展開できないため、とりあえず適当なディレクトリを指定する。バージョンを指定しない場合はシステムに最適な最新版を落としてくれる(と思う)

今回はlaravel8.10.0になりました。ヒエッ。

とりあえずtmpから全部移動して最初のcommitとします。

1% mv tmp/* .
2% mv tmp/.* . 
3% rmdir tmp  
4% git add .
5% git commit -m "initial commit"   
6% git push

起動してみる

1% php artisan serve --host=0.0.0.0 

とかでport 8000に接続できるはず。なお、テストではサーバは必要ないので確認できたら落としておきます。ver8は大分変わったみたいっすね^^;

テストしてみる

特に何も設定せずとも単純な機能テストがtests/に入っていたりします。あとphpunitがvendor/bin/phpunitに存在してたりしており、またそれ用の設定がphpunit.xmlとして構成されています。即ち

1% ./vendor/bin/phpunit                         
2PHPUnit 9.4.1 by Sebastian Bergmann and contributors.
3
4..                                                                  2 / 2 (100%)
5
6Time: 00:00.084, Memory: 20.00 MB
7
8OK (2 tests, 2 assertions)

とかいう具合にtestできます(何も解説していないので、何やってるかよくわからないとはいえ、とにかくテストできます)

artisan経由でのtestもあり、こちらは出力がちょっと違ってくるんですが、基本的にはそれほどやってる事は変わらないんじゃないかなーと思っています。

 1% php artisan test  
 2
 3   PASS  Tests\Unit\ExampleTest
 4  ✓ basic test
 5
 6   PASS  Tests\Feature\ExampleTest
 7  ✓ basic test
 8
 9  Tests:  2 passed
10  Time:   0.15s

こっちの方が若干可読性がよいか?

CIのセットアップ

(001.png)

(002.png)

(003.png)

結構いたれりつくせりな感じだ。が、DBの設定とかがあるので、これは現状では必要ない所とかあります。とりあえずひたすらコメントアウトしていきます。

1# This folder is cached between builds
2# http://docs.gitlab.com/ce/ci/yaml/README.html#cache
3cache:
4  paths:
5    - vendor/
6    - node_modules/

これは残しておく。

before_scriptの所で

 1before_script:
 2  # Update packages
 3  - apt-get update -yqq
 4  # Prep for Node
 5  - apt-get install gnupg -yqq
 6  # Upgrade to Node 8
 7  - curl -sL https://deb.nodesource.com/setup_8.x | bash -
 8  # Install dependencies
 9  - apt-get install git nodejs libcurl4-gnutls-dev libicu-dev libmcrypt-dev libvpx-dev libjpeg-dev libpng-dev libxpm-dev zlib1g-dev libfreetype6-dev libxml2-dev libexpat1-dev libbz2-dev libgmp3-dev libldap2-dev unixodbc-dev libpq-dev libsqlite3-dev libaspell-dev libsnmp-dev libpcre3-dev libtidy-dev -yqq
10  # Install php extensions
11  - docker-php-ext-install mbstring pdo_mysql curl json intl gd xml zip bz2 opcache
12  # Install & enable Xdebug for code coverage reports
13  - pecl install xdebug
14  - docker-php-ext-enable xdebug
15  # Install Composer and project dependencies.
16  - curl -sS https://getcomposer.org/installer | php
17  - php composer.phar install
18  # Install Node dependencies.
19  # comment this out if you don't have a node dependency
20  - npm install
21  # Copy over testing configuration.
22  # Don't forget to set the database config in .env.testing correctly
23  # DB_HOST=mysql
24  # DB_DATABASE=project_name
25  # DB_USERNAME=root
26  # DB_PASSWORD=secret
27  - cp .env.testing .env
28  # Run npm build
29  # comment this out if you don't have a frontend build
30  # you can change this to to your frontend building script like
31  # npm run build
32  - npm run dev
33  # Generate an application key. Re-cache.
34  - php artisan key:generate
35  - php artisan config:cache
36  # Run database migrations.
37  - php artisan migrate
38  # Run database seed
39  - php artisan db:seed

とかあるけどとりあえず全部コメントアウトする。

testの項目

 1test:
 2  script:
 3    # run laravel tests
 4    #- php vendor/bin/phpunit --coverage-text --colors=never
 5    # run frontend tests
 6    # if you have any task for testing frontend
 7    # set it in your package.json script
 8    # comment this out if you don't have a frontend test
 9    #- npm test
10    echo "ok"

これはokしか出してないのでもちろんpassします。jobsから確認できます。

チューニングしていく

yamlをpullして手元で加工していきます。とりあえずmysqlは必要ないので、before_scriptを直していきます。今回はを検査しないのでnodeとかはいれてないです。xdebugもいれていません。

.envは**.env.example**を暫定的に使っています。

以上を踏まえて以下のようなyamlとなるでしょう

 1image: php:latest
 2cache:
 3  paths:
 4    - vendor/
 5    - node_modules/
 6before_script:
 7  - apt-get update -yqq
 8  - apt-get install gnupg -yqq
 9bjpeg-dev libpng-dev libxpm-dev zlib1g-dev libfreetype6-dev libxml2-dev libexpat1-dev libbz2-dev libgmp3-dev libldap2-dev unixodbc-dev libpq-dev libsqlite3-dev libaspell-dev libsnmp-dev libpcre3-dev libtidy-dev -yqq
10  - apt-get install git libcurl4-gnutls-dev libicu-dev libmcrypt-dev libvpx-dev libjpeg-de
11v libpng-dev libxpm-dev zlib1g-dev libfreetype6-dev libxml2-dev libexpat1-dev libbz2-dev l
12ibgmp3-dev libldap2-dev unixodbc-dev libpq-dev libsqlite3-dev libaspell-dev libsnmp-dev libpcre3-dev libtidy-dev -yqq
13  - curl -sS https://getcomposer.org/installer | php
14  - php composer.phar install
15  - cp .env.example .env
16  - php artisan key:generate
17  - php artisan config:cache
18
19test:
20  script:
21    # run laravel tests
22    - php artisan test

これで普通に通過すると思います。

(004.png)

テストを失敗してみる

正直ここまでテストの内容に関しては全く振れてなかったのですが、feautureテストをあえて失敗させてみます。

tests/Feature/ExampleTest.php

1    public function testBasicTest()
2    {
3        $response = $this->get('/');
4
5        $response->assertStatus(500);
6#        $response->assertStatus(200);
7
8    }

手元でも確認しておくといいと思われます。

 1% php artisan test   
 2
 3   PASS  Tests\Unit\ExampleTest
 4  ✓ basic test
 5
 6   FAIL  Tests\Feature\ExampleTest
 7  ⨯ basic test
 8
 9  ---
10
11  • Tests\Feature\ExampleTest > basic test
12  Expected status code 500 but received 200.
13  Failed asserting that 500 is identical to 200.
14
15  at tests/Feature/ExampleTest.php:19
16     15▕     public function testBasicTest()
17     16▕     {
18     17▕         $response = $this->get('/');
19     18▕
20  ➜  19▕         $response->assertStatus(500);
21     20▕ #        $response->assertStatus(200);
22     21▕     }
23     22▕ }
24     23▕
25
26
27  Tests:  1 failed, 1 passed
28  Time:   0.24s

これをcommitします

1% git commit -a -m "add failed test"

jobを見ます

(005.png)

ある意味想定通り失敗してくれたという事になるでしょう。testは通過するように戻しておきます。

dockerを使う

CIで動いてるものがそもそもdockerなので手元にdockerがあった方がよいだろうと思われます。ここではdocker-composeと合わせて使ってみます。

docker-compose.yml

1---
2version: '3'
3
4services:
5  web:
6    build: ./docker/php
7    container_name: "laravel-ci-php"

Dockerfileを書きます docker/php/Dockerfile

1FROM php:latest

起動します。

1% docker-compose up
2...
3WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
4Creating laravel-ci-php ... done
5Attaching to laravel-ci-php
6laravel-ci-php | Interactive shell
7laravel-ci-php |
8laravel-ci-php exited with code 0

このように終了します。これはDockerの特性で「やる事だけやったら終わる」というのに基いていますが、今回はdockerの中でテストできるかどうか検証するのでこれではちょっとマズいという事になります。YAMLを改変します。

1services:
2  web:
3    build: ./docker/php
4    container_name: "laravel-ci-php"
5    tty: true

すると

1% docker-compose up  
2Recreating laravel-ci-php ... done
3Attaching to laravel-ci-php
4laravel-ci-php | Interactive shell
5laravel-ci-php |

で止まるので別のシェル?で中に侵入します

1% docker-compose exec web bash
2root@7b8e4e9b4140:/# php -v
3PHP 7.4.11 (cli) (built: Oct 13 2020 09:55:37) ( NTS )
4Copyright (c) The PHP Group
5Zend Engine v3.4.0, Copyright (c) Zend Technologies

と、こうなるわけです。これでいろいろ構成していきます。

そもそもphp:latestでいいのか問題

laravel8の場合php7.3であれば動作するというのもあり、対象のシステムに合わせたバージョンでテストしないとテストにならないというのもあります。そもそもdebian busterだったらphpは7.3.19だったりしますんで、latestじゃなくて7.3で合わせてみます。

これは単純に

1FROM php:7.3

とすればいいのですが、手元に置く場合はwebの穴も空けといた方が確認が楽なのでphp+apacheにします。もちろん、php-fpmを使ってもいいけど記事が長くなるので(別枠にします)

というわけでここまででこうなりました。

1FROM php:7.3-apache
2RUN apt update -yqq

こうした変更のある場合ばビルドしなおさないといけません。

1% docker-compose build --no-cache
2% docker-compose up

upと一緒にやる方法もある(と思った)けど、2つにわけました。

1% docker-compose exec web bash

dockerの中に入って

1root@fe7d249402ed:/var/www/html# php -v
2PHP 7.3.21 (cli) (built: Aug  6 2020 20:40:30) ( NTS )
3Copyright (c) 1997-2018 The PHP Group
4Zend Engine v3.3.21, Copyright (c) 1998-2018 Zend Technologies

バージョンが7.4から7.3に下がっている事を確認します。

また、カレントディレクトリが**/var/www/html**にセットされているのも確認できます。

1root@fe7d249402ed:/var/www/html# pwd
2/var/www/html

Dockerfileを整えていく

.gitlab-ci.ymlとよく似てるんですが違うのでそこそこ頑張って仕掛けていきます

ボリューム

現在**/var/www/html**がカレントになっているため、ここに手元のファイルをマウントします。

1services:
2  web:
3    build: ./docker/php
4    container_name: "laravel-ci-php"
5    volumes:
6      - ./:/var/www/html
7    tty: true

dockerを再起動するとファイルがみえるはずです。

1root@ad39f1d4f389:/var/www/html# ls
2README.md  composer.json  docker              public      storage
3app        composer.lock  docker-compose.yml  resources   tests
4artisan    config         package.json        routes      vendor
5bootstrap  database       phpunit.xml         server.php  webpack.mix.js

UIDの関係がちょっと面倒ですがまあこんな感じで

composer

手元の環境にcomposerを置く場合は以下のようにするといいようです

``docker FROM php:7.3-apache RUN apt update -yqq

Install composer

COPY –from=composer /usr/bin/composer /usr/bin/composer

1
2中で確認するとこうなっています
3

root@ad39f1d4f389:/var/www/html# type composer composer is /usr/bin/composer

1
2#### composerによるライブラリの設定
3

% docker-compose exec web composer install

1
2### .env
3
4これはlaravelをインストールしたての時は「作られちゃう」んですが、本来はありません。従って.env.exampleからcopyしてkeyを生成する必要があります。
5

% docker-compose exec web cp .env.example .env % docker-compose exec web php artisan key:generate

 1
 2### 外から接続してみる
 3
 4```yaml
 5services:
 6  web:
 7    build: ./docker/php
 8    container_name: "laravel-ci-php"
 9    volumes:
10      - ./:/var/www/html
11    tty: true
12    ports:
13      - 8000:80

などすると8000ポートが80番にアサインされますが、そのまま接続してもforbiddenになります。(forbiddenにならない場合(接続できないなど)はファイヤーウォールとかの設定を確認ください。AWSならセキュリティポリシーとか。

これは、もちろんなんですがapache2のデフォルトのDocumentRootが**/var/www/html**に向いてるんだけどもlaravelの場合は**/public**に向けないといけないというのがありあす。この辺のエラーログはdockerに排出されているはずです

1laravel-ci-php | [Mon Oct 19 03:01:05.737467 2020] [autoindex:error] [pid 19] [client 163.49.200.44:63429] AH01276: Cannot serve directory /var/www/html/: No matching DirectoryIndex (index.php,index.html) found, and server-generated directory index forbidden by Options directive

時間がバラバラになってるのも気になるところですが、ともあれ設定を変更します。

1<VirtualHost *:80>
2    ServerAdmin webmaster@localhost
3    DocumentRoot /var/www/html/public
4    ErrorLog ${APACHE_LOG_DIR}/error.log
5    CustomLog ${APACHE_LOG_DIR}/access.log combined
6    <Directory /var/www/html/public>
7        AllowOverride all
8    </Directory>
9</VirtualHost>

こんなファイルを用意して↑で使ったvolume機能で無理矢理当てて上書きしてしまうという方法を取ります。これはdocker/000-default.confとでもしましょうか。

すると

1The stream or file "/var/www/html/storage/logs/laravel.log" could not be opened in append mode: failed to open stream: Permission denied

こういうのが環境によって出ます。とりあえず777にすれば解決します

1% sudo chmod 777 storage -R 

ただ、mod_rewriteが効いてないのでDockerfileでmod_rewriteを効かせておくとよいでしょう。

1FROM php:7.3-apache
2RUN apt update -yqq
3
4# Install composer
5COPY --from=composer /usr/bin/composer /usr/bin/composer
6
7# enable mod_rewrite
8RUN a2enmod rewrite

ビルドし直せばうまくいくはずです。

ここまでを.gitlab-ci.ymlに反映させる

composerはまあなんというか使い捨てでいいでしょう。

apacheの部分は面倒みる必要ないのでまとめると以下になりますね。

  • composerをいれる
  • composer installする
  • .envを.env.exampleから作る
  • php artisan key:generateする

この4点です。余計なaptパッケージは一切入れてないのでシンプルに以下のようになるでしょう。

.gitlab-ci.yml

 1image: php:7.3
 2
 3cache:
 4  paths:
 5    - vendor/
 6#    - node_modules/
 7
 8before_script:
 9  # Update packages
10  - apt-get update -yqq
11  # Install Composer and project dependencies.
12  - curl -sS https://getcomposer.org/installer | php
13  - php composer.phar install
14  # Generate an application key. Re-cache.
15  - cp .env.example .env
16  - php artisan key:generate
17
18test:
19  script:
20    - php artisan --version

npm関連はちょっと今回は脇に置いときます

(006.png)

mysqlとの連携

さて、これがやりたくて今回ながながと記事を書いてきたとも言えますナ。まず手元のdockerを整えてみましょう。

mysqlを導入するのは非常に簡単です。ここではバージョン5.7を選択してみます。

docker-compose.yml

 1---
 2version: '3'
 3
 4services:
 5  web:
 6    build: ./docker/php
 7    container_name: "laravel-ci-php"
 8    volumes:
 9      - ./:/var/www/html
10      - ./docker/000-default.conf:/etc/apache2/sites-available/000-default.conf
11    tty: true
12    ports:
13      - 8000:80
14
15  mysql:
16    image: mysql:5.7
17    container_name: "laravel-ci-mysql"
18    restart: always
19    environment:
20      MYSQL_DATABASE: laravel
21      MYSQL_ROOT_PASSWORD: root

dockerを終了してビルドし直します。その後shellに入って接続してみます。

 1root@bf2ba23f26c8:/var/www/html# apt -y install mariadb-client
 2root@bf2ba23f26c8:/var/www/html# mysql -uroot -proot -hmysql
 3Welcome to the MariaDB monitor.  Commands end with ; or \g.
 4Your MySQL connection id is 2
 5Server version: 5.7.31 MySQL Community Server (GPL)
 6
 7Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
 8
 9Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
10
11MySQL [(none)]> show databases;
12+--------------------+
13| Database           |
14+--------------------+
15| information_schema |
16| laravel            |
17| mysql              |
18| performance_schema |
19| sys                |
20+--------------------+
215 rows in set (0.008 sec)

このようにhost名がmysqlで接続できるようになっています。ちなみに、この状態だとmysqlのデータは保存されずdockerを終了するたびにどこかにいってしまいます。テストではそれでokだけどアプリとして持続的につかう場合はvolumeを使います

、が、とりあえずここはlaravelからmysqlに接続できるかを確認するのでこのままでやります。

設定を書く

.envに設定を書きます。ということはコピー元の**.env.example**に書いておきます。

1  DB_CONNECTION=mysql
2~ DB_HOST=mysql
3  DB_PORT=3306
4  DB_DATABASE=laravel
5  DB_USERNAME=root
6~ DB_PASSWORD=root

こんな感じです。~のところが変更点です。コピーしてキーを生成します。configもクリアします

1% docker-compose exec web cp .env.example .env 
2% docker-compose exec web php artisan key:generate 
3% docker-compose exec web php artisan config:clear

migrateしてみると…

1% docker-compose exec web php artisan migrate          
2
3
4   Illuminate\Database\QueryException
5
6  could not find driver (SQL: select * from information_schema.tables where table_schema = laravel and table_name = migrations and table_type = 'BASE TABLE')

となります。まあ要するにmysqlドライバがないわけで、これを何とかしていきます。

Dockerの中でmysqlドライバをいれる

dockerの中のphpはちょっと特殊な組まれ方をしており、OSのモジュールを使わず独特のコマンドで入れる事になっています。

1# mysql module
2RUN docker-php-ext-install pdo_mysql

これをDockerfileに書いておいてビルドしてupして

1% docker-compose exec web php artisan migrate                            
2
3Migration table created successfully.
4Migrating: 2014_10_12_000000_create_users_table
5Migrated:  2014_10_12_000000_create_users_table (29.72ms)
6Migrating: 2014_10_12_100000_create_password_resets_table
7Migrated:  2014_10_12_100000_create_password_resets_table (22.11ms)
8Migrating: 2019_08_19_000000_create_failed_jobs_table
9Migrated:  2019_08_19_000000_create_failed_jobs_table (21.67ms)

なるほどよさそう。これを**.gitlab-ci.yml**に反映します。

ここまでやってくると**.gitlab-ci.yml**の内容が俯瞰できるようになってくると思いますが、なかなか重厚な設定になっているのが理解できると思います。

なお、docker-composeのmysqlとgitlab-ciでは違っているのでちょっと注意してください。mysqlもlatestから5.7を直接指定するようにしています。

 1image: php:7.3
 2
 3services:
 4  - mysql:5.7
 5
 6variables:
 7  MYSQL_DATABASE: laravel
 8  MYSQL_ROOT_PASSWORD: secret
 9
10cache:
11  paths:
12    - vendor/
13#    - node_modules/
14
15before_script:
16  # Update packages
17  - apt-get update -yqq
18  # Install Composer and project dependencies.
19  - curl -sS https://getcomposer.org/installer | php
20  - php composer.phar install
21  # Generate an application key. Re-cache.
22  - cp .env.example .env
23  - php artisan key:generate
24  # Install php extensions
25  - docker-php-ext-install pdo_mysql
26  # migrate database
27  - php artisan migrate
28
29test:
30  script:
31    - php artisan --version

mysql:latestと古いphpの組み合わせだとおそらく The server requested authentication method unknown となります。 こういうのをチェックできるのも利点といえば利点ではありますがー

これをpushしてjobを確認します。今回は**.env.example**も変更したので忘れずに

DBのテスト

これでようやくDBのテストができるようになってきたといいたい所ですが、laravelのDBテストというか機能テストは実稼動のDBとは別に破壊可能なデータベースをもう1つ用意するのが基本だろうと思います。

従ってもう1つ起動します。こういうのが手軽なのもdockerのいい所です

ちなみに、gitlab ciのデータベースはもともとサービスとして運用するわけではなく使い捨てなのでそんなに考える必要はないんですが、まあこれもあとでセットアップし直しします。

ただその前にテストするものがない

というわけなのでデータベースにデータを用意します。手軽なのはseedです。

laravel8からユーザのseederの書き方のexampleがシンプル極まる形になりました

database/seeders/DatabaseSeeder.php

 1<?php
 2
 3namespace Database\Seeders;
 4
 5use Illuminate\Database\Seeder;
 6
 7class DatabaseSeeder extends Seeder
 8{
 9    /**
10     * Seed the application's database.
11     *
12     * @return void
13     */
14    public function run()
15    {
16        // \App\Models\User::factory(10)->create();
17    }
18}

まあ、ここはlaravelのチュートリアルじゃないからこれでいいか…とりあえずコメントを外しまして

1% docker-compose exec web php artisan db:seed 

とします。本当に入ったか確認するのでtinkerしてみます。

 1% docker-compose exec web php artisan tinker     
 2Psy Shell v0.10.4 (PHP 7.3.21 — cli) by Justin Hileman
 3>>> User::find(1)
 4[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.
 5=> App\Models\User {#4046
 6     id: 1,
 7     name: "Prof. Rickey Leannon II",
 8     email: "gabrielle.weber@example.net",
 9     email_verified_at: "2020-10-19 04:34:07",
10     created_at: "2020-10-19 04:34:08",
11     updated_at: "2020-10-19 04:34:08",
12   }

よさそうです。seedでユーザが10人作られているかのテストをtinkerでやってみます

注意: seedの数は割と変わっていく事もあるだろうから実際問題こういうテストはあんまよくないテストですがとりあえずのチュートリアルとして書きます。

1>>> User::count() === 10
2[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.
3=> true

テストを書く

割と何でもartisanで処理できます。末尾をTest.phpにしておかないと拾ってくれないような気がします

1% docker-compose exec web php artisan make:test CheckUserSeederCountTest

するとtests/Feature/CheckUserSeederCountTest.phpができるのでテストを書きます。これは先頭をtestにメソッドを書けば↓のようなテストでも拾ってくれます

 1<?php
 2
 3namespace Tests\Feature;
 4
 5use Illuminate\Foundation\Testing\RefreshDatabase;
 6use Illuminate\Foundation\Testing\WithFaker;
 7use Tests\TestCase;
 8
 9class CheckUserSeederCount extends TestCase
10{
11    use RefreshDatabase;
12
13    public function testSeedで10人作成されている()
14    {
15        $this->seed();
16        $count = \App\Models\User::count();
17        $this->assertEquals($count, 10);
18    }
19}

testします。これは通過すると思います。

 1% docker-compose exec web php artisan test  
 2
 3   PASS  Tests\Unit\ExampleTest
 4  ✓ basic test
 5
 6   PASS  Tests\Feature\CheckUserSeederCount
 7  ✓ seedで10人作成されている
 8
 9   PASS  Tests\Feature\ExampleTest
10  ✓ basic test
11
12  Tests:  3 passed
13  Time:   0.36s

これは何のdatabaseを使っているのか

本番をぶっとばすようになりました。マージですか。本番を破壊しないように**.env.testing**を作成してみます。

.env.testing

1DB_CONNECTION=mysql
2DB_HOST=mysql
3DB_PORT=3306
4DB_DATABASE=laravel-test
5DB_USERNAME=root
6DB_PASSWORD=root

これでテストすると

1  SQLSTATE[HY000] [1049] Unknown database 'laravel-test' (SQL: SHOW FULL TABLES WHERE table_type = 'BASE TABLE')

とかなりますね。まあmysql-testというデータベースを作成していないので当然です。

テスト用途のDBを定義する

docker-composeにて

 1  mysql:
 2    image: mysql:5.7
 3    container_name: "laravel-ci-mysql"
 4    restart: always
 5    environment:
 6      MYSQL_DATABASE: laravel
 7      MYSQL_ROOT_PASSWORD: root
 8
 9  mysql-test:
10    image: mysql:5.7
11    container_name: "laravel-ci-mysql-test"
12    restart: always
13    environment:
14      MYSQL_DATABASE: laravel-test
15      MYSQL_ROOT_PASSWORD: root

こんな感じに生やせばokでしょう。

あとkeyを適当に貼っておきます。最終的にはこんな感じ

.env.testing

1APP_KEY=base64:C9rZy+e3a8x7ikq0DE9ZCoYWG5nAGwEWo+fSL9SEl1I=
2DB_CONNECTION=mysql
3DB_HOST=mysql-test
4DB_PORT=3306
5DB_DATABASE=laravel-test
6DB_USERNAME=root
7DB_PASSWORD=root

これでtestが通るようになりました

.env.testingは差分しか書いてないのでこれをgitlab-ciで使うのは問題になります。gitlab-ciはDBが壊れてもいいわけなので.env.exampleを使っていいんですが、そうなると今度は**.env.testing**が邪魔になりますね。だったらもうrmしちゃえばいいだろうと思います。

最終的にこんな感じになっています。

というわけでgitlab-ciとlaravel+mysqlを使ったテストはこんな感じです。流石にわかり辛い気がするから推敲しましょう!!!!!111112345

参考

https://docs.gitlab.com/ee/ci/examples/laravel_with_gitlab_and_envoy/

いい記事と思うけどenvoyでのdeployまで包括して書かれてるからちょっと難しいかもね。