Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make phpunit do code-coverage on an external repository?

Question

I want to have PhpUnit tests in one git repository and the code being tested in another one. Q: May I do code-coverage?

In principle, this may sound weird to you. To prevent answers with "you should not do this" or "tests live in the same repo", let me give context.

Context

  1. Usually PhpUnit is for running unit-tests.

  2. If we strictly stick to pure DDD, a PHP project based on symfony should be based in two distinct repositories:

    • One with the model, pure PHP classes, unit-tested, no reference to symfonay at all;
    • and another with the "application" that uses symfony, and via composer, takes the model into the vendors to be consumed by a public PHP API.
  3. In addition to unit-tests, I used to use PhpUnit as a test-runner to run functional tests with Selenium.

  4. When we were not doing DDD so pure and we had, as 99% of the population, the model in the same repo than the application, just in a separated directory, live was easy. That was DDD "as an approach" even if we had the model outside any bundle, as the model is completely independent and truly should live in a separated repo.

  5. Instead, functional tests, do not belong to the model. The functional test may be selenium if the application is a web application, or some kind of JSON parser if the application is a REST-API, or a command-tester if the application is a command-line interface.

Soooo...

When you have /tests and /src in the same repository myNiceProject-ModelAndApplication.git it is easy to have a conig file like this one.

<phpunit bootstrap="vendor/autoload.php" colors="true">
    <testsuites>
        <testsuite name="myNiceProject-ModelAndApplication">
            <directory>tests</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">src</directory>
        </whitelist>
    </filter>
</phpunit>

Instead, when you have functional tests in the repository myNiceProject-Application.git and the model in the respository myNiceProject-Model.git, and you want to "monitor" how much percentage of the model is exercised by the functional test of the application, because the business rules say that the "functional test shall ensure coverage of 90% of the code lines containing business logic", then...

Q: How do you setup the configuration in repo A, where the test resides, to do test coverage over code that resides in repo B?

Side note

Another case of this pattern is a Q.A. department that needs to double-test what the coders already tested. They do "not" rely on the auto-contained unit-tests and want to apply another independent test-suite.

In addition, Q.A. should not write to the main repo, to do not pollute coder's work.

like image 977
Xavi Montero Avatar asked May 15 '26 05:05

Xavi Montero


1 Answers

Whitelist the directory you want coverage on.

fizz/
├── composer.json
├── phpunit.xml.dist
├── src
│   └── Fizz.php
└── test
    └── FizzTest.php
buzz/
├── composer.json
├── phpunit.xml.dist
├── src
│   └── Buzz.php
└── test
    └── BuzzTest.php

fizz/phpunit.xml.dist

<?xml version="1.0" encoding="UTF-8"?>
<phpunit>
    <testsuites>
        <testsuite name="unit">
            <directory>test</directory>
        </testsuite>
    </testsuites>

    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory>src</directory>
            <directory>./../buzz/src</directory>
        </whitelist>
    </filter>

    <logging>
        <log type="coverage-html" target="build/coverage" />
    </logging>

</phpunit>

The above configuration includes coverage of the buzz projects src directory.

An absolute path can be used too.

like image 99
Gerard Roche Avatar answered May 18 '26 10:05

Gerard Roche