loading...
Cover image for Rails: minitest & GitLab CI

Rails: minitest & GitLab CI

mpressen profile image Maximilien Pressensé ・2 min read

Hi everybody, this post is the first of a serie I'd like to write, revolving around rails and CI/CD.

In this one I'll show you how to setup a proper CI for your new rails project.

I tried to give you the simplest example in order to focus on what's interesting, the configuration, I hope you'll find it useful.

Here is the repo alongside this article: https://gitlab.com/mpressen/rails_with_gitlab_ci


Init project

$ rails new rails_with_gitlab_ci --database=postgresql
$ cd rail_with_gitlab_ci
$ rails db:create db:migrate
$ rails server

Yay! You're on Rails

Perfect time to commit and push our code :

$ git add -A
$ git commit -m 'init rails project with postgresql'
$ git remote add origin git@gitlab.com:$(username)/rails_with_gitlab_ci.git
$ git push --set-upstream origin master

Add failing tests

Let's create a failing controller test :

# test/controllers/dummy_controller_test.rb

require 'test_helper'

class DummyControllerTest < ActionDispatch::IntegrationTest
  test "the truth" do
    assert false
  end
end

And a failing system test :

# test/system/dummy_system_test.rb

require 'application_system_test_case'

class DummySystemTest < ApplicationSystemTestCase
  test 'the truth' do
    assert false
  end
end

Setup gitlab CI

# .gitlab-ci.yml

image: ruby

stages:
  - test

tests:
  stage: test
  services:
  - postgres
  - name: selenium/standalone-chrome
    alias: chrome
  cache:
    paths:
      - apt-cache
      - node_modules
      - vendor/bundle
  variables:
      DB_HOST: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: root
      SELENIUM_REMOTE_URL: http://chrome:4444/wd/hub
      RAILS_ENV: test
      BUNDLE_PATH: vendor/bundle
  before_script:
    - export APT_CACHE_DIR=`pwd`/apt-cache && mkdir -pv $APT_CACHE_DIR
    - curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
    - echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
    - apt-get update -qq && apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -yqq yarn
    - yarn install
    - bundle install
    - bundle exec rails db:setup
  script:
    - bundle exec rails test  test/*

# config/database.yml

...
#
default: &default
  ...
  host: <%= ENV["DB_HOST"] %>
  username: <%= ENV["POSTGRES_USER"] %>
  password: <%= ENV["POSTGRES_PASSWORD"] %>
...

This config caches back and front dependencies for speed and computation cost (a must).

My favorite part is the use of a third docker image, selenium/standalone-chrome that avoids a pain point (chrome versions ...) some might have encountered before. With this config, it's another container that runs an headless chrome navigator on system tests.

# test/application_system_test_case.rb

require "test_helper"

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  if ENV['SELENIUM_REMOTE_URL']
    Capybara.server_host = '0.0.0.0'
    driven_by :selenium, using: :headless_chrome, screen_size: [800, 800], options: { url: ENV['SELENIUM_REMOTE_URL'] }
  else
    driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
  end

  def setup
    if ENV['SELENIUM_REMOTE_URL']
      net = Socket.ip_address_list.detect(&:ipv4_private?)
      ip = net.nil? ? 'localhost' : net.ip_address
      Capybara.app_host = "http://#{ip}"
    end
    super
  end
end
group :test do
  ...
  gem 'webdrivers', require: !ENV['SELENIUM_REMOTE_URL']
end

Let's try it !

$ git add -A
$ git commit -m 'setup gitlab CI'
$ git push

CI failure

Now, let's replace assert false by assert true in our dummy tests, commit and push.

CI success

Yeah !

Discussion

pic
Editor guide