Laravel, Circle CI and Github FTW
Tags: productivity, laravel, testing
Published: 2019-10-30 17:10:39

We all have unique ways of working. The view on personal projects is different. They can be quick and dirty. Some even make them so much that you can avoid testing (I know). In my experience, there are times when I skip the whole test coverage things, especially if it's just something I am spiking out. But for more stable pet projects that are going to be having actual people paying to use it. I would reconsider the approach. Mostly because its a key driver that helps me cut down on the manual testing. 

One of the side projects that I run, I would have found it really difficult to manage if it didn't have decent test coverage on the features. Pushing out new features, or fixing some urgent bug would require me to manually test and ensure everything is working for about 15-20 endpoints, also to make sure that core components are working. This is a hassle when it's a one-man team. I do have extra help here and there. And this is quite valuable to keep things in check when I have extra hands helping out with features. Because it helps me sleep better at night. I can be less freaked out when someone merges something and it doesn't break the flows for hundreds of outlets.

## Development and Deployments

I have a simple setup, the Admin and API's are written in PHP on the Laravel framework. It might not be everyone's favorite, but it helps me get stuff out the window pretty quickly and not having to sweat on the small things. I use [forge](https://forge.laravel.com/) for deployments and provisioning. This is not my favorite. Don't get me wrong, it's a great product. I use it because most of the time I can't be bothered about spending a few hours maintaining my configuration scripts. But the luxury of not having to give a f*ck about the whole thing and just provision stuff on demand and to know that it works out of the box. It is a lifesaver at times. I can trigger deployments trough slack, and sometimes I have push-to-deploy enabled so code gets deployed when I merge to master. 

The development process results in PR's I create for everything I work on. I did cheat at times, I regret that. I ensure that there is sufficient coverage on all endpoints. And enough UI tests on critical Admin features. Circle CI is my integration goto tool. For a few reasons, I get about 2000 min free. I can use private projects. And the configuration is damn straight forward. 

```
version: 2
jobs:
  build:
    docker:
      # Specify the version you desire here
      - image: circleci/php:7.3.3-fpm-node
      - image: circleci/mysql:8.0-ram
        command: [--default-authentication-plugin=mysql_native_password]
        environment:
          MYSQL_USER: root
          MYSQL_ROOT_PASSWORD: password
          MYSQL_DATABASE: platform_test
    steps:
      - checkout
      - run:
          name: Setup Environment
          command: |
            cp .env.testing .env
      - run: sudo apt update && sudo apt install zlib1g-dev libsqlite3-dev
      - run: sudo docker-php-ext-install zip
      - run: sudo -E docker-php-ext-install pdo pdo_mysql
      - run: sudo -E docker-php-ext-install bcmath && sudo docker-php-ext-enable bcmath
      - run: sudo apt install -y mysql-client

      # composer cache
      - restore_cache:
          keys:
          # "composer.lock" can be used if it is committed to the repo
          - v1-dependencies-{{ checksum "composer.json" }}
          # fallback to using the latest cache if no exact match is found
          - v1-dependencies-
      - run: composer install -n --prefer-dist
      - save_cache:
          key: composer-v1-{{ checksum "composer.lock" }}
          paths:
            - vendor
      # node cache
      - restore_cache:
          keys:
            - node-v3-{{ checksum "package.json" }}
            - node-v3-
      - run: yarn install
      - save_cache:
          key: node-v3-{{ checksum "package.json" }}
          paths:
            - node_modules
            - ~/.yarn
      - run: composer dump-autoload
      # prepare the database
      - run: php artisan key:generate
      - run: php artisan migrate --force
      - run: php artisan db:seed --force
      - run: ./vendor/bin/phpcs --standard=PSR2 app/
      - run:
          name: Run Laravel Server
          command: php artisan serve
          background: true
      - run:
          name: Run App Feature Tests
          command: ./vendor/bin/phpunit --testsuite Feature
      - run:
          name: Run App Unit Tests
          command: ./vendor/bin/phpunit --testsuite Unit
      - run:
          name: Run Laravel Dusk Tests
          command: php artisan dusk
          environment:
            APP_URL: http://localhost:8000

```
 
I have a few key steps:

1. Unit tests
2. Feature tests - More or less the HTTP API test
3. Dusk tests - These are E2E test for some Admin components and not all
4. PHP Code style checks - Just in case.

With Github, its pretty easy to have these build reflect the state of the PR and if its mergeable or not. Circle CI and forge have this ability to trigger automatic deployments when the merge the code when the tests are green. I haven't decided to go down that path for this project yet. 

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/zioy345tcj1wdu11i6u9.png)
 
## Conclusion 

In conclusion, for solo development for a product that makes money or even if its something that is being used by people and/or that is affecting some people in their day to day lives. Test coverage and automating this process will reduce the burden of making sure everything is sane and working every time you get something out of the door. The ROI is massive, compared to not having tests. You can easily get overwhelmed by the sheer number of areas that need to be manually verified. Sometimes testing an API using something like postman is just so effing boring. You should just automate it. 

Cheers and Good luck.