テスト メタデータの収集

CircleCI は、XML ファイルからテスト メタデータを収集し、それを使用してジョブに関するインサイトを提供します。 ここでは、よく使用されるテスト ランナー用にテスト メタデータを XML として出力し、store_test_results ステップでレポートを保存するように CircleCI を構成する方法について説明します。

テスト結果をアーティファクトとして表示するには、store_artifacts ステップを使用してテスト結果をアップロードします。

設定ファイルでは、以下のように store_test_results キーが使用されます。

- store_test_results:
    path: test-results

ここで、path キーは、JUnit XML または Cucumber JSON テスト メタデータ ファイルのサブディレクトリが含まれる working_directory への絶対パスまたは相対パスです。 この path 値が非表示のフォルダーではないことを確認してください (たとえば .my_hidden_directory は無効な形式です)。

テスト メタデータを収集するように CircleCI を構成すると、最も頻繁に失敗するテストの一覧がアプリケーション内の [Insights (インサイト)] の詳細ページに表示されるので、不安定なテストを特定して、繰り返し発生している問題を分離できます。

失敗したテストに関するインサイト

フォーマッタの有効化

JUnit フォーマッタを有効化するまで、テスト メタデータは CircleCI 2.0 で自動的には収集されません。 RSpec、Minitest、および Django に対して、以下の構成を追加してフォーマッタを有効化します。

  • RSpec では、gemfile に以下を追加する必要があります。

    gem ‘rspec_junit_formatter’

  • Minitest では、gemfile に以下を追加する必要があります。

    gem ‘minitest-ci’

  • Django は、django-nose テスト ランナーを使用して構成する必要があります。

カスタム テスト ステップでのメタデータの収集

大多数のテスト ランナーが何らかの形式でサポートしているように、JUnit XML 出力を生成するカスタムのテスト ステップを使用している場合は、以下のとおり XML ファイルをサブディレクトリに書き出します。

<br />- store_test_results:
    path: /tmp/test-results

カスタム テスト ランナーの例

このセクションでは、以下のテスト ランナーの例を示します。

Cucumber

カスタム Cucumber ステップの場合は、JUnit フォーマッタを使用してファイルを生成し、それを cucumber ディレクトリに書き込む必要があります。 .circleci/config.yml ファイルに追加するコードの例は以下のとおりです。

    steps:
      - run:
          name: テスト結果の保存
          command: |
            mkdir -p ~/cucumber
            bundle exec cucumber --format junit --out ~/cucumber/junit.xml
          when: always
      - store_test_results:
          path: ~/cucumber
      - store_artifacts:
          path: ~/cucumber

path: は、ファイルが格納されるディレクトリをプロジェクトのルート ディレクトリからの相対ディレクトリで指定します。 CircleCI は、アーティファクトを収集して S3 にアップロードし、アプリケーション内の[Job (ジョブ)] ページの [Artifacts (アーティファクト)] タブに表示します。

または、Cucumber の JSON フォーマッタを使用する場合は、出力ファイルに .cucumber で終わる名前を付け、それを /cucumber ディレクトリに書き出します。 たとえば、以下のようになります。

    steps:
      - run:
          name: テスト結果の保存
          command: |
            mkdir -p ~/cucumber
            bundle exec cucumber --format pretty --format json --out ~/cucumber/tests.cucumber
          when: always
      - store_test_results:
          path: ~/cucumber
      - store_artifacts:
          path: ~/cucumber

Java JUnit の結果に使用する Maven Surefire プラグイン

Maven ベースのプロジェクトをビルドする場合は、Maven Surefire プラグインを使用して XML 形式のテスト レポートを生成することがほとんどです。 CircleCI では、これらのレポートを簡単に収集できます。 以下のコードをプロジェクトの .circleci/config.yml ファイルに追加します。

    steps:
      - run:
          name: テスト結果の保存
          command: |
            mkdir -p ~/test-results/junit/
            find . -type f -regex ".*/target/surefire-reports/.*xml" -exec cp {} ~/test-results/junit/ \;
          when: always
      - store_test_results:
          path: ~/test-results
      - store_artifacts:
          path: ~/test-results/junit

Gradle JUnit のテスト結果

Gradle で Java または Groovy ベースのプロジェクトをビルドする場合は、テスト レポートが XML 形式で自動的に生成されます。 CircleCI では、これらのレポートを簡単に収集できます。 以下のコードをプロジェクトの .circleci/config.yml ファイルに追加します。

    steps:
      - run:
          name: テスト結果の保存
          command: |
            mkdir -p ~/test-results/junit/
            find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/junit/ \;
          when: always
      - store_test_results:
          path: ~/test-results
      - store_artifacts:
          path: ~/test-results/junit

