なぜ local で CircleCI を動かしたいと思ったのか
リモートの CircleCI 上でよく落ちるテストがあるが、ローカルでbundle exec rspec
ではほぼ再現しないことがあった。
『push デバックは辛いな』『Docker の設定で、低スペック状態にして確認することもできるし』という思いから、local で CircleCI でテストできる環境を整えようということからやってみた
結論、まだローカルではうまく行ってない!
テストの実行自体は問題ないのだがスクリーンショットが.... 😭
各種インストール
Docker
Dockerのサイトにアクセスし、Docker Desktopをダウンロードします。 今回は開発環境がMacだったので、Download for mac でダウンロードを行います。Docker.dmg ファイルがダウンロードされる。
ダウンロード完了後、Docker.dmg を開き、Docker を Applicationsフォルダに drag and drop を行う。
CircleCI
local で CircleCI を動かすために、CircleCI CLI のインストールを行う。
今回は Homebrew を利用してインストールを行います。
$ brew install circleci # Docker インストール済みの場合はこちら $ brew install --ignore-dependencies circleci
CircleCI用の設定ファイル
CircleCI CLI では、config のバージョンが2.1だとこのJob実行が行えないとのことでした。
このプロダクトでは既に CircleCI を利用しており、config を確認したところバージョンが2.1であったため、バージョンが2の設定ファイルを用意する必要があります。
.circleci/config.yml version: 2.1 executors: default: docker: - &base_docker image: circleci/xxxxxxxxxx environment: LANG: ja_JP.UTF-8 LANGUAGE: "ja_JP:ja" RAILS_ENV: "test" REVIEWDOG_VERSION: "0.10.2" RUBYOPT: "-EUTF-8" TZ: Asia/Tokyo commands: bundle_install_and_cache: steps: # Download and cache dependencies - restore_cache: keys: - v3-dependencies-{{ checksum "Gemfile.lock" }} # fallback to using the latest cache if no exact match is found - v3-dependencies- - bundle_install - save_cache: paths: - ./vendor/bundle key: v3-dependencies-{{ checksum "Gemfile.lock" }} bundle_install: steps: - run: name: install dependencies command: | bundle install --clean --jobs=4 --retry=3 --path vendor/bundle install_nodejs: steps: # https://circleci.com/docs/2.0/circleci-images/#best-practices - run: name: "Update Node.js and npm" command: | curl -sSL "https://nodejs.org/dist/v12.19.0/node-v12.19.0-linux-x64.tar.xz" \ | sudo tar --strip-components=2 -xJ -C /usr/local/bin/ node-v12.19.0-linux-x64/bin/node curl https://www.npmjs.com/install.sh | sudo bash node_version: steps: - run: name: node version command: node --version yarn_version: steps: - run: name: yarn version command: yarn --version yarn_install: steps: - restore_cache: keys: - v1-yarn-packages-{{ checksum "yarn.lock" }} - v1-yarn-packages- - run: name: yarn install command: yarn install --frozen-lockfile --ignore-optional --cache-folder ~/.cache/yarn - save_cache: paths: - ~/.cache/yarn key: v1-yarn-packages-{{ checksum "yarn.lock" }} jobs: build: executor: default working_directory: ~/repo steps: - checkout - bundle_install_and_cache - install_nodejs - node_version - yarn_version - yarn_install - persist_to_workspace: root: ~/repo paths: - ./vendor/bundle - ./node_modules - ./public/assets - ./tmp/cache/assets
circleci config process .circleci / config.yml > .circleci / process.yml
上記のコマンドで、バージョン2.1の設定ファイルの内容をバージョン2に整形し、process.yml(ファイル名は任意)というファイルに出力させる。
注意 : save_cache
/restore_cache
/store_artifacts
の記述があるが、CircleCi CLI では利用できない。そのため、ローカルで実行時には警告が表示されます。また、workflow にも対応していません。
.circleci/process.yml `save_cache` と `restore_cache`の記述に関しては削除済み version: 2 jobs: build: docker: - image: circleci/xxxxxxxxxx environment: LANG: ja_JP.UTF-8 RAILS_ENV: test REVIEWDOG_VERSION: 0.10.2 RUBYOPT: -EUTF-8 TZ: Asia/Tokyo working_directory: ~/repo steps: - checkout - run: name: install dependencies command: | bundle install --clean --jobs=4 --retry=3 --path vendor/bundle - run: name: Update Node.js and npm command: | curl -sSL "https://nodejs.org/dist/v12.19.0/node-v12.19.0-linux-x64.tar.xz" \ | sudo tar --strip-components=2 -xJ -C /usr/local/bin/ node-v12.19.0-linux-x64/bin/node curl https://www.npmjs.com/install.sh | sudo bash - run: name: node version command: node --version - run: name: yarn version command: yarn --version - run: name: yarn install command: yarn install --frozen-lockfile --ignore-optional --cache-folder ~/.cache/yarn - persist_to_workspace: root: ~/repo paths: - ./vendor/bundle - ./node_modules - ./public/assets - ./tmp/cache/assets
circleci local execute -c .circleci/process.yml # config にバージョン2で設定しているとき circleci local execute
上記のコマンドで CircleCI の build をローカルで実行することができます。
build 以外のジョブを実行する際には、--job JOB_NAME
のオプションをつけることで実行することができます。
features テストが失敗した時スクリーンショットを撮りたい!
gem 'capybara-screenshot' を入れて、失敗した時に勝手にスクリーンショットをとってくれる様にする。
group :test do gem 'capybara-screenshot' end
テストを実行する時のみgem 'capybara-screenshot'
が必要なので、テスト実行時のみパッケージがインストールされるようにする。
capybara-screenshot
の設定を追加する。
Capybara::Screenshot.register_filename_prefix_formatter(:rspec) do |example| "screenshot_#{example.description.tr(' ', '-').gsub(%r{^.*/spec/}, '')}" end
GitHub と CircleCI を連携している場合は、font をインストールしていないとお豆腐(□)が大量発生します。
commands に font のインストールについて追加し、そのコマンドをテストを実行しているジョブに追記します。
commands に追記せずそのまま steps に記載でも👍 知らんけど
commands: install_font: steps: - run: name: apt-get update command: sudo apt-get update - run: name: Install fonts command: | sudo apt-get install -y fonts-ipaexfont fonts-noto-cjk && sudo fc-cache -fv job: test: steps: - install_font
ここではfonts-ipaexfont fonts-noto-cjk
を入れていますが、お好みのフォントをどうぞ。
これでリモートでは綺麗なスクリーンショットが撮られる様になります。
最後にstore_artifacts
をテスト実行後に追加するのを忘れずに
- store_artifacts: path: tmp/capybara/
CircleCI の ARTIFACTS から失敗した際の画面のスクリーンショットを確認することができる様になります。
スクリーンショット(png)と HTML の両方で失敗原因について確認することができる様になります。
最後に
Dockerの設定でボリュームをマウントしてるが、ローカルにはなかった。
確認したところテストの実行が終了した段階でプロジェクトのファイルがなくなる様になっているみたいです。
そもそもスクリーンショットは/home/circleci/repo/tmp/capybara/
配下に格納される様になってました。
格納場所をそもそも勘違いしてました。馬鹿ですねぇw
no_output_timeout:
で止めている間にコンテナに入って、スクリーンショットが取れていることは確認できた。ただどんなスクリーンショットが撮られているかまでは確認してないけどね!!
docker cp コンテナ:tmp/capybara ローカルパス
でローカルにcapybara配下に格納されているスクリーンショットをローカルに
ってところで、この記事の期日が来てしまった...
ローカルでもうまくできたらまた会おう