概要
CircleCi初心者です。
今回はローカルではRspecのテストが正常にパスするのに、CircleCi上でのみテストに失敗してしまい解決するのにかなり時間がかかってしまいました。
こちらはとりあえずRspecを通す為だけの対応策で根本的な解決はできていません。
とりあえずCI時のRspecをパスしたい場合のみ適用してください。
また根本的な解決方法があればぜひ教えて下さい。
↓
無事解決致しました!
##環境
CircleCi 2
Rails 5.0.7
ruby 2.5.1
Mysql 5.6
##コード
version: 2 # use CircleCI 2.0
jobs: # a collection of steps
build: # runs not using Workflows must have a `build` job as entry point
parallelism: 3 # run three instances of this job in parallel
docker: # run the steps with Docker
- image: circleci/ruby:2.5.1-node-browsers # ...with this image as the primary container; this is where all `steps` will run
environment: # environment variables for primary container
BUNDLE_JOBS: 3
BUNDLE_RETRY: 3
BUNDLE_PATH: vendor/bundle
RAILS_ENV: test
- image: circleci/mysql:5.6
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: true
MYSQL_ROOT_PASSWORD: ''
MYSQL_DATABASE: app_test
MYSQL_HOST: 127.0.0.1
MYSQL_ROOT_HOST: '%'
MYSQL_USER: root
steps: # a collection of executable commands
- checkout # special step to check out source code to working directory
# Which version of bundler?
- run:
name: Which bundler?
command: bundle -v
# Restore bundle cache
# Read about caching dependencies: https://circleci.com/docs/2.0/caching/
- restore_cache:
keys:
- rails-demo-bundle-v2-{{ checksum "Gemfile.lock" }}
- rails-demo-bundle-v2-
- run: # Install Ruby dependencies
name: Bundle Install
command: bundle check --path vendor/bundle || bundle install --deployment
# Store bundle cache for Ruby dependencies
- save_cache:
key: rails-demo-bundle-v2-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
- run:
name: Yarn Install
command: yarn install --cache-folder ~/.cache/yarn
# Store yarn / webpacker cache
- save_cache:
key: rails-demo-yarn-{{ checksum "yarn.lock" }}
paths:
- ~/.cache/yarn
- run:
name: Wait for DB
command: dockerize -wait tcp://127.0.0.1:3306 -timeout 120s
- run: bundle exec rake db:create
- run: bundle exec rake db:schema:load
- run:
name: Run rspec in parallel
command: |
bundle exec rspec --profile 10 \
--format RspecJunitFormatter \
--out test_results/rspec.xml \
--format progress \
$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)
# Save test results for timing analysis
- store_test_results: # Upload test results for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/
path: test_results
# See https://circleci.com/docs/2.0/deployment-integrations/ for example deploy configs
このファイルでpushすると
##エラー
ActiveRecord::StatementInvalid:
Mysql2::Error: Incorrect string value: '\xE8\xA5\xBF\xE6\x9D\x91' for column 'username' at row 1: INSERT INTO `users` (`email`, `encrypted_password`, `created_at`, `updated_at`, `username`) VALUES ('constance.ohara@hotmail.com', '$2a$04$cFA1loXQT9LSz9Y6Jw053.hnTIvgaGChi3h86KRaP2AFLNCI15AVC', '2020-03-05 15:03:31', '2020-03-05 15:03:31', '西村')
こちらはローカルで bundle exec rspec を実行時には正常にパスするのですが、
CI時のみエラーが出てしまいます。
このMysqlエラー自体はDBの文字コードの設定によって起きるエラーで、日本語が全て読み込まれず起きているようです。
なのでRspecテストのダミーデータを作成していたFactoryBotの設定をすべて英語にするとひとまずCI上でもテストをパスすることができました。
以上、根本的には解決になっていないのですがひとまずの対応策として記しておきます。
##追記
根本的な解決へと至りました。
予想通り文字コードによるエラーでした。
遭遇したエラーで検索をかけるとほとんどが、database.ymlの設定やmysqlに接続してターミナルから文字コードを変更する方法がヒットするのですが、今回の私の場合問題はschema.rbにありました。
create_table "comment", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1" do |t|
もともとはこのようにデフォルトの文字コードはlatin1になっており、こちらはdatabase.ymlを変更しただけでは修正できません。
ではどのように変更するかというと、まずdatabase.ymlを以下のように変更します。
adapter: mysql2
encoding: utf8
#以下略
その後一度migrateを行います。
$ bundle exec rake db:migrate
そうするとschema.rbは
- create_table "comments", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1" do |t|
+ create_table "comments", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
このように文字コードを変更することができます。
はじめにrake db:createでdbを作成すると文字コードはlatin1が設定されるようです。
以上です。
たどり着くのにかなり時間がかかったので、同じエラーに遭遇した人の助けになれば幸いです。