✅当方の環境
- 開発環境 : Docker
- ruby 2.7.5
- rails 6.1.5
- Circle Ci
✅前提条件
「selenium-webdriver」をアプリ(WEB)のコンテナに導入したのではなく、アプリ(WEB)のコンテナとは別の「selenium-webdriver」のDockerコンテナを新しく作成・起動させて、SYSTEMテストを実行した場合に、本記事が有効である
- アプリ(WEB)のコンテナに、直接「Chome-driver」を導入した場合などは、本記事は対象外
- こちらの記事で「selenium-webdriver」を導入した場合は、以降の内容を試してみてください
✅概要
Circle Ciで使用する「自分で設定したイメージファイル」と、「自分で設定したDockerのイメージファイル」は、別々でお互いに共有されないため、Circle Ciの環境をDockerのイメージと同じ環境にするためには「.circleci\config.yml」にDockerfileと同じ設定を記載する必要がある。
- そのため、「.circleci\config.yml」に、「selenium-webdriver」を別コンテナで起動させるように、イメージを追加
- そして、ブラウザによるテストのため、javascriptが起動してしまうため、アセッツコンパイルを実施
- しかし、DockerのRubyの元々のイメージには、nodejsが導入されていないため、Circle CIが提供しているイメージ バリアントを使用し、あらかじめRubyのイメージにnodejsが導入されているようイメージを使用する
- 最後に、テスト前に「rake assets:precompile」を実行させる
✅よくあるエラー
SocketError:
Failed to open TCP connection to chrome:4444 (getaddrinfo: No address associated with hostname)
SocketError:
Failed to open TCP connection to chrome:4444 (getaddrinfo: No address associated with hostname)
Failure/Error: <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
ActionView::Template::Error:
Webpacker can't find application.js in /home/circleci/*****************/src/public/packs-test/manifest.json. Possible causes:
✅解決法
- 「.circleci\config.yml」に、CircleCiでも「selenium-webdriver」を使用するように修正する
docker-compose.yml
version: 2.1
orbs:
ruby: circleci/ruby@1.1.2
heroku: circleci/heroku@1.2.3
jobs:
build:
docker:
- image: cimg/ruby:2.7.5
working_directory: ~/dev-docker-rails6/src
steps:
- checkout:
path: ~/dev-docker-rails6
- ruby/install-deps
test:
docker:
#RUBYのイメージに最初から、nodejsを導入するようイメージ バリアントを追加
+ - image: cimg/ruby:2.7.5-node
- image: circleci/mysql:5.5
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: app_test
MYSQL_USER: root
#selenium-webdriverを別コンテナで起動させるため、seleniumのイメージ追加
- - image: selenium/standalone-chrome-debug:latest
- name: chrome
environment:
BUNDLE_JOBS: "3"
BUNDLE_RETRY: "3"
APP_DATABASE_HOST: "127.0.0.1"
RAILS_ENV: test
working_directory: ~/dev-docker-rails6/src
steps:
- checkout:
path: ~/dev-docker-rails6
- ruby/install-deps
- run:
name: Database setup
command: bundle exec rails db:migrate
#javasriptでエラーが発生するため、テスト前にアセッツコンパイルを実施
#アセッツコンパイルをするために、RUBYのイメージにnode-jsが必要
+ - run:
+ name: webpacker compile
+ command: bundle exec rake assets:precompile
# - run:
# name: Database setup
# command: bundle exec rails db:seed
- run:
name: test
command: bundle exec rspec
deploy:
docker:
- image: cimg/ruby:2.7.5
steps:
- checkout
- setup_remote_docker:
version: 19.03.13
- heroku/install
- run:
name: heroku login
command: heroku container:login
- run:
name: push docker image
command: heroku container:push web -a $HEROKU_APP_NAME
- run:
name: release docker image
command: heroku container:release web -a $HEROKU_APP_NAME
- run:
name: database setup
command: heroku run bundle exec rake db:migrate RAILS_ENV=production -a $HEROKU_APP_NAME
# - run:
# name: database seed
# command: heroku run bundle exec rake db:seed RAILS_ENV=production -a $HEROKU_APP_NAME
workflows:
version: 2
build_test_and_deploy:
jobs:
- build
- test:
requires:
- build
- deploy:
requires:
- test
filters:
branches:
only: main
✅参考ファイル
✅当方の環境の各種設定ファイル
🔴Gemfile
Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.7.5'
gem 'rails', '~> 6.1.5'
gem 'mysql2', '~> 0.5'
gem 'puma', '~> 5.0'
gem 'sass-rails', '>= 6'
gem 'webpacker', '~> 5.0'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.7'
gem 'bootsnap', '>= 1.4.4', require: false
group :development, :test do
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
#Rspecのため導入
gem 'pry-rails'
gem "rspec-rails", "~> 4.0.1"
gem 'factory_bot_rails', '~> 5.0'
end
group :development do
gem 'web-console', '>= 4.1.0'
gem 'rack-mini-profiler', '~> 2.0'
gem 'listen', '~> 3.3'
gem 'spring'
end
group :test do
#RspecのSystemテストのため導入
gem 'capybara', '~> 3.28'
gem 'selenium-webdriver', '~> 3.142'
end
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
gem 'rails-i18n'
🔴Dockerfile
Dockerfile
FROM ruby:2.7.5
ENV RAILS_ENV=production
#apt-keyとdevconfのエラー対策
ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
ENV DEBCONF_NOWARNINGS=yes
RUN 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 install -y nodejs yarn mariadb-client vim
WORKDIR /app
COPY ./src /app
RUN bundle config --local set path 'vendor/bundle' \
&& bundle install
COPY start.sh /start.sh
RUN chmod 744 /start.sh
CMD ["sh", "/start.sh"]
🔴docker-compose.yml
docker-compose.yml
version: '3'
services:
db:
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
volumes:
- ./src/db/mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: password
TZ: Asia/Tokyo
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- ./src:/app
ports:
- "3000:3000"
environment:
RAILS_ENV: development
SELENIUM_DRIVER_URL: http://selenium_chrome:4444/wd/hub
depends_on:
- db
- chrome
chrome:
image: selenium/standalone-chrome-debug
ports:
- 4444:4444
🔴config.yml
.circleci\config.yml
version: 2.1
orbs:
ruby: circleci/ruby@1.1.2
heroku: circleci/heroku@1.2.3
jobs:
build:
docker:
- image: cimg/ruby:2.7.5
working_directory: ~/dev-docker-rails6/src
steps:
- checkout:
path: ~/dev-docker-rails6
- ruby/install-deps
test:
docker:
- image: cimg/ruby:2.7.5-node
- image: circleci/mysql:5.5
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: app_test
MYSQL_USER: root
- image: selenium/standalone-chrome-debug:latest
name: chrome
environment:
BUNDLE_JOBS: "3"
BUNDLE_RETRY: "3"
APP_DATABASE_HOST: "127.0.0.1"
RAILS_ENV: test
working_directory: ~/dev-docker-rails6/src
steps:
- checkout:
path: ~/dev-docker-rails6
- ruby/install-deps
- run:
name: Database setup
command: bundle exec rails db:migrate
- run:
name: webpacker compile
command: bundle exec rake assets:precompile
# - run:
# name: Database setup
# command: bundle exec rails db:seed
- run:
name: test
command: bundle exec rspec
deploy:
docker:
- image: cimg/ruby:2.7.5
steps:
- checkout
- setup_remote_docker:
version: 19.03.13
- heroku/install
- run:
name: heroku login
command: heroku container:login
- run:
name: push docker image
command: heroku container:push web -a $HEROKU_APP_NAME
- run:
name: release docker image
command: heroku container:release web -a $HEROKU_APP_NAME
- run:
name: database setup
command: heroku run bundle exec rake db:migrate RAILS_ENV=production -a $HEROKU_APP_NAME
# - run:
# name: database seed
# command: heroku run bundle exec rake db:seed RAILS_ENV=production -a $HEROKU_APP_NAME
workflows:
version: 2
build_test_and_deploy:
jobs:
- build
- test:
requires:
- build
- deploy:
requires:
- test
filters:
branches:
only: main
🔴database.yml
config\database.yml
# MySQL. Versions 5.5.8 and up are supported.
#
# Install the MySQL driver
# gem install mysql2
#
# Ensure the MySQL gem is defined in your Gemfile
# gem 'mysql2'
#
# And be sure to use new-style password hashing:
# https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html
#
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: password
host: db
development:
<<: *default
database: app_development
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: app_test
host: <%= ENV.fetch("APP_DATABASE_HOST") { 'DB' } %>
# As with config/credentials.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password or a full connection URL as an environment
# variable when you boot the app. For example:
#
# DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
#
# If the connection URL is provided in the special DATABASE_URL environment
# variable, Rails will automatically merge its configuration values on top of
# the values provided in this file. Alternatively, you can specify a connection
# URL environment variable explicitly:
#
# production:
# url: <%= ENV['MY_APP_DATABASE_URL'] %>
#
# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full overview on how database connection configuration can be specified.
#
production:
<<: *default
database: <%= ENV['APP_DATABASE'] %>
username: <%= ENV['APP_DATABASE_USERNAME'] %>
password: <%= ENV['APP_DATABASE_PASSWORD'] %>
host: <%= ENV['APP_DATABASE_HOST'] %>