Travis CI Logo

React with Rails – Testing, Deployment and Continuous Integration

Let’s walk through setting up React with Rails. Not just any React/Rails project, however. We will use RSpec testing for test-driven development, deploy our application to Heroku and use a continuous integration/delivery service provided by Travis CI.

Continuous What?

Testing is an important aspect of creating software. To ensure that unit tests are run against every build of a project, many engineering organizations have adopted the practice of continuous integration (CI), which involves using tools, such as Jenkins or Travis CI, to ensure that all new code is automatically and consistently tested for errors. Continuous delivery (CD) goes one step further by ensuring you can deploy every build into a production-like environment and then pass integration tests in that environment.

https://cloud.google.com/solutions/continuous-delivery-with-travis-ci

The bottom line is that Travis CI will run our test suite to ensure everything is passing. Once our tests are passing, Heroku will be notified and will automatically build the latest version of our application.

Before We Begin

  • This will be a long post, but hopefully worth it for you.
  • Mac OS is required for Chrome Driver. I am sure you can install it on Windows/Linux, but I won’t be going over it.
  • You need to have Homebrew installed. You can install it by following the directions here. Once installed, please install Chrome Driver by running brew install chromedriver
  • I recommend committing the new Rails project we will be creating to GitHub. If you just want to checkout the RSpec testing portion, no GitHub/Heroku is required.
  • I use the same database type (PostgreSQL) in development as I do in the production environment (you should too). Please install PostgreSQL before continuing.
  • Register accounts on Travis CI and Heroku. Both are free.
  • Setup your Heroku CLI by following these instructions.
  • If you don’t want to use React, just skip that portion. Everything else will still work just fine.

Setting Up Rails

Go ahead and generate a new Rails project running rails new app-name --database=postgresql. Once Rails is done with its magic, add a few gems to the gemfile. Add webpacker, rspec-rails, and database_cleaner The last two gems mentioned need to be in group test. Webpacker will be used throughout all environments. Go ahead and run bundle install and let’s continue.

Now that we have all of our required gems, run rails rspec:install from the root project directory. This command will setup our RSpec testing environment and will generate the rails_helper.rb and spec_helper.rb files in a directory named spec.

Open the rails_helper.rb file and add in the require statements below. Be sure the statements are under the helpful comment shown below.

# Add additional requires below this line. Rails is not loaded until this point!
require 'rspec/rails'
require 'capybara/rspec'
require 'capybara/dsl'
require 'database_cleaner'

Also add in this code just under the large comment block.

Capybara.register_driver :selenium_chrome do |app|
  Capybara::Selenium::Driver.new(app, browser: :chrome)
end
Capybara.javascript_driver = :selenium_chrome
Your rails_helper.rb should look something like this.

A Quick RSpec Test

Now that our RSpec test environment is setup we want to quickly ensure it is working. Go ahead and create a root route for Rails. Also create a view and put in a bit of text. We will use this text to ensure our testing is working and we will have the test visit the root path.

Once your root route is setup and associated with your new view, navigate to your spec folder and create a file called root_spec.rb. Inside of your new spec file, let’s add a quick test. First we want the test to fail, so ensure we are checking for text that doesn’t exist. Don’t forget the require statement!

require_relative './rails_helper.rb'

describe 'Feature Test: Homepage Interactions', type: :feature, js: true do
  it 'Text is present' do
    visit '/'
    expect(page).to have_content('Hello World!')
  end
end

Now run rspec in your terminal from the root project directory. If rspec does not work for you, try running bundle exec rspec /spec. You should have noticed that a barebones Chrome browser opened and closed, and now we have a failing test. Go ahead and change the test so that is should pass and run it again.

A quick point to note is that we are telling the test that we are using JavaScript. If you remove js: true, a browser will not open and the test will still run. Our test will still pass because our text is not rendered via JS. This little piece of information is important when you start to test content rendered via JS, such as the React frontend.

Installing and Using React

Installing React is actually quite simple and straightforward. We will not be using create-react-app, so we do not have to worry about running a Node.js and Rails server together. Rails will be serving React via the asset pipeline. No more CORS issues or running a proxy to test API calls. Yay!

Run rails webpacker:install from the root directory of your project. Once this is complete, run rails webpacker:install:react.

Take a look in app/javascript. We have this folder called packs, where all of our React components will live. You should see a default component called hello_react.jsx. We can present this component by including it in a Rails view. Go ahead and open your view you created earlier and add in <%= javascript_pack_tag ‘hello_react’ %>. In addition to whatever text you had earlier, you should see the text “Hello React!”.

Cool, so now we have React running and it only took 2 commands. Go ahead and play around with your RSpec test. Edit it to check for the text “Hello React!” and see what happens when js: true is missing.

One last note is that we can now easily restrict access to our React application. We can require users to be logged in before serving a specific view in the controller (remember a view contains the connection to our React app) just like we normally would with pure Rails.

Setting Up Heroku & Travis CI

Heroku

First we will get everything setup to be deployed to Heroku. Add a new file named Procfile in the base of your project. Copy and paste this into your Procfile: web: bundle exec puma -C config/puma.rb. This is telling Heroku how to run our Rails server.

While in the root directory of the project, run heroku create app-name. This will generate a new Heroku project. If you want, leave out the app-name identifier and Heroku will generate an awesome name for you.

Now we are ready to push to Heroku. Run git push heroku master. This will trigger Heroku to build a production environment and start serving our application. Run heroku open to see your live site.

If you encounter an error when visiting your site, check out the logs by running heroku logs in your terminal.

Travis CI

Inside of app/config, create a new file named database.yml.travis. Copy and paste the code below into the file.

test:
  adapter: postgresql
  database: travis_ci_test

In your root project directory, make a file called .travis.yml and paste in the code below. Take care to ensure the indenting is correct and that you have changed the Ruby version to the one you are running. (use ruby -v to get it).

sudo: required
dist: trusty
addons:
  apt:
    sources:
      - google-chrome
    packages:
      - google-chrome-stable

language: ruby
rvm:
  - 2.6.2
env:
  matrix:
      - DB=postgresql
services:
  - postgresql
script:
  - RAILS_ENV=test bundle exec rake db:schema:load --trace
  - bundle exec rake db:test:prepare
  - bundle exec rspec spec/
before_script:
  - cp config/database.yml.travis config/database.yml
  - psql -c 'create database travis_ci_test' -U postgres
  - export DISPLAY=:99.0
  - sh -e /etc/init.d/xvfb start
  - npm i -g npm@^3
  - sleep 3

Before we push this code to GitHub, let’s go connect our Heroku app and our Travis CI account to our repository.

On Heroku, log in and open your app by clicking on it. Navigate to the Deploy tab. Select GitHub as your deployment method. Find your GitHub repository using the search tool and connect with it. Next, click the checkbox for ‘Wait for CI to pass before deploy’ and enable automatic deploys.

What your Heroku setup should look like.

Next, head over to Travis CI and log in. In the top right click settings. Find your repository using the search feature and click the slider. Now you have turned on continuous integration for your repository.

Now we can go ahead and push our changes to GitHub (not to Heroku!). Once GitHub receives the commit, Travis CI will begin running our test suite. If the test suite passes, Heroku will build a new version of our application. If the test suite fails, Heroku will not build a new version, so our live application will not error out in front of live users.

A new commit. Travis CI is running the test suite.

Further Reading

Everything above should get you up and running so you can start working on an actual project. If you want more detail about anything we covered, check out some of the links below.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.