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

Overview

Build Status Code Climate Scrutinizer Code Quality Code Coverage Dependencies

PHP_Testability

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

Installation

PHP_Testability requires at least PHP 7.0 to run.

Composer

Add edsonmedina/php_testability as a dependency to your project's composer.json file if you use Composer to manage the dependencies of your project.

{
    "require-dev": {
        "edsonmedina/php_testability": "dev-master"
    }
}

And run composer update.

Or alternatively, just run:

composer require edsonmedina/php_testability "dev-master"

Usage

Analyse the current directory and generate an HTML report into report/

vendor/bin/testability . -o report

Exclude some directories

vendor/bin/testability . -x vendor,tmp,upload,config -o report

Check all the available options.

vendor/bin/testability --help

Results

Open report/index.html on your browser. You shoule see something like this:

Screenshot

If you click on a file with issues, it'll show you a code browser and will highlight the lines with issues.

Screenshot

These are issues that hinder testability, such as:

  • references to global variables, super globals, etc
  • calls to functions that can't be mocked (like static methods or global functions)
  • new instances of objects (tight coupling - can't be mocked/injected)
  • ...and much more

Kudos to the brilliant PHP-Parser (by nikic) on which PHP_Testability relies heavily.

Comments
  • PHP Fatal error: Uncaught UnexpectedValueException: DirectoryIterator::__construct(...)

    PHP Fatal error: Uncaught UnexpectedValueException: DirectoryIterator::__construct(...)

    Running php_testability against the Genesis Framework (parent theme for WordPress), and it fails. Digging down to the reported first failure, and the following against this gives:

    ./vendor/bin/testability ./lib/admin/menu.php -x vendor -vvv
    
    PHP_Testability by Edson Medina
    Analysing code on "/Users/gary/code/themes/genesis/lib/admin/menu.php"...
    PHP Fatal error:  Uncaught UnexpectedValueException: DirectoryIterator::__construct(/Users/gary/code/themes/genesis/lib/admin/menu.php): failed to open dir: Not a directory in /Users/gary/code/themes/genesis/vendor/edsonmedina/php_testability/src/FileIterator.php:42
    Stack trace:
    #0 /Users/gary/code/themes/genesis/vendor/edsonmedina/php_testability/src/FileIterator.php(42): DirectoryIterator->__construct('/Users/gary/cod...')
    #1 /Users/gary/code/themes/genesis/vendor/edsonmedina/php_testability/src/Testability.php(58): edsonmedina\php_testability\FileIterator->iterate(Object(edsonmedina\php_testability\Contexts\RootContext))
    #2 /Users/gary/code/themes/genesis/vendor/edsonmedina/php_testability/src/testability(55): edsonmedina\php_testability\Testability->runReport()
    #3 {main}
      thrown in /Users/gary/code/themes/genesis/vendor/edsonmedina/php_testability/src/FileIterator.php on line 42
    
    Fatal error: Uncaught UnexpectedValueException: DirectoryIterator::__construct(/Users/gary/code/themes/genesis/lib/admin/menu.php): failed to open dir: Not a directory in /Users/gary/code/themes/genesis/vendor/edsonmedina/php_testability/src/FileIterator.php:42
    Stack trace:
    #0 /Users/gary/code/themes/genesis/vendor/edsonmedina/php_testability/src/FileIterator.php(42): DirectoryIterator->__construct('/Users/gary/cod...')
    #1 /Users/gary/code/themes/genesis/vendor/edsonmedina/php_testability/src/Testability.php(58): edsonmedina\php_testability\FileIterator->iterate(Object(edsonmedina\php_testability\Contexts\RootContext))
    #2 /Users/gary/code/themes/genesis/vendor/edsonmedina/php_testability/src/testability(55): edsonmedina\php_testability\Testability->runReport()
    #3 {main}
    

    Other files in the same directory seem to pass fine - I'm not sure why this file seems to be being treated as a directory.

    opened by GaryJones 6
  • Recoverable fatal error: Object of class ...Variable could not be converted to string

    Recoverable fatal error: Object of class ...Variable could not be converted to string

    PHP_Testability by Edson Medina Analysing code on "tki"... ..........................................................................................PHP Recoverable fatal error: Object of class PhpParser\Node\Expr\Variable could not be converted to string in tki/vendor/edsonmedina/php_testability/src/NodeWrapper.php on line 76

    :(

    Not sure the cause for this error, please let me know if I can help further.

    opened by thekabal 6
  • php-parser version required is old and conflicting(?)

    php-parser version required is old and conflicting(?)

    ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) Your requirements could not be resolved to an installable set of packages.

    Problem 1 - Can only install one of: nikic/php-parser[v3.0.6, v1.4.1]. - Can only install one of: nikic/php-parser[v1.4.1, v3.0.6]. - Can only install one of: nikic/php-parser[v1.4.1, v3.0.6]. - edsonmedina/php_testability dev-master requires nikic/php-parser 1.4.1 -> satisfiable by nikic/php-parser[v1.4.1]. - Installation request for edsonmedina/php_testability dev-master -> satisfiable by edsonmedina/php_testability[dev-master]. - Installation request for nikic/php-parser (locked at v3.0.6) -> satisfiable by nikic/php-parser[v3.0.6].

    opened by thekabal 5
  • PHP Notice:  Undefined property: PhpParser\Node\Expr\ArrayDimFetch::$name

    PHP Notice: Undefined property: PhpParser\Node\Expr\ArrayDimFetch::$name

    Follow on from #80.

    screenshot 2017-07-14 10 09 59

    PHP Notice:  Undefined property: PhpParser\Node\Expr\ArrayDimFetch::$name in /Users/gary/code/themes/genesis/vendor/edsonmedina/php_testability/src/NodeWrapper.php on line 79
    
    Notice: Undefined property: PhpParser\Node\Expr\ArrayDimFetch::$name in /Users/gary/code/themes/genesis/vendor/edsonmedina/php_testability/src/NodeWrapper.php on line 79
    PHP Notice:  Undefined property: PhpParser\Node\Expr\ArrayDimFetch::$name in /Users/gary/code/themes/genesis/vendor/edsonmedina/php_testability/src/NodeWrapper.php on line 85
    
    Notice: Undefined property: PhpParser\Node\Expr\ArrayDimFetch::$name in /Users/gary/code/themes/genesis/vendor/edsonmedina/php_testability/src/NodeWrapper.php on line 85
    

    Using -vvv, it suggests that the troublesome file is genesis-admin-boxes-holder.php.

    opened by GaryJones 4
  • parent::run() reported as static call.

    parent::run() reported as static call.

    Hi

    I've discovered that parent::run() is reported as a static call, I don't think this should be the case (if the part in front is parent just assume it's not a static call?)

    I'll gladly try to fix this myself and submit a Pull Request for it.

    opened by Archanium 4
  • Untestable files

    Untestable files

    Untestable files (no scopes to test) flag "code_on_global_space" on every line. And the header displays " ---- Testable" which is incorrect.

    bug blocked 
    opened by edsonmedina 4
  • Better metrics

    Better metrics

    Report metrics like:

    Files: 76% (152/200) Methods: 64% (192/300)

    Do this for CLI and HTML reports.

    This would be a million times more helpful than the current number of issues.

    enhancement working on it hard 
    opened by edsonmedina 2
  • abandoned?

    abandoned?

    Installing this project with composer yields the warning Package edsonmedina/php_testability is abandoned, you should avoid using it. No replacement was suggested. Any idea why?

    opened by bingalls 1
  • Fixing two issues: one documentation, one warning in NodeWrapper

    Fixing two issues: one documentation, one warning in NodeWrapper

    fixing documentation/help issue: csvtotals cmdline option does not take argument fixing wrong assumption in NodeWrapper class: that node is always set

    opened by Fake51 1
  • ReportData refactoring

    ReportData refactoring

    To include things like:

    • Number of processed files
    • Number of files completely testable
    • Number of untestable files (no classes/methods)
    • Number of processed functions/methods (per file)
    • Number of testable functions/methods (per file)
    • Number of processed/testable files and functions/methods (per dir)

    First steps:

    • Move factory into ReportData
    • AddIssue should only receive: $node and issue type
    • Scope should be queried inside addIssue
    • saveScopePosition() methods should be removed (scope should be saved inside startClass/Method/Function/Trait)
    working on it urgent Refactoring 
    opened by edsonmedina 1
  • Protected/private methods

    Protected/private methods

    They can't be directly tested (without using Reflection or RunKit), and only protected methods can be mocked (but not tested directly). So they should be flagged.

    enhancement trivial urgent 
    opened by edsonmedina 1
  • Bump mustache/mustache from 2.11.1 to 2.14.1

    Bump mustache/mustache from 2.11.1 to 2.14.1

    Bumps mustache/mustache from 2.11.1 to 2.14.1.

    Release notes

    Sourced from mustache/mustache's releases.

    Mustache.php v2.14.1 — Security release

    • Fix CVE-2022-0323, possible RCE when rendering untrusted user templates, reported by @​altm4n via huntr.dev
    • Improve compatibility with PHP 8.1

    Mustache.php v2.14.0

    Mustache.php v2.13.0

    • Fix notices on PHP 7.4 (Thanks @​tomjn, @​stronk7, and @​JoyceBabu!)
    • Fix a parse error in the delimiter change tag (e.g. {{=<% %>=}}) and throw a syntax error when it's invalid.
    • Improve Tokenizer::scan performance by 98.2%.
    • Test against all the PHPs in CI.

    Mustache.php v2.12.0

    • Prevent redundant Autoloader registration (Thanks @​hcpss-banderson!)
    • Add a ProductionFilesystemLoader, which doesn't read template file contents before every render.
    • Improve test coverage.
    • Fix a bug when rendering the same block names multiple times in one template.
    • Add a delimiters option for overriding default delimiters at the engine level.
    • Add validation to prevent empty template_class_prefix config.
    Commits
    • 579ffa5 Fix CVE-2022-0323 (improper neutralization of section names)
    • 0762097 Explicitly treat null as an empty string when interpolating.
    • 7fd191f Remove unused variable.
    • e7165a3 Only check for mbstring.func_overload in < PHP 8.x
    • 26c8a44 Fix PHP 8.1 deprecation warning when user lambdas do not return a string
    • 4e2724d Merge branch 'release/2.14.0'
    • 3ce0ee0 Bump to v2.14.0, bump spec version to 1.2.2
    • 6361644 Merge pull request #380 from schlessera/fix/trim-php-8.1
    • d6340c8 Update readme link
    • 1a125df Brevity.
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • PHP Catchable fatal error:  Object of class PhpParser\Node\Expr\BinaryOp\Concat

    PHP Catchable fatal error: Object of class PhpParser\Node\Expr\BinaryOp\Concat

    PHP_Testability by Edson Medina Analysing code on "/var/www/html/Fourmidados"... ............................................PHP Catchable fatal error: Object of class PhpParser\Node\Expr\BinaryOp\Concat could not be converted to string in /home/vagrant/vendor/edsonmedina/php_testability/src/NodeWrapper.php on line 74

    opened by cezarq 0
  • Uncaught Error: Class 'PhpParser\ParserFactory' not found

    Uncaught Error: Class 'PhpParser\ParserFactory' not found

    Hello guys,

    I have installed package via composer, try to run and got error:

    Fatal error:  Uncaught Error: Class 'PhpParser\ParserFactory' not found in {{projectPath}}/vendor/edsonmedina/php_testability/src/AnalyserFactory.php:15
    

    May it be something with a version of nikic/php-parser? You have "nikic/php-parser": "*" in composer JSON

    ENV: Mac OS X, PHP 7.0.19 Commit hash from composer output: 5e6d481

    opened by tuxoff 1
Owner
Edson Medina
Edson Medina
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
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
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
Library that provides collection, processing, and rendering functionality for PHP code coverage information.

phpunit/php-code-coverage Provides collection, processing, and rendering functionality for PHP code coverage information. Installation You can add thi

Sebastian Bergmann 8.5k Jan 5, 2023
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
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
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
PHP client for Selenium/WebDriver protocol. Previously facebook/php-webdriver

Php-webdriver library is PHP language binding for Selenium WebDriver, which allows you to control web browsers from PHP.

php-webdriver 4.7k Jan 3, 2023
The most powerful and flexible mocking framework for PHPUnit / Codeception.

AspectMock AspectMock is not an ordinary PHP mocking framework. With the power of Aspect Oriented programming and the awesome Go-AOP library, AspectMo

Codeception Testing Framework 777 Dec 12, 2022
Some shorthand functions for skipping and focusing tests.

Pest Plugin: Shorthands This repository contains the Pest Plugin Shorthands. If you want to start testing your application with Pest, visit the main P

Thomas Le Duc 10 Jun 24, 2022
The Phoronix Test Suite is the most comprehensive testing and benchmarking platform

The Phoronix Test Suite is the most comprehensive testing and benchmarking platform available for Linux, Solaris, macOS, Windows, and BSD operating systems.

Phoronix Test Suite 1.9k Jan 7, 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
PHPStan PHPUnit extensions and rules

PHPStan PHPUnit extensions and rules PHPStan PHPUnit This extension provides following features: createMock(), getMockForAbstractClass() and getMockFr

PHPStan 359 Dec 28, 2022