LoginSignup
2
2

More than 3 years have passed since last update.

CircleCIでのテスト実行時間を短縮する:テストの並列化

Posted at

Laravelでサービスを提供しており、CircleCI内でテストを実行しています。
テストが増えるに連れてCircleCI内でのテスト時間が気になってきました。

並列のコンテナを増やすのも手ですが、お金もかかるのでとりあえず工夫できることから試してみました。

まずはテストの並列化。

現状のCircleCI設定

.circleci/config.yml
version: 2
references:
  php-c-image: &php-c-image
    image: sencorp/docker-php-c:v2.0.0
  postgres-image: &postgres-image
    image: circleci/postgres:10.1
    environment:
      POSTGRES_DB: hoge
      POSTGRES_USER: fuga
      POSTGRES_PASSWORD: fuga
jobs:
  build:
    docker:
      - *php-c-image
    working_directory: ~/repo
    steps:
      - checkout
      - restore_cache:
          keys:
              - composer-v2-{{ checksum "laravel/composer.lock" }}
      - run:
          name: composer install
          working_directory: ~/repo/laravel
          command: composer install -n --prefer-dist
      - save_cache:
          key: composer-v2-{{ checksum "laravel/composer.lock" }}
          paths:
            - laravel/vendor
      - restore_cache:
          keys:
              - npm-v2-{{ checksum "laravel/package-lock.json" }}
      - run:
          name: if there is no node_modules, npm ci
          working_directory: ~/repo/laravel
          command: |
            if [ ! -d node_modules ]; then
              npm ci
            fi
      - save_cache:
          key: npm-v2-{{ checksum "laravel/package-lock.json" }}
          paths:
            - laravel/node_modules
  test:
    docker:
      - *php-c-image
      - *postgres-image
    environment:
      APP_ENV: testing
      DB_HOST: localhost
      DB_PORT: 5432
      PAGER: cat # prevent psql commands using less
    working_directory: ~/repo
    steps:
      - checkout
      - restore_cache:
          keys:
              - composer-v2-{{ checksum "laravel/composer.lock" }}
      - restore_cache:
          keys:
              - npm-v2-{{ checksum "laravel/package-lock.json" }}
      - run:
          name: npm run dev
          working_directory: ~/repo/laravel
          command: npm run dev
      - run:
          name: dump-autoload
          working_directory: ~/repo/laravel
          command: composer dump-autoload
      - run:
          name: db migrate
          working_directory: ~/repo/laravel
          command: php artisan migrate
      - run:
          name: seed data
          working_directory: ~/repo/laravel
          command: php artisan db:seed
      - run:
          name: run test
          working_directory: ~/repo/laravel
          command: ./vendor/bin/phpunit
workflows:
  version: 2
  build-syntax-test:
    jobs:
      - build:
      - test:
          requires:
              - build

※不要な部分を削除したり、一部変更してあります

並列化にparatestを利用する

phpunitを並列に実行できるparatest。

インストール

$ composer require --dev brianium/paratest

実行

$ vendor/bin/paratest --processes 4

問題発生!

Storage::fake('my-disk')が実行毎にディレクトリを初期化してしまう。
並列時には他のテストの部分まで影響してしまう。

解決方法はこちら

CreatesFakeStorageのtraitを作成して、Storage::fakeを置き換えて解決しました。

何並列にするか

こちらは愚直に並列数を増やしながら、時間を計測しました。
今の状態だと10並列が一番速かったので10並列に。

並列化したCircleCI設定

.circleci/config.yml
version: 2
references:
  php-c-image: &php-c-image
    image: sencorp/docker-php-c:v2.0.0
  postgres-image: &postgres-image
    image: circleci/postgres:10.1
    environment:
      POSTGRES_DB: hoge
      POSTGRES_USER: fuga
      POSTGRES_PASSWORD: fuga
jobs:
  build:
    docker:
      - *php-c-image
    working_directory: ~/repo
    steps:
      - checkout
      - restore_cache:
          keys:
              - composer-v2-{{ checksum "laravel/composer.lock" }}
      - run:
          name: composer install
          working_directory: ~/repo/laravel
          command: composer install -n --prefer-dist
      - save_cache:
          key: composer-v2-{{ checksum "laravel/composer.lock" }}
          paths:
            - laravel/vendor
      - restore_cache:
          keys:
              - npm-v2-{{ checksum "laravel/package-lock.json" }}
      - run:
          name: if there is no node_modules, npm ci
          working_directory: ~/repo/laravel
          command: |
            if [ ! -d node_modules ]; then
              npm ci
            fi
      - save_cache:
          key: npm-v2-{{ checksum "laravel/package-lock.json" }}
          paths:
            - laravel/node_modules
  test:
    docker:
      - *php-c-image
      - *postgres-image
    environment:
      APP_ENV: testing
      DB_HOST: localhost
      DB_PORT: 5432
      PAGER: cat # prevent psql commands using less
    working_directory: ~/repo
    steps:
      - checkout
      - restore_cache:
          keys:
              - composer-v2-{{ checksum "laravel/composer.lock" }}
      - restore_cache:
          keys:
              - npm-v2-{{ checksum "laravel/package-lock.json" }}
      - run:
          name: npm run dev
          working_directory: ~/repo/laravel
          command: npm run dev
      - run:
          name: dump-autoload
          working_directory: ~/repo/laravel
          command: composer dump-autoload
      - run:
          name: db migrate
          working_directory: ~/repo/laravel
          command: php artisan migrate
      - run:
          name: seed data
          working_directory: ~/repo/laravel
          command: php artisan db:seed
      - run:
          name: run test
          working_directory: ~/repo/laravel
-         command: ./vendor/bin/phpunit
+         command: ./vendor/bin/paratest --processes 10
workflows:
  version: 2
  build-syntax-test:
    jobs:
      - build:
      - test:
          requires:
              - build

結果

diffの部分だけの計測ですが、実行時間が6分の1まで改善されました!

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2