Elixir and Phoenix: continuous integration on Gitlab CI
Recently I was introduced to Elixir and Phoenix (thanks @smeevil) and I've been playing around with that for the last few days. The functional programming takes some getting used to, but the quality of the tools and documentation are astounding and it's lots of fun to write a web application with Phoenix.
As a fun “real world” exercise I'm writing a simple web shop in Phoenix, as that touches on almost any aspect of web development: database interaction, frontend, backend, styling, image uploads, etcetera.
Of course I'm also writing tests for my mockup shop, and I thought it would be nice to try and hook these up to Gitlab CI.
In this article you'll learn how to configure your Elixir/Phoenix project for continuous integration with Gitlab CI, including integration tests with Hound and PhantomJS.
Setting up Gitlab CI
To run your tests on Gitlab CI, you'll need a .gitlab-ci.yml file in the root of your project. You'll also need a Gitlab instance to run your tests on; their documentation has all the details.
I'm using the Docker runner to run my tests locally. This is my
image: 'marceldegraaf/elixir' services: - 'postgres:latest' variables: POSTGRES_DB: shop_test POSTGRES_USER: postgres POSTGRES_PASSWORD: '' MIX_ENV: test before_script: - 'phantomjs --wd --webdriver-logfile=/tmp/phantomjs.log > /dev/null 2>&1 &' - cp config/test.exs.ci config/test.exs - mix deps.get - mix ecto.create - mix ecto.migrate stages: - test job: stage: test script: - mix test artifacts: paths: - tmp/screenshots cache: paths: - '_build' - 'deps'
marceldegraaf/elixir image contains an Erlang VM with Elixir pre-installed, and also comes with PhantomJS to make testing with Hound possible.
As you can see, in the before_script section we first start PhantomJS in webdriver mode, and then prepare the application for running our tests. The actual test commands are in job.script; in this case I just run mix test to run my test files.
To run integration tests I'm using Hound, using the PhantomJS driver. I've added a test/integration folder to my Phoenix project. A simple home page integration test could look like this:
defmodule Shop.HomePageTest do use ExUnit.Case use Hound.Helpers hound_session test "page title" do navigate_to "/" assert find_element(:tag, "h1") |> inner_html == "Welcome!" end end
To make sure Hound uses the PhantomJS webdriver, I've added this to my config/test.exs file:
config :hound, driver: "phantomjs"
If you run these tests locally, make sure to start PhantomJS before running mix test, or Hound will trow errors for not being able to reach the webdriver.