CircleCI에서 PHPUnit 병렬 실행

12740 단어 CircleCIPHPUnit
CircleCI 테스트의 병렬 실행은 테스트 파일을 인스턴스별로 분배함으로써 실현됩니다. 그러나 PHPUnit 명령줄( phpunit )은 여러 파일 이름을 받아 실행할 수 없습니다.
circleci tests glob "tests/**/*Test.php" | circleci tests split
# => インスタンスに割り当てられたテストファイル名のリスト (スペース区切)
# => そのままでは phpunit で実行できない...

그래서, 파일명의 리스트를 인수에 있어서, 그 테스트를 실행하기 위한 phpunit.xml ( phpunit-partial.xml ) (을)를 생성하는 툴을 작성해 대응했습니다.

phpunit-xml-gen.php



phpunit-xml-gen.php
<?php

$files = array_slice($argv, 1);

$xml = new DOMDocument();
$xml->load(__DIR__ . '/phpunit.xml');

$testsuite = $xml->createElement('testsuite');
$testsuite->setAttribute('name', 'partial');

foreach ($files as $file) {
    $testsuite->appendChild($xml->createElement('file', $file));
}

$testsuites = $xml->createElement('testsuites');
$testsuites->appendChild($testsuite);

$phpunit = $xml->getElementsByTagName('phpunit')->item(0);
$phpunit->replaceChild($testsuites, $phpunit->getElementsByTagName('testsuites')->item(0));

$xml->save(__DIR__ . '/phpunit-partial.xml');

exit(0);
  • 같은 디렉토리내의 phpunit.xml<testsuites /> 요소내를, 건네받은 파일명을 실행하는 <testsuite /> 로 옮겨놓아, phpunit-partial.xml 를 생성한다.
  • 프로젝트의 phpunit.xml에서 생성되므로 실행 파일 이외의 다른 설정을 인계합니다.
  • 그대로 phpunit를 실행하는 스크립트로 해도 좋았지만, 런타임에 옵션을 건네주고 싶기 때문에 그것은 그만두었다.

  • 이것을 다음과 같은 느낌으로 실행하면(요phpunit.xml)
    $ echo tests/FooTest.php tests/BarTest.php | xargs php ./phpunit-xml-gen.php
    

    이러한 느낌의 phpunit-partial.xml가 생성됩니다. 이 파일을 phpunit-c ( --configuration ) 옵션에 전달하면 모든 테스트 파일 만 실행할 수 있습니다.

    phpunit-partial.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <phpunit backupGlobals="false"
             backupStaticAttributes="false"
             bootstrap="vendor/autoload.php"
             colors="true"
             convertErrorsToExceptions="true"
             convertNoticesToExceptions="true"
             convertWarningsToExceptions="true"
             processIsolation="false"
             stopOnFailure="false">
        <testsuites>
            <testsuite name="partial">
                <file>tests/FooTest.php</file>
                <file>tests/BarTest.php</file>
            </testsuite>
        </testsuites>
        <filter>
            <whitelist processUncoveredFilesFromWhitelist="true">
                <directory suffix=".php">./app</directory>
            </whitelist>
        </filter>
        <php>
            <env name="APP_ENV" value="testing"/>
        </php>
    </phpunit>
    

    CircleCI 설정



    .circleci/config.yml
    jobs:
    
      phpunit:
        parallelism: 4
        steps:
          - run:
              command: |
                circleci tests glob "tests/Feature/**/*Test.php" "tests/Unit/**/*Test.php" | circleci tests split --split-by=timings | xargs php ./phpunit-xml-gen.php
                php ./vendor/bin/phpunit \
                  --verbose \
                  --log-junit tmp/test-reports/phpunit/logfile.xml \
                  --coverage-clover tmp/coverage-${CIRCLE_NODE_INDEX}.xml \
                  --configuration phpunit-partial.xml
          - store_test_results:
              path: tmp/test-reports
          - persist_to_workspace:
              root: /var/www/html
              paths:
                - tmp/coverage-*.xml
    

    store_test_results





    JUnit XML 형식의 파일을 CircleCI에 저장하도록 설정하면 테스트 파일의 실행 시간으로부터 좋은 느낌으로 각 인스턴스로 나누어 준다고 합니다. 설정하면 위와 같이 Test Summary가 표시됩니다.

    PHPUnit의 경우 --log-junit 옵션으로 생성 할 수 있으므로 store_test_results로 저장하고 테스트 할당 명령 인수에 --split-by=timings를 전달합니다.
    php ./vendor/bin/phpunit \
      --log-junit tmp/test-reports/phpunit/logfile.xml # ← これ
    
    circleci tests split --split-by=timings
    

    커버리지





    테스트를 실행한 인스턴스 내에서 생성되는 커버리지의 결과는 해당 인스턴스에서 실행한 테스트의 분만 반영됩니다.

    Coveralls와 같은 서비스를 사용하는 경우 모든 인스턴스의 테스트 실행이 완료될 때까지 기다려야 합니다.

    PHPUnit의 경우 phpunit를 실행할 때 생성되는 적용 범위의 파일 이름을 인스턴스별로 구분하여 persist_to_workspace/attach_workspace에서 좋은 느낌으로 수집하십시오.
    php ./vendor/bin/phpunit \
      --coverage-clover tmp/coverage-${CIRCLE_NODE_INDEX}.xml # ← これ
    

    .circleci/config.yml
    jobs:
    
      report:
        steps:
          - attach_workspace:
              at: /var/www/html
          - run:
              # NOTE: require $COVERALLS_REPO_TOKEN
              command: |
                php ./vendor/bin/php-coveralls \
                  --verbose \
                  --json_path=tmp/coveralls-upload.json \
                  --coverage_clover=tmp/coverage-*.xml
    

    workflow는 이런 느낌.

    .circleci/config.yml
    workflows:
      version: 2
      build-test-deploy:
        jobs:
          - build
          - phpunit:
              requires:
                - build
          - report:
              requires:
                - phpunit
    

    참고


  • h tps : // / rc ぇ시. 코 m / 두 cs / 2.0 / 파라 ぇ ぃ s m ぁ s r-jo bs /
  • htps // ph puni t. Red d. cs. 이오/엔/7.3/테이. HTML
  • htps // ph puni t. Red d. cs. 이오 / 엔 / 7.3 / 곤후 쿠라 치온. HTML
  • 좋은 웹페이지 즐겨찾기