dockerコンテナ内で実行したJunitの結果をCircleCIに反映する


環境

  • Circle CI 2.0
  • Circle CI のイメージ 「docker:17.05.0-ce-git」

やりたいこと

Circle CI で所定の設定を行うとspte実行したJunitを実行した結果を Circle CIの画面から参照できます。

.circleci/config.yml への記載は https://circleci.com/docs/2.0/collect-test-data/#gradle-junit-results にある通りです。

steps:
      - run:
          name: Save test results
          command: |
            mkdir -p ~/junit/
            find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/junit/ \;
          when: always
      - store_test_results:
          path: ~/junit
      - store_artifacts:
          path: ~/junit 

Dockerコンテナでなければこの通りなのですが、Dockerコンテナ内で実行した場合は、Junitを実行したコンテナから引っ張り出す必要があります。

やったこと

Dockerfile.junit

ビルドの都合で Junit用の Dockerfileを作成しました。内容はソース一式を COPY でコンテナ内に入れて、 CMD でgradle の testタスクを実行します。

FROM java:8 AS build
RUN mkdir /app
WORKDIR /app
COPY ./ ./
CMD ./gradlew test

.circleci/config.yml

まず、「name: Build container and run junit」でJunit用のコンテナを作成して実行します。実行する時には --name オプションでコンテナ名を指定します。

続いて、「name: Save junit results」で実行したコンテナからイメージを作ります。作成したイメージを使い公式サイトにある find . -type f -regex ".*/build/test-results/.*xml" でメタデータのxmlファイルを探し、tar cf - を行うことで、dockerコマンドの標準出力にtar形式のデータを出力します。
ホストのパイプで tar xvf -に渡すことでtar形式のファイルを展開して ~/junit ディレクトリに保存しています。

steps:
      - run:
          name: Build container and run junit 
          command: |
            docker build -f Dockerfile.junit -t kfc-batch-singleuse-coupon-junit .
            docker run --name junit kfc-batch-singleuse-coupon-junit

      - run:
          name: Save test results from docker container
          command: |
            mkdir -p ~/junit/
            docker commit junit junit-result
            docker run --rm junit-result /bin/bash -c 'find . -type f -regex ".*/build/test-results/.*xml" | tar cf - -T - --null ' | tar xvf - -C ~/junit
          when: always
      - store_test_results:
          path: ~/junit
      - store_artifacts:
          path: ~/junit

実行結果