Small Things to note running dockerized Laravel testing with Github Actions
Tags: github, laravel, testing, docker
Published: 2021-07-21 04:02:13

It’s always good to test your app on code changes so that buggy code never goes to production. Github Actions is a sweet feature to use for continuous integration. For a free account, you have 2000 mins/month to use. Today, let’s setup dockerized Laravel unit testing using it.

tldr;
The final workflow at `.github/workflows/testing.yml` look like this

```yml
name: Laravel testing

on:
    push:
        branches:
            - release

jobs:
    phpunit:
        runs-on: ubuntu-20.04
        strategy:
            fail-fast: true

        container:
            image: kenngsimply/laravelapp:v1

        services:
            db-tests:
                image: mysql:5.7
                env:
                    MYSQL_ROOT_PASSWORD: <YOUR-ROOT-PASSWORD>
                    MYSQL_USER: <YOUR-DB-USER>
                    MYSQL_PASSWORD: <YOUR-DB-USER-PASSWOD>
                    MYSQL_DATABASE: <YOUR-DB-NAME>
                ports:
                    - 3306:3306
            redis:
                image: redis:6-alpine
                ports:
                    - 6379:6379

        steps:
            - name: Checkout
              uses: actions/checkout@v2
            - name: Install composer dependencies
              run: |
                composer install
            - name: Prepare Laravel Application
              run: |
                cp .env.testing .env
                php artisan key:generate
            - name: Migrate and seed
              run: |
                php artisan migrate --seed
            - name:
              run: |
                php artisan redis:init
            - name: Run Testsuite
              run: php artisan test
```

Note:
- Since phpunit will be using `.env.testing` when it’s exists, we will copy it as `.env` in the test environment
- Since we specify `container`, the jobs will be running in the laravelapp docker container instead of in the runner machine. This simplifies the network access to service containers. 
- `services.<name>` will become your docker container’s hostname. For our example, the MySQL database container hostname will be `db-tests`. So in your `.env.testing`, make sure to set the `DB_HOST=db-tests`. Again this is because the jobs are running inside the docker. If it's running in the runner machine, then we would have to change it to `DB_HOST=localhost`. Refers to this good tutorial on [service container](https://docs.github.com/en/actions/guides/creating-redis-service-containers) for better understanding.
- If you having a connection issue with MySQL, you can try ping it using curl as one of the run step , Example `curl db-tests:3306 --ouput -`
- We use `fetch-depth: 1` so that we are not cloning the entire git history. In fact, this is the default behaviour of `actions/checkout@v2`, we just make it explicit here. Refer to the [doc](https://github.com/actions/checkout/blob/v2/action.yml) for all the inputs that are available.
- `fail-fast` is by default set to true, we just make it explicit here.

Here’s a sample of .env.testing

```yml
APP_NAME="My Sample Laravel App"
APP_ENV=testing
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=db-tests
DB_PORT=3306
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=

REDIS_CLIENT=phpredis
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_DB=0
REDIS_PREFIX='redis_test_'

CACHE_DRIVER=database
CACHE_PREFIX='cache_'   

TELESCOPE_ENABLED=false
```