Library that provides collection, processing, and rendering functionality for PHP code coverage information.

Overview

phpunit/php-code-coverage

Latest Stable Version CI Status Type Coverage

Provides collection, processing, and rendering functionality for PHP code coverage information.

Installation

You can add this library as a local, per-project dependency to your project using Composer:

composer require phpunit/php-code-coverage

If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:

composer require --dev phpunit/php-code-coverage

Usage

 declare(strict_types=1);
use SebastianBergmann\CodeCoverage\Filter;
use SebastianBergmann\CodeCoverage\Driver\Selector;
use SebastianBergmann\CodeCoverage\CodeCoverage;
use SebastianBergmann\CodeCoverage\Report\Html\Facade as HtmlReport;

$filter = new Filter;
$filter->includeDirectory('/path/to/directory');

$coverage = new CodeCoverage(
    (new Selector)->forLineCoverage($filter),
    $filter
);

$coverage->start('');

// ...

$coverage->stop();


(new HtmlReport)->process($coverage, '/tmp/code-coverage-report');
Comments
  • Group line code-coverage by branch

    Group line code-coverage by branch

    Fix https://github.com/sebastianbergmann/php-code-coverage/issues/959

    • [x] Move tests over ExecutableLinesFindingVisitor from RawCodeCoverageDataTest to its own unit test
    • [x] Inline test data expectations to ease readability and maintainability
    • [x] Make test data expectations relative, so new test data can be added before or after the current ones without the need to rewrite other test data
    • [x] Save an associative array of line <=> branch index
    • [x] Add a test for every Control Structure and language definitions (Functions and Classes)
    • [x] Intersect line <=> branch index association with CC driver's output to obtain the final CC
    • [x] Test multiple CC data merge
    • [x] Test PR over existing code bases

    Effects on real code bases

    Before

    image

    After

    image

    As you can see, the difference can be quite high on line coverage: the code base in the shown here uses for example a lot of array declarations; prior to this PR, a single 1.000 array would have produced lines of CC only on non-scalar nodes; this PR instead marks all the 1.000 as executed (or not).

    But as we know, line CC is convenient, quick and reliable only as a quantitative result. Functions/Methods/Classes/Traits coverage has a much higher qualitative value, and this PR has very little effect on results. The difference in these cases are correct and expected: current 9.2.19 release has bugs that this PR fixes.

    Special cases

    Some PHP structure cannot be deterministically handled well. For example:

    return match($var) {
        MyEnum::A => 1,
        MyEnum::B => 1,
    };
    

    This code will always depend on autoload runtimes, but in contrast to https://github.com/sebastianbergmann/php-code-coverage/pull/892 this will also always produce 4 executable lines from CC drivers. This PR favour determinism and stability over CC precision, so for the example provided a single branch is reported, and thus all the 4 lines are going to be marked as covered if return has any hit.

    If the user needs precise and reliable feedback over CC, only Mutation Testing can help; in the match example it would be MatchArmRemoval mutators from Infection, see https://infection.github.io/guide/mutators.html#Removal-Mutators

    opened by Slamdunk 42
  • Version 9 (used with PHPUnit 9.3) is slower than Version 8 (used with PHPUnit 9.2)

    Version 9 (used with PHPUnit 9.3) is slower than Version 8 (used with PHPUnit 9.2)

    | Q | A | --------------------| --------------- | PHPUnit version | 9.3 | PHP version | 7.4 | Installation Method | Composer

    Summary

    After upgrading to PHPUnit 9.3, code coverage generation slowed down a lot.

    How to reproduce

    I've experienced this on most of my business repos; I'm sorry I can't provide a useful test set right now, but I can assure PHPUnit is the only upgraded package here

    Until PHPUnit 9.2 (best of 5 runs):

    $ /usr/local/bin/php '-d' 'pcov.enabled=1' '/var/www/html/vendor/phpunit/phpunit/phpunit' -v '--coverage-php' '/tmp/CV_ItLP7c' '--configuration' '/var/www/html/phpunit.xml' '--log-junit' '/tmp/PT_uMW9cK'
    PHPUnit 9.2.6 by Sebastian Bergmann and contributors.
    
    Runtime:       PHP 7.4.9 with PCOV 1.0.6
    Configuration: /var/www/html/phpunit.xml
    
    .....................................................             53 / 53 (100%)
    
    Time: 00:10.480, Memory: 74.50 MB
    
    OK (53 tests, 259 assertions)
    
    Generating code coverage report in PHP format ... done [00:00.023]
    

    From PHPUnit 9.3 (best of 5 runs):

    $ /usr/local/bin/php '-d' 'pcov.enabled=1' '/var/www/html/vendor/phpunit/phpunit/phpunit' -v '--coverage-php' '/tmp/CV_ItLP7c' '--configuration' '/var/www/html/phpunit.xml' '--log-junit' '/tmp/PT_uMW9cK'
    PHPUnit 9.3.2 by Sebastian Bergmann and contributors.
    
    Runtime:       PHP 7.4.9 with PCOV 1.0.6
    Configuration: /var/www/html/phpunit.xml
    Warning:       Your XML configuration validates against a deprecated schema.
    Suggestion:    Migrate your XML configuration using "--migrate-configuration"!
    
    .....................................................             53 / 53 (100%)
    
    Time: 00:17.054, Memory: 96.50 MB
    
    OK (53 tests, 259 assertions)
    
    Generating code coverage report in PHP format ... done [00:00.008]
    
    performance 
    opened by Slamdunk 42
  • ExecutableLinesFindingVisitor executable lines does not match the lines from xdebug coverage

    ExecutableLinesFindingVisitor executable lines does not match the lines from xdebug coverage

    | Q | A | --------------------------| --------------- | php-code-coverage version | 9.2.17 (latest) | PHP version | 8.0.23 (latest) | Driver | Xdebug | Xdebug version | 3.2.0alpha3 (latest) | Installation Method | Composer | Usage Method | PHPUnit & other | PHPUnit version (if used) | 9.5.24 (latest)

    An issue, that took me quite a while to figure out what is going on.

    In atk4/ui we have the following coverage setup:

    a) collect coverage in phpunit tests, config: https://github.com/atk4/ui/blob/33779a9414b624a8faa7e959883d4ba407099dcd/phpunit.xml.dist#L23-L29 b) collect coverage from web requests, config: https://github.com/atk4/ui/blob/33779a9414b624a8faa7e959883d4ba407099dcd/demos/init-app.php#L21-L24 and https://github.com/atk4/ui/blob/33779a9414b624a8faa7e959883d4ba407099dcd/src/Behat/CoverageUtil.php#L38-L43 c) then merge all the coverage files using phpunit/phpcov in https://github.com/atk4/ui/blob/33779a9414b624a8faa7e959883d4ba407099dcd/.github/workflows/test-unit.yml#L223

    Coverage collection is working. But as soon as we include tests/ dir also in b), the coverage decreases. This is wrong, as all tests/ files are already included in a) and inclusion of an already included file in another coverage collection cannot decrease the merged coverage.

    CI repro: https://github.com/atk4/ui/pull/1852/commits - see 2nd and 3rd commit

    https://app.codecov.io/gh/atk4/ui/blob/b762d62434df393aad170a7378d3d45876f93f5a/tests/JsTest.php (2nd commit coverage) https://app.codecov.io/gh/atk4/ui/blob/99f347b7d04567faefafa3b39105042b728e1649/tests/JsTest.php (3rd commit coverage)

    It seems the problem is in https://github.com/sebastianbergmann/php-code-coverage/pull/892 or in https://github.com/sebastianbergmann/phpcov.

    opened by mvorisek 37
  • Make colors in HTML report configurable

    Make colors in HTML report configurable

    | Q | A | --------------------------| --------------- | php-code-coverage version | 4.0.8 | PHP version | 7.0.24 | Driver | Xdebug | Xdebug version (if used) | 2.5.5 | Installation Method | Composer | Usage Method | PHPUnit | PHPUnit version (if used) | 5.7.23

    Hello. Is there an easy way to customize the colors in style.css? My variant of colorblindness make it pretty difficult to differentiate between high coverage (#dff0d8) and low coverage (#f2dede) as they both have very low saturation (8% to 10%). Thank you.

    opened by sebastienbarre 35
  • Feature/branch coverage

    Feature/branch coverage

    This PR continue the work @sebastianbergmann made on feature/path-coverage branch.

    Includes PRs #398 and #399

    Close #380

    TODO:

    • Clover XML Report. I won't add support for cond line types.
    opened by Maks3w 34
  • Executable code not shown as executed/executable

    Executable code not shown as executed/executable

    Moved here from #411 (where more than one issue was discussed).

    Environment

    • Linux
    • PHP 7.1.0RC6
    • Xdebug 2.5.0RC1
    • PHPUnit 5.6.7
    • php-code-coverage 4.0.3

    Steps to reproduce

    git clone https://github.com/ramsey/uuid-doctrine.git
    cd uuid-doctrine
    git checkout abbcbe56b023319dea7a72177333089cf47f5a69
    composer install
    ./vendor/bin/phpunit
    

    Actual result

    e9f95398-d168-11e5-901a-a8b81661e3a2

    Expected result

    Lines 50-52 of the uuid-doctrine/src/UuidBinaryType.php files should not be white.

    xdebug 
    opened by sebastianbergmann 30
  • WIP: Add Cobertura report format

    WIP: Add Cobertura report format

    Attempting to add Cobertura support, addressing #6, in case this is something we want to have.

    The report should be valid against http://cobertura.sourceforge.net/xml/coverage-04.dtd, and I need to know how to represent the branch-rate and related data. Is that something the coverage collector can provide? line-rate and related are simple enough.

    The tests are work in progress as well, need to add the example files for the other types of coverage reports as well.

    Other notes:

    Cobertura, as originating in the Java world, has no concept of code outside classes. This means we probably can't display "raw" PHP file code coverage (e.g. stuff like functions.php, index.php and so on) in these reports unless we mangle the data to fit report structure in some way.

    opened by rask 29
  • Incorrect coverage reported

    Incorrect coverage reported

    | Q | A | --------------------| --------------- | php-code-coverage version | 5.2.1 PHP version | 7.0.19 | Driver | Xdebug | Xdebug version (if used) | v2.5.3 | Installation Method | Composer | Usage Method | PHPUnit | PHPUnit version | 6.1.3

    Today, after doing a composer update, my coverage guards broke, when phpunit started reporting that my coverage had dropped to 88% from 100%. (I started with phpunit version 5.6.x, and upgraded to phpunit 6.1 after I saw the bug, in hopes of it being fixed, seems to be present in all recent versions including the 5.x line)

    Since no code had changed this seemed incorrect (only had done a composer update, no code changes).

    Further investigation shows that PHPUnit is incorrectly reporting random arguments in methods and functions as not covered (even though they are).

    Example:

    example

    In the example above, you can see that 4 tests actually cover that method, but it is saying that 1 argument is not covered. That seems impossible, since I have to call that method with those arguments. Especially since these tests are actually functional tests. Previously, these tests showed full coverage accross all metrics (Line, Functions and Methods, Classes and Traits), now, Lines show 100% but not Functions and Methods or Classes and Traits.

    Example of one of the tests:

        public function testPostManifestNotification()
        {
            $payload = ['emails' => [
                '[email protected]',
            ]];
            /** @var Branch $branch */
            $branch = $this->referenceRepository->getReference('release/COM170401.0');
            $path = sprintf(
                '/manifests/%s/actions/notify.json',
                StringType::create($branch->getFullName())->replace('/', '-')->toString()
            );
            $this->client->request('POST', $path, $payload);
            $response = $this->client->getResponse();
            $this->assertEquals(Response::HTTP_ACCEPTED, $response->getStatusCode());
        }
    

    As you can see, this is fully a functional test that should cover all the lines. PHPUnit reports they are not covered?

    This is causing all my reports and CI to break, since it uses phpunit to determine coverage thresholds.

    My phpunit config

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
    <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.7/phpunit.xsd"
         backupGlobals="false"
         colors="true"
         convertWarningsToExceptions="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         bootstrap="app/autoload.php">
        <php>
            <ini name="error_reporting" value="-1" />
            <server name="KERNEL_DIR" value="app/" />
        </php>
    
        <testsuites>
            <testsuite name="Isengard Tests">
                <directory suffix="Test.php">tests</directory>
            </testsuite>
        </testsuites>
    
        <filter>
            <whitelist>
                <directory>.</directory>
                <exclude>
                    <directory>./.hooks</directory>
                    <directory>./app</directory>
                    <directory>./bin</directory>
                    <directory>./var</directory>
                    <directory>./src/*Bundle/Resources</directory>
                    <directory>./src/*Bundle/DataFixtures</directory>
                    <directory>./src/AppBundle/Entity</directory>
                    <directory>./src/*/*Bundle/Resources</directory>
                    <directory>./src/*/Bundle/*Bundle/Resources</directory>
                    <directory>./vendor</directory>
                    <directory>./web</directory>
                    <directory>./tests</directory>
                    <file>RoboFile.php</file>
                </exclude>
            </whitelist>
        </filter>
        <logging>
            <log type="coverage-clover" target="build/phpunit/logs/clover.xml" />
            <log type="coverage-crap4j" target="build/phpunit/logs/crap4j.xml" />
            <log type="coverage-html" target="build/phpunit/html"/>
            <log type="junit" target="build/phpunit/logs/junit.xml" logIncompleteSkipped="false"/>
        </logging>
    </phpunit>
    

    Relevant composer parts:

        "require": {
            "php": ">=7.0",
            "ext-redis": "*",
            "symfony/symfony": "~3.2",
            "doctrine/orm": "^2.5",
            "doctrine/doctrine-bundle": "^1.6",
            "doctrine/doctrine-cache-bundle": "^1.2",
            "doctrine/doctrine-migrations-bundle": "^1.2",
            "stof/doctrine-extensions-bundle": "^1.2",
            "league/tactician-doctrine": "^1.0",
            "ramsey/uuid-doctrine": "^1.2",
            "symfony/swiftmailer-bundle": "^2.3",
            "symfony/monolog-bundle": "~2.11.3",
            "symfony/polyfill-apcu": "^1.0",
            "sensio/distribution-bundle": "^5.0",
            "sensio/framework-extra-bundle": "^3.0.2",
            "incenteev/composer-parameter-handler": "^2.0",
            "league/tactician-bundle": "^0.4",
            "friendsofsymfony/rest-bundle": "~2.2",
            "nelmio/api-doc-bundle": "^2.11",
            "jms/serializer-bundle": "^1.1",
            "jms/di-extra-bundle": "^1.8",
            "guzzlehttp/guzzle": "6.2.2",
            "mopa/bootstrap-bundle": "~3.0",
            "twbs/bootstrap": "~3.3.0",
            "symfony/assetic-bundle": "^2.8",
            "friendsofsymfony/jsrouting-bundle": "^1.6",
            "bmatzner/fontawesome-bundle": "~4.7",
            "tdn/php-types": "dev-develop as 3.0.0",
            "kzykhys/git": "v0.1.2",
            "cache/apcu-adapter": "~0.2",
            "cache/redis-adapter": "~0.4",
            "cache/cache-bundle": "~0.5",
            "cache/adapter-bundle": "~0.4",
            "cache/psr-6-doctrine-bridge": "^3.0",
            "kachkaev/assets-version-bundle": "~2.0",
            "components/jquery": "~3.1",
            "components/jqueryui": "~1.12",
            "datatables/datatables": "~1.10",
            "e-moe/guzzle6-bundle": "~1.1",
            "composer/semver": "^1.4",
            "paquettg/php-html-parser": "~1.7",
            "verbalexpressions/php-verbal-expressions": "dev-master",
            "typo3/class-alias-loader": "dev-master"
        },
        "require-dev": {
            "phploc/phploc": "^3.0",
            "sensio/generator-bundle": "^3.1",
            "dephpend/dephpend": "dev-develop",
            "henrikbjorn/lurker": "@stable",
            "doctrine/doctrine-fixtures-bundle": "^2.3",
            "symfony/phpunit-bridge": "dev-master",
            "friendsofphp/php-cs-fixer": "~2.0",
            "squizlabs/php_codesniffer": "~2.7",
            "phpunit/phpunit": "~6.1",
            "sebastian/phpcpd": "~3.0",
            "mockery/mockery": "~0.9",
            "liip/functional-test-bundle": "~1.7",
            "jakub-onderka/php-parallel-lint": "0.*",
             "phpmd/phpmd" : "@stable",
            "consolidation/robo": "~1.0",
            "seld/jsonlint": "~1.6",
            "kevinlebrun/colors.php": "0.*",
            "rskuipers/php-assumptions": "dev-feature/update-parser",
            "povils/phpmnd": "~1.0",
            "escapestudios/symfony2-coding-standard": "^2.10",
            "tm/tooly-composer-script": "^1.2"
        },
        "scripts": {
            "symfony-scripts": [
                "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
                "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
                "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
                "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
                "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
                "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget",
                "Mopa\\Bundle\\BootstrapBundle\\Composer\\ScriptHandler::postInstallSymlinkTwitterBootstrap",
                "Tooly\\ScriptHandler::installPharTools"
            ],
            "post-install-cmd": [
                "@symfony-scripts"
            ],
            "post-update-cmd": [
                "@symfony-scripts"
            ]
        },
        "config": {
            "process-timeout": 10000,
            "preferred-install": "dist",
            "github-protocols": ["https"],
            "bin-dir": "bin",
            "platform": {
                "php": "7.0"
            }
        },
        "extra": {
            "symfony-app-dir": "app",
            "symfony-bin-dir": "bin",
            "symfony-var-dir": "var",
            "symfony-web-dir": "web",
            "symfony-tests-dir": "tests",
            "symfony-assets-install": "relative",
            "incenteev-parameters": {
                "file": "app/config/parameters.yml"
            },
            "tools": {
                "phpmd-extension": {
                    "url": "https://github.com/mi-schi/phpmd-extension/releases/download/stable/phpmd-extension.phar",
                    "only-dev": true,
                    "force-replace": true
                },
                "phpmetrics": {
                    "url": "https://github.com/phpmetrics/PhpMetrics/releases/download/v2.2.0/phpmetrics.phar",
                    "only-dev": true,
                    "force-replace": true
                }
    
            },
            "typo3/class-alias-loader": {
                "class-alias-maps": [
                    "src/AppBundle/AliasMap.php"
                ],
                "always-add-alias-loader": true
            }
        },
        "repositories": [
            {
                "type": "git",
                "url": "https://github.com/vpassapera/php-assumptions.git"
            }
        ]
    

    Xdebug Config

    ; Managed by ansible
    zend_extension=/opt/remi/php70/root/usr/lib64/php/modules/xdebug.so
    xdebug.remote_enable=1
    xdebug.remote_autostart=1
    xdebug.remote_host=10.10.10.1
    xdebug.max_nesting_level=250
    xdebug.remote_port=9000
    xdebug.idekey=PHPSTORM
    
    [09:47:59] [vagrant@isengard] /vagrant [][develop ✓] →  php -i | grep -i "xdebug"                   
    /etc/php.d/15-xdebug.ini,
        with Xdebug v2.5.3, Copyright (c) 2002-2017, by Derick Rethans
    xdebug
    xdebug support => enabled
    xdebug.auto_trace => Off => Off
    xdebug.cli_color => 0 => 0
    xdebug.collect_assignments => Off => Off
    xdebug.collect_includes => On => On
    xdebug.collect_params => 0 => 0
    xdebug.collect_return => Off => Off
    xdebug.collect_vars => Off => Off
    xdebug.coverage_enable => On => On
    xdebug.default_enable => On => On
    xdebug.dump.COOKIE => no value => no value
    xdebug.dump.ENV => no value => no value
    xdebug.dump.FILES => no value => no value
    xdebug.dump.GET => no value => no value
    xdebug.dump.POST => no value => no value
    xdebug.dump.REQUEST => no value => no value
    xdebug.dump.SERVER => no value => no value
    xdebug.dump.SESSION => no value => no value
    xdebug.dump_globals => On => On
    xdebug.dump_once => On => On
    xdebug.dump_undefined => Off => Off
    xdebug.extended_info => On => On
    xdebug.file_link_format => no value => no value
    xdebug.force_display_errors => Off => Off
    xdebug.force_error_reporting => 0 => 0
    xdebug.halt_level => 0 => 0
    xdebug.idekey => PHPSTORM => PHPSTORM
    xdebug.max_nesting_level => 250 => 250
    xdebug.max_stack_frames => -1 => -1
    xdebug.overload_var_dump => 2 => 2
    xdebug.profiler_aggregate => Off => Off
    xdebug.profiler_append => Off => Off
    xdebug.profiler_enable => Off => Off
    xdebug.profiler_enable_trigger => Off => Off
    xdebug.profiler_enable_trigger_value => no value => no value
    xdebug.profiler_output_dir => /tmp => /tmp
    xdebug.profiler_output_name => cachegrind.out.%p => cachegrind.out.%p
    xdebug.remote_addr_header => no value => no value
    xdebug.remote_autostart => On => On
    xdebug.remote_connect_back => Off => Off
    xdebug.remote_cookie_expire_time => 3600 => 3600
    xdebug.remote_enable => On => On
    xdebug.remote_handler => dbgp => dbgp
    xdebug.remote_host => 10.10.10.1 => 10.10.10.1
    xdebug.remote_log => no value => no value
    xdebug.remote_mode => req => req
    xdebug.remote_port => 9000 => 9000
    xdebug.scream => Off => Off
    xdebug.show_error_trace => Off => Off
    xdebug.show_exception_trace => Off => Off
    xdebug.show_local_vars => Off => Off
    xdebug.show_mem_delta => Off => Off
    xdebug.trace_enable_trigger => Off => Off
    xdebug.trace_enable_trigger_value => no value => no value
    xdebug.trace_format => 0 => 0
    xdebug.trace_options => 0 => 0
    xdebug.trace_output_dir => /tmp => /tmp
    xdebug.trace_output_name => trace.%c => trace.%c
    xdebug.var_display_max_children => 128 => 128
    xdebug.var_display_max_data => 512 => 512
    xdebug.var_display_max_depth => 3 => 3
    

    Seems that anywhere I use a mock (i use mockery), or symfony functional tests, phpunit is not honoring that coverage under the Methods & Functions | Classes metrics...it did not that long ago.


    MOVED FROM https://github.com/sebastianbergmann/phpunit/issues/2676

    opened by vpassapera 28
  • Fix executable lines analysis

    Fix executable lines analysis

    add more tests for #948 and fix found issues to make executable lines really a maximal subset (edge cases can be non-present, but not the other way around, otherwise #942) of xdebug

    fix https://github.com/sebastianbergmann/php-code-coverage/pull/909/files#r820517185

    fix #942 (nested array test added and tested againt about 50k real LoC)

    fix #954 (merged via https://github.com/mvorisek/php-code-coverage/pull/2)

    fix #938 (test added)

    opened by mvorisek 25
  • Added a phpdbg based code coverage driver.

    Added a phpdbg based code coverage driver.

    Uses phpdbg to create code coverage reports, without x-debug. Phpdbg works on opcode basis therefore code coverage numbers differ in comparison to x-debug.

    The driver requires the phpdbg which is shipped with PHP7. The features required will not be available in phpdbg+PHP5 and those are also not planned to be backported.

    This driver takes all files into account which were included by the time $codeCoverage->stop() is called using get_included_files. All the coverage data is extracted from the phpdbgs' oplog. Files which get included after stop is invoked will not be part of the report (neither as covered nor uncovered).

    Main selling point for this driver is that it doesn't have "external dependencies" but works with a regular php7 build (which contains tokenizer and phpdbg).

    credits to @bwoebi for the phpdbg implementation part and @rdlowrey, @kelunik for discussions arround the topic.

    opened by staabm 25
  • CodeCoverage driver for PCOV

    CodeCoverage driver for PCOV

    Driver for krakjoe/pcov

    Initial testing shows this to be faster than phpdbg when configured correctly.

    I'm not able to use the Filter object to configure it, so for the moment the extension is configured by ini.

    opened by krakjoe 23
  • Fix coverage failure in case of an invalid file

    Fix coverage failure in case of an invalid file

    My lib supports two incompatible versions of a dependency. Code for newer version extends class that does not exist in older one. Currently code coverage fails with Uncaught Error: Class 'Latte\Extension' not found https://github.com/orisai/localization/actions/runs/3766553046/jobs/6403184303

    After applying the fix, coverage no longer fails. And file is correctly reported as uncovered. https://github.com/orisai/localization/commit/a0f7a0b766c738d0df99eed52f8f529aceabb4f3 https://github.com/orisai/localization/actions/runs/3766885353

    opened by mabar 1
  • Regression in executable line identification for `match` expressions in 9.2.21

    Regression in executable line identification for `match` expressions in 9.2.21

    | Q | A | --------------------------| --------------- | php-code-coverage version | 9.2.21 | PHP version | 8.1.7 | Driver | Xdebug | Xdebug version (if used) | 3.1.5 | Installation Method | Composer | Usage Method | PHPUnit | PHPUnit version (if used) | 9.5.26

    Some valuable precision in the identification of executable lines is lost as a result of #964. I have not reviewed that PR carefully enough to judge its merits, but I see how the concerns raised by @mvorisek can manifest as a regression in real-world test suites. I appreciate the many, many hours of effort by the contributors working on this issue and I hope that we can find a solution that is still friendly to mutation testing without impacting precision.

    For example, in 9.2.20, only the branches of a match expression that were actually executed were displayed as covered. In 9.2.21, the entire match expression is now reported as being covered, even though it is not. It was quite useful to know which branches were being exercised by the test.

    I'm having a bit of deja vu here, because I reported a nearly identical regression to match expression coverage in #904, which was fixed somewhere between 9.2.13 and 9.2.20! :)

    Here is an example class:

    <?php declare(strict_types=1);
    
    class MatchExpr {
    
        public int $result;
    
        public function __construct(int $value) {
            $this->result = match ($value) {
                0 => 4,
                1 => 5,
                2 => 6,
                3 => 7,
                default => 8,
            };  
        }   
    
    }
    

    And here is the corresponding test:

    <?php declare(strict_types=1);
    
    use PHPUnit\Framework\TestCase;
    use MatchExpr;
    
    /**
     * @covers MatchExpr
     */
    class MatchExprTest extends TestCase {
    
        /** 
         * @testWith [0, 4]
         *           [2, 6]
         *           [9, 8]
         */
        public function test_happy_path(int $value, int $expected): void {
            self::assertSame($expected, (new MatchExpr($value))->result);
        }   
    
    }
    

    Coverage report in 9.2.20 (only 3 of the 5 branches are covered, as expected): image

    Coverage report in 9.2.21 (all branches are marked as covered): image

    Thank you for your time!

    opened by hemberger 7
  • Statement below class does not generate any coverage line

    Statement below class does not generate any coverage line

    | Q | A | --------------------------| --------------- | php-code-coverage version | 9.2.18, 9.2.19 / latest | PHP version | 8.0.24 | Driver | Xdebug | Xdebug version | 3.2.0RC1 | Installation Method | Composer | Usage Method | PHPUnit | PHPUnit version | 9.5.25

    code: https://github.com/atk4/data/blob/e091b675d32a17d839e918557f3e24ab6211b563/bootstrap-types.php#L49

    <?xml version="1.0" encoding="UTF-8"?>
    <coverage generated="1668794616">
      <project timestamp="1668794616">
    ...
        <file name="/__w/data/data/bootstrap-types.php">
          <class name="Atk4\Data\Types\Types" namespace="global">
            <metrics complexity="0" methods="0" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="0" coveredstatements="0" elements="0" coveredelements="0"/>
          </class>
          <class name="Atk4\Data\Types\MoneyType" namespace="global">
            <metrics complexity="8" methods="5" coveredmethods="5" conditionals="0" coveredconditionals="0" statements="8" coveredstatements="8" elements="13" coveredelements="13"/>
          </class>
          <line num="17" type="method" name="getName" visibility="public" complexity="1" crap="1" count="12"/>
          <line num="19" type="stmt" count="12"/>
    ...
          <line num="43" type="method" name="requiresSQLCommentHint" visibility="public" complexity="1" crap="1" count="12"/>
          <line num="45" type="stmt" count="12"/>
          <metrics loc="50" ncloc="50" classes="1" methods="5" coveredmethods="5" conditionals="0" coveredconditionals="0" statements="8" coveredstatements="8" elements="13" coveredelements="13"/>
        </file>
    ...
    

    image

    simple repro code:

    <?php
    
    class Foo
    {
        public function x(): void
        {
            phpversion(); // must be covered (currently covered)
        }
    }
    
    phpversion(); // must be covered too (currently NOT covered)
    

    does not generate any coverage line (in clover output)

    when the statement is added into method body, the coverage is generated, but for some reasons, coverage for statement outside/below method does not - maybe related to clover only, not sure

    opened by mvorisek 4
  • Improved the Cobertura coverage report

    Improved the Cobertura coverage report

    The format of the Cobertura report did not match the Cobertura document definition. For example in some cases, the required attribute name of package and the required attribute signature of method was empty. Resulting in tools like Jenkins not being able to interpret the report.

    type/bug 
    opened by jhoffland 9
  • Coverage cache should use relative paths.

    Coverage cache should use relative paths.

    | Q | A | --------------------------| --------------- | php-code-coverage version | >= 9.2.17 | Installation Method | Composer | Usage Method | PHPUnit | PHPUnit version (if used) | 9.5.25

    The cache file lookup uses the absolute path of both, the cache scripts of this project (introduced here: https://github.com/sebastianbergmann/php-code-coverage/commit/acd254eb5eb09e26c2ec1bf407230d162d2db453) and the absolut path of covered file of the project under test. As we are running subsequent builds of our project in different paths (including the build number e.g.), we can't use the cache much, as every run causes a miss and would only produce tons of duplicates in a shared cache folder.

    Would it be possible to change both path to use relative path to the files? As both methods are using the content of the file as well, it should be sufficient to build unique cache hashes. What do you think?

    opened by thirsch 2
  • Directories are not shown in strict alphabetical order

    Directories are not shown in strict alphabetical order

    | Q | A | --------------------------| --------------- | php-code-coverage version | 9.2.17 | PHP version | 7.4.24 | Driver | PCOV | PCOV version (if used) | 7.4.13 | Installation Method | Composer | Usage Method | Codeception | PHPUnit version (if used) | 9.5.24

    Dirctories should be shown in alphabetical order. In the screenshot, EntityRepository comes before Entity but it should be after. image

    opened by CJDennis 0
Owner
Sebastian Bergmann
Sebastian Bergmann is the creator of PHPUnit. He co-founded thePHP.cc and helps PHP teams build better software.
Sebastian Bergmann
Removes final keywords from source code on-the-fly and allows mocking of final methods and classes

Removes final keywords from source code on-the-fly and allows mocking of final methods and classes. It can be used together with any test tool such as PHPUnit or Mockery.

David Grudl 326 Dec 9, 2022
An effort to make testing PHP code as easy and fun as its JavaScript equivalent

An effort to make testing PHP code as easy and fun as its JavaScript equivalent when using the excellent Jasmine, from which syntax and general usage is shamelessly borrowed.

Johan Stenqvist 24 Apr 22, 2022
Provides generic data providers for use with phpunit/phpunit.

data-provider Installation Run composer require --dev ergebnis/data-provider Usage This package provides the following generic data providers: Ergebni

null 25 Jan 2, 2023
CommandHelper - is a very useful thing for quick code testing and more!

CommandHelper CommandHelper - is a very useful thing for quick code testing and more! Examples: Code: require_once('commandhelper.php');

RuvSleep 1 Feb 11, 2022
A PHP library for mocking date and time in tests

ClockMock Slope s.r.l. ClockMock provides a way for mocking the current timestamp used by PHP for \DateTime(Immutable) objects and date/time related f

Slope 44 Dec 7, 2022
Faker is a PHP library that generates fake data for you

Faker Faker is a PHP library that generates fake data for you. Whether you need to bootstrap your database, create good-looking XML documents, fill-in

FakerPHP 2.7k Dec 27, 2022
Faker is a PHP library that generates fake data for you

Faker is a PHP library that generates fake data for you. Whether you need to bootstrap your database, create good-looking XML documents, fill-in your persistence to stress test it, or anonymize data taken from a production service, Faker is for you.

FakerPHP 1.7k Aug 23, 2021
PHPArch is a work in progress architectural testing library for PHP projects

PHPArch What is this? Installation Simple Namespace validation Available Validators Defining an architecture Syntactic sugar: Bulk definition of compo

Johannes Hertenstein 236 Nov 28, 2022
Mockery - Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library

Mockery Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its c

Mockery 10.3k Jan 1, 2023
Infrastructure and testing helpers for creating CQRS and event sourced applications.

Broadway is a project providing infrastructure and testing helpers for creating CQRS and event sourced applications. Broadway tries hard to not get in your way.

null 1.5k Dec 30, 2022
The modern, simple and intuitive PHP unit testing framework.

atoum PHP version atoum version 5.3 -> 5.6 1.x -> 3.x 7.2 -> 8.x 4.x (current) A simple, modern and intuitive unit testing framework for PHP! Just lik

atoum 1.4k Nov 29, 2022
:heavy_check_mark: PHP Test Framework for Freedom, Truth, and Justice

Kahlan is a full-featured Unit & BDD test framework a la RSpec/JSpec which uses a describe-it syntax and moves testing in PHP one step forward. Kahlan

Kahlan 1.1k Jan 2, 2023
PHP unit testing framework with built in mocks and stubs. Runs in the browser, or via the command line.

Enhance PHP A unit testing framework with mocks and stubs. Built for PHP, in PHP! Quick Start: Just add EnhanceTestFramework.php and you are ready to

Enhance PHP 67 Sep 12, 2022
A PHP Module, that help with geneting of task script for playwright and send it node.js

A PHP Module, that help with geneting of task script for playwright and send it node.js

LuKa 13 Dec 7, 2022
Mocks, stubs, and spies for PHP.

Mocks, stubs, and spies for PHP. Installation Available as various Composer packages, depending on the test framework in use: For Kahlan, use eloquent

Eloquent 195 Dec 25, 2022
PHP libraries that makes Selenium WebDriver + PHPUnit functional testing easy and robust

Steward: easy and robust testing with Selenium WebDriver + PHPUnit Steward is a set of libraries made to simplify writing and running robust functiona

LMC s.r.o. 219 Dec 17, 2022
SimpleTest is a framework for unit testing, web site testing and mock objects for PHP

SimpleTest SimpleTest is a framework for unit testing, web site testing and mock objects for PHP. Installation Downloads All downloads are stored on G

SimpleTest 147 Jun 20, 2022
Analyses and produces a report with testability issues of a php codebase

Analyses and produces a report with testability issues of a php codebase

Edson Medina 134 Oct 27, 2022