8
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

テストを高速化しよう!CircleCI での並列テストのやり方をご紹介!!【CircleCI実践入門】

はじめに

今回はCircleCIで並列テストを実施する方法について解説します!

実際の使い方は、以下の公式記事を読む方が早いですが、本記事ではRailsのプロジェクトにRSpecを適用する方法について解説します。
https://circleci.com/docs/ja/2.0/parallelism-faster-jobs

YouTube動画

動画で確認したい方はこちらをどうぞ!
【YouTube動画】 テストを高速化しよう!CirceCI での並列テストのやり方をご紹介!!【CircleCI入門】
テストを高速化しよう!CirceCI での並列テストのやり方をご紹介!!【CircleCI入門】

GitHub

GitHubからコードをダウンロードして試すこともできます。

$ git clone git@github.com:yassun-youtube/circleci-parallel-test-sample.git

並列処理をするために

並列処理をするには、有料プランへの切り替えが必要です。
30ドル支払えば、テストが高速化します!

実際の設定ファイル

以下が実際のファイルです。

本記事では、並列テストと関連する部分だけを説明します。

それ以外の基本的な書き方については、以下のQiita記事か公式サイトの記事を参考にしてください。
https://qiita.com/yassun-youtube/items/2a09d5b1b56feace8156

circleci.yml
version: 2.1
jobs:
  test:
    docker:
      - image: circleci/ruby:2.7.2-node
    parallelism: 4
    steps:
      - checkout
      - restore_cache:
          keys:
            - bundle-{{ .Environment.CACHE_VERSION }}-{{ checksum "Gemfile.lock" }}
      - run:
          command: bundle install
      - save_cache:
          key: bundle-{{ .Environment.CACHE_VERSION }}-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle
      - run:
          name: Prepare Test
          command: circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings > /tmp/tests-to-run
      - run:
          name: Run Test
          command: bundle exec rspec --format documentation --format RspecJunitFormatter --out tmp/test-results/rspec.xml $(cat /tmp/tests-to-run)
      - store_test_results:
          path: tmp/test-results
workflows:
  version: 2
  test_workflow:
    jobs:
      - test

並列処理する数

並列処理する数はparallelismで指定します。
有料プランの場合は最大80まで指定できます。

parallelism: 4

テストファイルを分割するために

並列テストを実行するために、以下のコマンドを記述します。

glob "spec/**/*_spec.rb"で、specディレクトリ以下の_spec.rbファイルを表示し、split --split-by=timingsでCircleCIで保存されているタイミングデータをもとにテストファイルを分けます。
分けたファイルをtmp以下のtests-to-runsディレクトリに保存して準備は完了です。

*タイミングデータには、ファイル名またはクラス名ごとに各テストが完了するまでにかかった時間が記録されています。

- run:
    name: Prepare Test
    command: circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings > /tmp/tests-to-run

テストを実行する

あとはテストを実行するだけです。
RSpecの結果をRspecJunitFormatter (JUnit) で保存する場合は、gemの追加も必要です。

- run:
    name: Run Test
    command: bundle exec rspec --format documentation --format RspecJunitFormatter --out tmp/test-results/rspec.xml $(cat /tmp/tests-to-run)
# Gemfile
gem 'rspec_junit_formatter'

次回テストを効率的にするために

テストを準備するときに使用したタイミングデータは以下を指定しない場合、記録されません。
タイミングデータを使うと、テストの終了時間が均等になるようにファイルが分配されるので、テストが速くなります。

- store_test_results:
    path: tmp/test-results

 

分散と並列 (parallelismとparallel_tests)

CircleCIでparallelismを使うと、複数のマシンでテストを実行できますが、1つのマシン内で複数のテストを実行することもできます。
1つのマシン内で複数のテストを実行するには、Railsの場合、parallel_testsというgemを使います。

このgemを使うと、1つのマシン内でテストを複数動かすことができるので、さらに速度が上がります。

おわりに

今回はCircleCIでテストを高速化するための手法として、並列処理 (parallelism) について紹介しました。
parallel_testsを使って、さらに分割する方法は別動画・記事で触れたいと思います。

また、CircleCIの使い方については、基本編とJOBの使い方についても動画・記事を書いてます。
不安な方はぜひ、ご確認ください。

初心者必見! CircleCIでHello Worldしてみよう!

YouTube動画
https://youtu.be/6uZltaISUvo

Qiita記事
https://qiita.com/yassun-youtube/items/2a09d5b1b56feace8156

CircleCI を使いこなす! JOBの設定方法を徹底解説!!

YouTube動画
https://youtu.be/NWjNn2DLcPM

Qiita記事
https://qiita.com/yassun-youtube/items/38c6d32b50cbda2fcb9e

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
8
Help us understand the problem. What are the problem?