Node.js 用の Mocha

Mocha テスト ランナーで JUnit テストを出力するには、JUnit Reporter for Mocha を使用します。

.circleci/config.yml のテスト用作業セクションは、以下のようになります。

    steps:
      - checkout
      - run: npm install
      - run: mkdir ~/junit
      - run:
          command: mocha test --reporter mocha-junit-reporter
          environment:
            MOCHA_FILE: ~/junit/test-results.xml
          when: always
      - store_test_results:
          path: ~/junit
      - store_artifacts:
          path: ~/junit

Mocha と nyc の組み合わせ

以下は、marcospgp から提供された、Mocha と nyc の組み合わせに使用できるサンプルの全文です。

version: 2 jobs: build: environment: CC_TEST_REPORTER_ID: code_climate_id_here NODE_ENV: development docker:

            - image: circleci/node:8
              environment:
                MONGODB_URI: mongodb://admin:password@localhost:27017/db?authSource=admin
            - image: mongo:4.0
              environment:
                MONGO_INITDB_ROOT_USERNAME: admin
                MONGO_INITDB_ROOT_PASSWORD: password
        working_directory: ~/repo
        steps:
            - checkout

            # npm を更新します

            - run:
                name: update-npm
                command: 'sudo npm install -g npm@latest'

            # 依存関係をダウンロードしてキャッシュします

            - restore_cache:
                keys:
                    - v1-dependencies-{{ checksum "package-lock.json" }}
                # 正確な一致が見つからない場合は、最新のキャッシュの使用にフォールバックします
                    - v1-dependencies-

            - run: npm install

            - run: npm install mocha-junit-reporter # CircleCI 専用

            - save_cache:
                paths:
                    - node_modules
                key: v1-dependencies-{{ checksum "package-lock.json" }}

        - run: mkdir reports

            # mocha を実行します

            - run:
                name: npm のテスト
                command: ./node_modules/.bin/nyc ./node_modules/.bin/mocha --recursive --timeout=10000 --exit --reporter mocha-junit-reporter --reporter-options mochaFile=reports/mocha/test-results.xml
                when: always

            # eslint を実行します

            - run:
                name: eslint
                command: |
                    ./node_modules/.bin/eslint ./ --format junit --output-file ./reports/eslint/eslint.xml
                when: always

            # Code Climate のカバレッジ レポートを実行します

            - run:
                name: Code Climate テスト レポーターのセットアップ
                command: |
                    # テスト レポーターを静的バイナリとしてダウンロードします
                    curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
                    chmod +x ./cc-test-reporter
                    ./cc-test-reporter before-build
                when: always

            - run:
                name: code-coverage
                command: |
                    mkdir coverage
                    # nyc レポートでは、nyc が既に実行されている必要があります
                    # これにより、必要なデータが入った .nyc_output フォルダーが作成されます
                    ./node_modules/.bin/nyc report --reporter=text-lcov > coverage/lcov.info
                    ./cc-test-reporter after-build -t lcov
                when: always

            # 結果をアップロードします

            - store_test_results:
                path: reports

            - store_artifacts:
                path: ./reports/mocha/test-results.xml

            - store_artifacts:
                path: ./reports/eslint/eslint.xml

            - store_artifacts: # テスト カバレッジをアーティファクトとしてアップロードします
                path: ./coverage/lcov.info
                prefix: tests

Node.js 用の AVA

AVA テスト ランナーで JUnit テストを出力するには、tap-xunit を指定して TAP レポーターを使用します。

.circleci/config.yml のテスト用作業セクションは、以下の例のようになります。

    steps:
      - run:
          command: |
            yarn add ava tap-xunit --dev # または npm を使用できます
            mkdir -p ~/reports
            ava --tap | tap-xunit > ~/reports/ava.xml
          when: always
      - store_test_results:
          path: ~/reports
      - store_artifacts:
          path: ~/reports

ESLint

ESLint から JUnit 結果を出力するには、JUnit フォーマッタを使用します。

.circleci/config.yml の作業テスト セクションは、以下のようになります。

    steps:
      - run:
          command: |
            mkdir -p ~/reports
            eslint ./src/ --format junit --output-file ~/reports/eslint.xml
          when: always
      - store_test_results:
          path: ~/reports
      - store_artifacts:
          path: ~/reports

PHPUnit

PHPUnit テストの場合は、--log-junit コマンド ライン オプションを使用してファイルを生成し、それを /phpunit ディレクトリに書き込む必要があります。 .circleci/config.yml は以下のようになります。

    steps:
      - run:
          command: |
            mkdir -p ~/phpunit
            phpunit --log-junit ~/phpunit/junit.xml tests
          when: always
      - store_test_results:
          path: ~/phpunit
      - store_artifacts:
          path: ~/phpunit

