Производительность покрытия тестами PHP проекта

3 мар. 2022 г.

Всем привет! Сегодня хотел бы рассказать о своем опыте оптимизации анализа покрытия теставми для PHP проекта.

Проект основан на Symfony компонентах и частично покрыт unit и интеграционными тестами. В какой-то момент захотелось узнать точное покрытие, и в дальнейшем мониторить состояние.

Запуск тестов c рассчетом покрытия показал около 65%. Также стало понятно, что рассчет покрытия существенно влияет на производительность. Всего проект содержит около 45000 строк PHP кода.

Полезные ссылки:

Тесты запускались в Github Actions. Также приведены примеры конфигурации workflow.

Без покрытия.

Без рассчета покрытия тесты выполняются за 5 мин. 47 сек.

Пример конфигурации:

name: Tests
jobs:
  php-tests:
      runs-on: ubuntu-latest
      steps:
        - name: Git checkout Core
          uses: actions/checkout@v2
        - name: Setup PHP
          uses: shivammathur/setup-php@v2
          with:
              php-version: '7.4'
              coverage: none
        - name: Run tests
          run: vendor/bin/phpunit

Xdebug

Известный отладчик для PHP, помимо дебага умеет считать покрытие. Наиболее распространенный вариант расчета. В некоторых случаях вызывает проблемы с производительностью. Это может быть проблемой для крупнонго проекта.

Тесты выполняются за 30 мин. 32 сек. Запускать для каждого коммита проблематично.

Пример конфигурации:

name: Tests
jobs:
  php-tests:
      runs-on: ubuntu-latest
      steps:
        - name: Git checkout Core
          uses: actions/checkout@v2
        - name: Setup PHP
          uses: shivammathur/setup-php@v2
          with:
              php-version: '7.4'
              extensions: xdebug
              coverage: xdebug
        - name: Run tests
          run: vendor/bin/phpunit --coverage-html coverage --coverage-clover coverage.xml

Phpdbg

Альтернативный отладчик, более лекговесный.

Тесты выполняются за 14 мин. 31 сек. Уже лучше! Но все-таки почти в 3 раза медленнее, чем без покрытия. Можно ли прогонять тесты быстрее?

Пример конфигурации:

name: Tests
jobs:
  php-tests:
      runs-on: ubuntu-latest
      steps:
        - name: Git checkout Core
          uses: actions/checkout@v2
        - name: Setup PHP
          uses: shivammathur/setup-php@v2
          with:
              php-version: '7.4'
              extensions: phpdbg
              coverage: none
        - name: Run tests
          run: phpdbg -qrr -d memory_limit=-1 vendor/bin/phpunit --coverage-html coverage --coverage-clover coverage.xml

Pcov

Специализированный инструмент, именно для рассчета покрытия тестами.

Тесты выполняются за 9 мин. 35 сек.

Пример конфигурации:

name: Tests
jobs:
  php-tests:
      runs-on: ubuntu-latest
      steps:
        - name: Git checkout Core
          uses: actions/checkout@v2
        - name: Setup PHP
          uses: shivammathur/setup-php@v2
          with:
              php-version: '7.4'
              coverage: pcov
        - name: Run tests
          run: php -d memory_limit=1024M -d pcov.enabled=1 vendor/bin/phpunit --coverage-html coverage --coverage-clover coverage.xml

В результате решено было использовать Pcov.

На этом пока все. Спасибо за внимание!