pytest

pytest を使用するプロジェクトにテスト メタデータを追加するには、JUnit XML を出力するように指定したうえで、テスト メタデータを保存します。

      - run:
          name: テストの実行
          command: |
            . venv/bin/activate
            mkdir test-results
            pytest --junitxml=test-results/junit.xml

      - store_test_results:
          path: test-results

      - store_artifacts:
          path: test-results

RSpec

カスタム rspec ビルド ステップを使用するプロジェクトにテスト メタデータ コレクションを追加するには、Gemfile に以下の gem を追加します。

gem 'rspec_junit_formatter'

さらに、テスト コマンドを以下のように変更します。

    steps:
      - checkout
      - run: bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3
      - run: mkdir ~/rspec
      - run:
          command: bundle exec rspec --format progress --format RspecJunitFormatter -o ~/rspec/rspec.xml
          when: always
      - store_test_results:
          path: ~/rspec

Minitest

カスタム minitest ビルド ステップを使用するプロジェクトにテスト メタデータ コレクションを追加するには、Gemfile に以下の gem を追加します。

gem 'minitest-ci'

さらに、テスト コマンドを以下のように変更します。

    steps:
      - checkout
      - run: bundle check || bundle install
      - run:
          command: bundle exec rake test
          when: always
      - store_test_results:
          path: test/reports

詳細については、minitest-ci README を参照してください。

Clojure テスト用の test2junit

Clojure のテスト出力を XML 形式に変換するには、test2junit を使用します。 詳細については、サンプル プロジェクトを参照してください。

Visual Studio/.NET Core テスト用の trx2junit

Visual Studio または .NET Core で出力される trx ファイルを XML 形式に変換するには、trx2junit を使用します。

.circleci/config.yml の作業セクションは、以下のようになります。

    steps:
      - checkout
      - run: dotnet build
      - run: dotnet test --no-build --logger "trx"
      - run:
          name: テスト結果
          when: always
          command: |
              dotnet tool install -g trx2junit
              export PATH="$PATH:/root/.dotnet/tools"
              trx2junit tests/**/TestResults/*.trx
      - store_test_results:
          path: tests/TestResults
      - store_artifacts:
          path: tests/TestResults
          destination: TestResults

Karma

Karma テスト ランナーで JUnit テストを出力するには、karma-junit-reporter を使用します。

.circleci/config.yml の作業セクションは、以下のようになります。

    steps:
      - checkout
      - run: npm install
      - run: mkdir ~/junit
      - run:
          command: karma start ./karma.conf.js
          environment:
            JUNIT_REPORT_PATH: ./junit/
            JUNIT_REPORT_NAME: test-results.xml
          when: always
      - store_test_results:
          path: ./junit
      - store_artifacts:
          path: ./junit
// karma.conf.js

// 追加の構成...
{
  reporters: ['junit'],
  junitReporter: {
    outputDir: process.env.JUNIT_REPORT_PATH,
    outputFile: process.env.JUNIT_REPORT_NAME,
    useBrowserName: false
  },
}
// 追加の構成...

Jest

Jest データを収集するには、まず jest.config.js という名前の Jest 設定ファイルを以下のように作成します。

// jest.config.js
{
  reporters: ["default", "jest-junit"],
}

.circleci/config.yml に、以下の run ステップを追加します。

steps:
  - run:
      name: JUnit カバレッジ レポーターのインストール
      command: yarn add --dev jest-junit
  - run:
      name: JUnit をレポーターとして使用したテストの実行
      command: jest --ci --runInBand --reporters=default --reporters=jest-junit
      environment:
        JEST_JUNIT_OUTPUT_DIR: "reports/junit/js-test-results.xml"

全体の手順については、Viget の記事「Using JUnit on CircleCI 2.0 with Jest and ESLint (Jest および ESLint と共に CircleCI 2.0 で JUnit を使用する)」を参照してください。

メモ: Jest テストの実行時には、--runInBand フラグを使用してください。 このフラグがない場合、Jest はジョブを実行している仮想マシン全体に CPU リソースを割り当てようとします。 --runInBand を使用すると、Jest は仮想マシン内の仮想化されたビルド環境のみを使用するようになります。

--runInBand の詳細については、Jest CLI ドキュメントを参照してください。 この問題の詳細については、公式 Jest リポジトリの Issue 1524Issue 5239 を参照してください。

API

実行時のテスト メタデータに API からアクセスするには、テスト メタデータ API ドキュメントを参照してください。

関連項目

インサイトの使用

ビデオ: テスト ランナーのトラブルシューティング