{"id":15109581,"url":"https://github.com/humbug/humbug","last_synced_at":"2025-09-27T10:31:47.106Z","repository":{"id":24884790,"uuid":"28300862","full_name":"humbug/humbug","owner":"humbug","description":"Humbug is a Mutation Testing framework for PHP to measure the real effectiveness of your test suites and assist in their improvement. It eats Code Coverage for breakfast.","archived":true,"fork":false,"pushed_at":"2017-12-31T15:29:08.000Z","size":991,"stargazers_count":1133,"open_issues_count":43,"forks_count":73,"subscribers_count":58,"default_branch":"master","last_synced_at":"2024-09-21T17:35:36.957Z","etag":null,"topics":["coverage","mutation-analysis","mutation-testing","php","testing"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/humbug.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-12-21T13:42:47.000Z","updated_at":"2024-05-31T03:33:50.000Z","dependencies_parsed_at":"2022-08-21T12:50:17.905Z","dependency_job_id":null,"html_url":"https://github.com/humbug/humbug","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humbug%2Fhumbug","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humbug%2Fhumbug/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humbug%2Fhumbug/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humbug%2Fhumbug/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/humbug","download_url":"https://codeload.github.com/humbug/humbug/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219871972,"owners_count":16554475,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coverage","mutation-analysis","mutation-testing","php","testing"],"created_at":"2024-09-25T23:05:10.810Z","updated_at":"2025-09-27T10:31:41.779Z","avatar_url":"https://github.com/humbug.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"Humbug: Mutation Testing for PHP\n================================\n\n🚨 This package is deprecated, check out [Infection](https://github.com/infection/infection) instead.\n\nHumbug is a Mutation Testing framework for PHP. It is currently in development and\nso, while it does actually work quite well, it will have rough edges that a team\nof minions are working hard to hammer out. If it falls out of the gate, you have \nbeen warned ;).\n\n[![Build Status](https://travis-ci.org/humbug/humbug.svg)](https://travis-ci.org/humbug/humbug) [![Build status](https://ci.appveyor.com/api/projects/status/j1v1iwcv5o8ohb7p/branch/master?svg=true)](https://ci.appveyor.com/project/humbug/humbug/branch/master) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/humbug/humbug/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/humbug/humbug/?branch=master)\n[![StyleCI](https://styleci.io/repos/28300862/shield?style=flat)](https://styleci.io/repos/28300862) [![Total Downloads](https://poser.pugx.org/humbug/humbug/downloads.png)](https://packagist.org/packages/humbug/humbug)\n[![Slack](https://img.shields.io/badge/slack-%23humbug-red.svg?style=flat-square)](https://symfony.com/slack-invite)\n\n⚠️️ Update your remotes! Humbug has transferred to a new location. While your\nexisting repositories will redirect transparently for any operations, take some\ntime to transition to the new URL.\n```sh\n$ git remote set-url upstream https://github.com/humbug/humbug.git\n```\nReplace `upstream` with the name of the remote you use locally; `upstream` is commonly\nused but you may be using something else. You may also using a different URL (e.g. git@github.com:mockery/mockery.git).\nRun `git remote -v` to see what you're actually using.\n\n**Table of Contents**\n\n- [Introduction](#introduction)\n- [Contributing](#contributing)\n- [Installation](#installation)\n\t- [Git](#git)\n\t- [Phar](#phar)\n\t- [Composer](#composer)\n- [Usage](#usage)\n\t- [Configuration](#configuration)\n\t\t- [Configure command](#configure-command)\n\t\t- [Manual Configuration](#manual-configuration)\n\t- [Running Humbug](#running-humbug)\n\t\t- [The Metrics](#the-metrics)\n- [Command Line Options](#command-line-options)\n\t- [Overriding The Configured Timeout](#overriding-the-configured-timeout)\n\t- [Restricting Files To Mutate](#restricting-files-to-mutate)\n\t- [Mutate specific files](#mutate-specific-files)\n\t- [Incremental Analysis](#incremental-analysis)\n- [Performance](#performance)\n- [Mutators](#mutators)\n\nIntroduction\n------------\n\nMutation Testing is, in a nutshell, giving your unit tests a run for their money.\nIt involves injecting small defects into source code and then checking if the unit\ntests noticed. If they do, then your unit tests have \"killed\" the mutation. If not,\nthe mutation has escaped detection. As unit tests are intended to prevent regressions,\nhaving a real regression pass unnoticed would be a bad thing!\n\nWhereas Code Coverage can tell you what code your tests are executing, Mutation\nTesting is intended to help you judge how well your unit tests actually perform\nand where they could be improved.\n\nI've written in more detail about why Mutation Testing is worth having: [Lies, Damned Lies and Code Coverage: Towards Mutation Testing](http://padraic.github.io/humbug.html)\n\nContributing\n------------\n\nHumbug is an open source project that welcomes pull requests and issues from anyone.\nBefore opening pull requests, please read our short [Contribution Guide](https://github.com/humbug/humbug/blob/master/.github/CONTRIBUTING.md).\n\n\nInstallation\n------------\n\n#### Git\n\nYou can clone and install Humbug's dependencies using Composer:\n\n```sh\ngit clone https://github.com/humbug/humbug.git\ncd humbug\n/path/to/composer.phar install\n```\n\nThe humbug command is now at bin/humbug.\n\n#### Phar\n\nIf you don't want to track the master branch directly, you can install the Humbug\nphar as follows:\n\n```sh\nwget https://padraic.github.io/humbug/downloads/humbug.phar\nwget https://padraic.github.io/humbug/downloads/humbug.phar.pubkey\n# If you wish to make humbug.phar directly executable\nchmod +x humbug.phar\n```\n\nOn Windows, you can just download using a browser or from Powershell v3 using the\nfollowing commands where `wget` is an alias for `Invoke-WebRequest`:\n\n```sh\nwget https://padraic.github.io/humbug/downloads/humbug.phar -OutFile humbug.phar\nwget https://padraic.github.io/humbug/downloads/humbug.phar.pubkey -OutFile humbug.phar.pubkey\n```\n\nIf you're stuck with Powershell v2:\n\n```sh\n$client = new-object System.Net.WebClient\n$client.DownloadFile(\"https://padraic.github.io/humbug/downloads/humbug.phar\", \"humbug.phar\")\n$client.DownloadFile(\"https://padraic.github.io/humbug/downloads/humbug.phar.pubkey\", \"humbug.phar.pubkey\")\n```\n\n##### PHAR Updates\n\nThe phar is signed with an openssl private key. You will need the pubkey file\nto be stored beside the phar file at all times in order to use it. If you rename\n`humbug.phar` to `humbug`, for example, then also rename the key from\n`humbug.phar.pubkey` to `humbug.pubkey`.\n\nThe phar releases are currently done manually so they will not be updated with the\nsame frequency as git master. To update your current phar, just run:\n\n```sh\n./humbug.phar self-update\n```\n\nNote: Using a phar means that fixes may take longer to reach your version, but there's\nmore assurance of having a stable development version. The public key is\ndownloaded only once. It is re-used by self-update to verify future phar releases.\n\nOnce releases commence towards stable, there will be an alpha, beta, RC and a final\nrelease. Your development track phar file will self-update automatically until\nit reaches a stable release. If you wish to continue tracking the development\nlevel phars, you will need to indicate this using one of the stability flags:\n\n```sh\n./humbug.phar self-update --dev\n```\n\n###### Self-Update Request Debugging\n\nIf you experience any issues self-updating with unexpected `openssl` or SSL errors,\nplease ensure that you have enabled the `openssl` extension. On Windows, you can\ndo this by adding or uncommenting the following line in the `php.ini` file for\nPHP on the command line (if different than the file for your http server):\n\n```\nextension=php_openssl.dll\n```\n\nCertain other SSL errors may arise due missing certificates. You can rectify this\nby finding their location on your system (e.g. `C:/xampp/php/ext/cacert.pem`), or\nalternatively downloading a copy from http://curl.haxx.se/ca/cacert.pem. Then\nensure the following option is correctly pointing to this file:\n\n```\nopenssl.cafile=C:/path/to/cacert.pem\n```\n\n#### Composer\n\nDue to Humbug's dependencies being pegged to recent versions, adding Humbug to\ncomposer.json may give rise to conflicts. The above two methods of installation are\npreferred where this occurs. You can however install it globally as any other\ngeneral purpose tool:\n\n```sh\ncomposer global require 'humbug/humbug=~1.0@dev'\n```\n\nAnd if you haven't done so previously...add this to `~/.bash_profile` (or `~/.bashrc`):\n\n```sh\nexport PATH=~/.composer/vendor/bin:$PATH\n```\n\nHumbug currently works on PHP 5.4 or greater.\n\nUsage\n-----\n\n### Configuration\n\nHumbug is still under development so, to repeat, beware of rough edges.\n\n#### Configure command\n\nTo configure humbug in your project you may run: \n\n```sh\nhumbug configure\n```\n\nThis tool will ask some questions required to create the Humbug configuration file\n(`humbug.json.dist`).\n\n#### Manual Configuration\n\nIn the base directory of your project create a `humbug.json.dist` file:\n\n```js\n{\n    \"timeout\": 10,\n    \"source\": {\n        \"directories\": [\n            \"src\"\n        ]\n    },\n    \"logs\": {\n        \"text\": \"humbuglog.txt\",\n        \"json\": \"humbuglog.json\"\n    }\n}\n```\n\nYou can commit the `humbug.json.dist` to your VCS and override it locally with a\n`humbug.json` file.\n\nEdit as appropriate. If you do not define at least one log, detailed information\nabout escaped mutants will not be available. The Text log is human readable.\nIf source files exist in the base directory, or files in the source directories\nmust be excluded, you can add exclude patterns (here's one for files in base\ndirectory where composer vendor and Tests directories are excluded):\n\n```js\n{\n    \"timeout\": 10,\n    \"source\": {\n        \"directories\": [\n            \".\"\n        ],\n        \"excludes\": [\n            \"vendor\",\n            \"Tests\"\n        ]\n    },\n    \"logs\": {\n        \"text\": \"humbuglog.txt\"\n    }\n}\n```\n\nIf, from your project's base directory, you must run tests from another directory\nthen you can signal this also. You should not need to run Humbug from any directory\nother than your project's base directory.\n\n```js\n{\n    \"chdir\": \"tests\",\n    \"timeout\": 10,\n    \"source\": {\n        \"directories\": [\n            \"src\"\n        ],\n    }\n}\n```\n\n### Running Humbug\n\nEnsure that your tests are all in a passing state (incomplete and skipped tests\nare allowed). Humbug will quit if any of your tests are failing.\n\nThe magic command, while in your project's base directory (using the PHAR download) is:\n\n```sh\n./humbug.phar\n```\n\nor if you just cloned Humbug:\n\n```sh\n../humbug/bin/humbug\n```\n\nor if you added Humbug as a composer dependency to your project:\n\n```sh\n./vendor/bin/humbug\n```\n\nInstead of php with the xdebug extension you may also run Humbug via [phpdbg](http://phpdbg.com/):\n\n```sh\nphpdbg -qrr humbug.phar\n```\n\nIf all went well, you will get something similar to:\n\n```\n _  _            _\n| || |_  _ _ __ | |__ _  _ __ _\n| __ | || | '  \\| '_ \\ || / _` |\n|_||_|\\_,_|_|_|_|_.__/\\_,_\\__, |\n                          |___/ \nHumbug version 1.0-dev\n\nHumbug running test suite to generate logs and code coverage data...\n\n  361 [==========================================================] 28 secs\n\nHumbug has completed the initial test run successfully.\nTests: 361 Line Coverage: 64.86%\n\nHumbug is analysing source files...\n\nMutation Testing is commencing on 78 files...\n(.: killed, M: escaped, S: uncovered, E: fatal error, T: timed out)\n\n.....M.M..EMMMMMSSSSMMMMMSMMMMMSSSE.ESSSSSSSSSSSSSSSSSM..M.. |   60 ( 7/78)\n...MM.ES..SSSSSSSSSS...MMM.MEMME.SSSS.............SSMMSSSSM. |  120 (12/78)\nM.M.M...TT.M...T.MM....S.....SSS..M..SMMSM...........M...... |  180 (17/78)\nMM...M...ESSSEM..MMM.M.MM...SSS.SS.M.SMMMMMMM..SMMMMS....... |  240 (24/78)\n.........SMMMSMMMM.MM..M.SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS |  300 (26/78)\nSSSSSSSSM..E....S......SS......M.SS..S..M...SSSSSSSS....MMM. |  360 (37/78)\n.M....MM..SM..S..SSSSSSSS.EM.S.E.M............M.....M.SM.M.M |  420 (45/78)\n..M....MMS...MMSSS................M.....EME....SEMS...SSSSSS |  480 (52/78)\nSSSSS.EMSSSSM..M.MMMM...SSE.....MMM.M..MM..MSSSSSSSSSSSSSSSS |  540 (60/78)\nSSS....SSSSSSSSMM.SSS..........S..M..MSSMS.SSSSSSSSSSSSSSSSS |  600 (68/78)\n......E...M..........SM.....M..MMMMM.MMMMMSSSSSSSM.SS\n\n653 mutations were generated:\n     284 mutants were killed\n     218 mutants were not covered by tests\n     131 covered mutants were not detected\n      17 fatal errors were encountered\n       3 time outs were encountered\n\nMetrics:\n    Mutation Score Indicator (MSI): 47%\n    Mutation Code Coverage: 67%\n    Covered Code MSI: 70%\n\nRemember that some mutants will inevitably be harmless (i.e. false positives).\n\nHumbug results are being logged as JSON to: log.json\nHumbug results are being logged as TEXT to: log.txt\n```\n\nTo explain the perhaps cryptic progress output:\n* Killed Mutation (.): A mutation that caused unit tests to fail which is a positive\noutcome.\n* Escaped Mutation (M): A mutation where the unit tests still passed which is not\nwhat we want! Our unit tests should detect any behaviour changes.\n* Uncovered Mutation (S): A mutation which occurs on a line not covered by any unit\ntest. Since there are no unit tests, this is another undesireable result.\n* Fatal Error (E): A mutation created a fatal error. Usually a positive result since\nit's obviously going to be noticed. In some cases, however, it might be a Humbug\nproblem that needs fixing.\n* Timeout (T): This is where unit tests exceed the allowed timeout configured for\nHumbug. Likely a positive result if your timeout is appropriate, and often occurs\nwhen a mutation ends up creating an infinite loop.\n\nKills, errors and timeouts are all counted as detected mutations. We report errors\nin the logs on the off chance that Humbug itself encountered an internal error, i.e.\na bug to be reported as an issue here!\n\n#### The Metrics\n\nThe example summary results reported a number of metric scores:\n* A Mutation Score Indicator (MSI) of 47%. This means that 47% of all generated\nmutations were detected (i.e. kills, timeouts or fatal errors). The MSI is the\nprimary Mutation Testing metric. Given the code coverage of 65%, there is a 18%\ndiscrepancy so Code Coverage was a terrible quality measurement in this example.\n* Mutation Code Coverage is 67%. On average it should be within the same ballpark\nas your normal code coverage, but code coverage ignores mutation frequency.\n* The Mutation Score Indicator for code that is actually covered by tests was 70%\n(i.e. ignoring code not even tested). This gives you some idea of how effective\nthe tests that do exist really are.\n\nIf you examine these metrics, the standout issue is that the MSI of 47% is 18 points\nlower than the reported Code Coverage at 65%. These unit tests are far less effective\nthan Code Coverage alone could detect.\n\nInterpreting these results requires some context. The logs will list all undetected\nmutations as diffs against the original source code. Examining these will provide\nfurther insight as to what specific mutations went undetected.\n\nCommand Line Options\n--------------------\n\nHumbug has a few command line options of note, other than those normally associated\nwith any Symfony Console application.\n\n#### Overriding The Configured Timeout\n\nYou can manually set the timeout threshold for any single test:\n\n```sh\nhumbug --timeout=10\n```\n\n#### Restricting Files To Mutate\n\nIf you're only interested in mutating a subset of your files, you can pass\nany number of `--file` options containing simple file names, globs or regular\nexpressions. Basically, these are all passed to the Symfony Finder's `name()`\nmethod.\n\n```sh\nhumbug --file=NewClass.php --file=*Driver.php\n```\n\nThis in no way restricts the initial Humbug check on the overall test suite which\nis still executed in full to ensure all tests are passing correctly before\nproceeding.\n\n#### Mutate specific files\n\nIf you want to mutate only a few specific files, you can pass \nany number of `--path` options containing full path file names. This option will be passed \nto a filter `\\Closure` that will intersect files found using the config and/or `--file` option\n with the files provided by you using the `--path` option.\n\n```sh\nhumbug --path=src/Data/NewClass.php --path=src/Driver/Driver.php\n```\n\nNote: This in no way restricts the initial Humbug check on the overall test suite which\nis still executed in full to ensure all tests are passing correctly before\nproceeding.\n\n#### Incremental Analysis\n\nIncremental Analysis (IA) is an experimental unfinished mode of operation where results\nare cached locally between runs and reused where it makes sense. At present, this\nmode operates very naively by eliminating test runs where both the immediate file\nbeing mutated and the relevant tests for a mutated line have not been modified\nsince the last run (as determined by comparing the SHA1 of the files involved).\n\n```sh\nhumbug --incremental\n```\n\nThe IA mode offers a significant performance increase for relatively stable code\nbases, and you're free to test it and see how it fares in real life. In the future,\nit does need to take into accounts changes in files which contain parent classes,\nimported traits and the classes of its immediate dependencies, all of which have\nan impact on the behaviour of any given object.\n\nIA utilises a local permanent cache, e.g. `/home/padraic/.humbug`.\n\nPerformance\n-----------\n\nMutation Testing has traditionally been slow. The concept being to re-run your test\nsuite for each mutation generated. To speed things up significantly, Humbug does the\nfollowing:\n\n* On each test run, it only uses those test classes which cover the specific file\nand line on which the mutation was inserted.\n* It orders test classes to run so that the slowest go last (hopefully the faster\ntests will detect mutations early!).\n* If a mutation falls on a line not covered by any tests, well, we don't bother\nrunning any tests.\n* Performance may, depending on the source code, be significantly impacted by timeouts.\nThe default of 60s may be far too high for smaller codebases, and far too low for\nlarger ones. As a rule of thumb, it shouldn't exceed the seconds needed to\nnormally run the tests being mutated (and can be set lower).\n\nWhile all of this speeds up Humbug, do be aware that a Humbug run will be slower than\nunit testing. A 2 second test suite may require 30 seconds for mutation testing. Or\n5 minutes. It all depends on the interplay between lines of code, number of tests,\nlevel of code coverage, and the performance of both code and tests.\n\nMutators\n--------\n\nHumbug implements a basic suite of Mutators, which essentially tells us when a\nparticular PHP token can be mutated, and also apply that mutation to an array\nof tokens.\n\nNote: Source code held within functions (rather than class methods) is not mutated\nat this time.\n\nBinary Arithmetic:\n\n| Original | Mutated | Original | Mutated |\n| :------: |:-------:| :------: |:-------:| \n| + | - | /= | *= |\n| - | + | %= | *= |\n| * | / | **= | /= |\n| / | * | \u0026 | \u0026#124; |\n| % | * | \u0026#124; | \u0026 |\n| ** | / | ^ | \u0026 |\n| += | -= | ~ |  |\n| -= | += | \u003e\u003e | \u003c\u003c |\n| *= | /= | \u003c\u003c | \u003e\u003e |\n\nBoolean Substitution:\n\nThis temporarily encompasses logical mutators.\n\n| Original | Mutated |\n| :------: |:-------:| \n| true | false |\n| false | true |\n| \u0026\u0026 | \u0026#124;\u0026#124; |\n| \u0026#124;\u0026#124; | \u0026\u0026 |\n| and | or |\n| or | and |\n| ! |  |\n\nConditional Boundaries:\n\n| Original | Mutated\n| :------: |:-------:\n| \u003e        | \u003e=\n| \u003c        | \u003c=\n| \u003e=       | \u003e\n| \u003c=       | \u003c\n\nNegated Conditionals:\n\n| Original | Mutated | Original | Mutated |\n| :------: |:-------:| :------: |:-------:| \n| == | != | \u003e | \u003c= |\n| != | == | \u003c | \u003e= |\n| \u003c\u003e | == | \u003e= | \u003c |\n| === | !== | \u003c= | \u003e |\n| !== | === |\n\nIncrements:\n\n| Original | Mutated |\n| :------: |:-------:| \n| ++ | -- |\n| -- | ++ |\n\nReturn Values:\n\n| Original | Mutated | Original | Mutated |\n| :------: |:-------:| :------: |:-------:|\n| return true; | return false; | return \u003cAny Float \u003e 1.0\u003e; | return -(\u003cFloat\u003e + 1); |\n| return false; | return true; | return $this; | return null; |\n| return 0; | return 1; | return function(); | function(); return null; |\n| return \u003cAny Integer\u003e; | return 0; | return new Class; | new Class; return null; |\n| return 0.0; | return 1.0; | return (`Anything`); | (`Anything`); return null; |\n| return 1.0; | return 0.0; |\n\nLiteral Numbers:\n\n| Original | Mutated |\n| :------: |:-------:| \n| 0 | 1 |\n| 1 | 0 |\n| Int \u003e 1 | Int + 1 |\n| Float \u003e= 1 / \u003c= 2 | Float + 1 |\n| Float \u003e 2 | 1 |\n\nIf Statements:\n\nAll if statements are covered largely by previous mutators, but there are special\ncases such as using native functions or class methods without any compares or operations, e.g.\n`is_int()` or `in_array()`. This would not cover functions defined in files since\nthey don't exist until runtime (something else to work on!).\n\n| Original | Mutated |\n| :------: |:-------:| \n| if(is_int(1)) | if(!is_int(1)) |\n\nMore Mutators will be added over time.\n\nJSON Log Stats\n--------------\n\n```sh\nbin/humbug stats ../my-project/humbuglog.json ../my-project/list-of-classes.txt --skip-killed=yes [-vvv]\n```\n\nParses stats from humbuglog.json or your custom named JSON log.\n\nCLI reference:\n```sh\nhumbug stats [humbuglog.json location] [class list location] [--skip-killed=yes] [-vvv]\n```\n\n    humbuglog.json location, defaults to ./humbuglog.json\n\n    class list location, a path to a text file containing full class names, one per line.\n\n    only this files-related stats would be shown\n    --skip-killed=yes is used to completely skip output of \"killed\" section\n    various verbosity levels define amount of info to be displayed:\n        by default, there's one line per class with amount of mutants killed/escaped/errored/timed out (depending on output section)\n        -v adds one line per each mutant with line number and method name\n        -vv adds extra line for each mutant, displaying diff view of line mutant is detected in\n        -vvv shows full diff with several lines before and after\n\nThis can be tested on humbug itself, by running in humbug's dir:\n\nbin/humbug\nbin/humbug stats [-vvv]\n\n\nDid I Say Rough Edges?\n----------------------\n\nThis is a short list of known issues:\n\n* Humbug does initial test runs, logging and code coverage. Should allow user to do that optionally.\n* Test classes (not tests) are run in a specific order, fastest first. Interdependent test classes may\ntherefore fail regularly which will skew the results.\n* Currently 100% PHPUnit specific, well 98.237%. There is an adapter where PHPUnit code is being shovelled.\n* Certain test suite may make assumptions about having sole access to resources like /tmp which\nwill cause errors when Humbug tries using same.\n* Fine grained test ordering by speed (as opposed to large grained test class ordering) is awaiting\nimplementation.\n* Should test classes be used to carry non-PHPUnit dependent testing code (e.g. register_shutdown_function()),\nit may create issues when combined with one or more of Humbugs optimisations which assume a finished\ntest really is finished.\n\nBah, Humbug!\n============\n\nCourtesy of [Craig Davis](https://github.com/craig-davis) who saw potential in a once empty repository :P.\n\n```\n                    .:::::::::::...\n                  .::::::::::::::::::::.\n                .::::::::::::::::::::::::.\n               ::::::::::::::::::::::::::::.\n              :::::::::::::::::::::::::::::::  .,uuu   ...\n             :::::::::::::::::::::::::::::::: dHHHHHLdHHHHb\n       ....:::::::'`    ::::::::::::::::::' uHHHHHHHHHHHHHF\n   .uHHHHHHHHH'         ::::::::::::::`.  uHHHHHHHHHHHHHP\"\n   HHHHHHHHHHH          `:::::::::::',dHHuHHHHHHHHP\".g@@g\n  J\"HHHHHHHHHP        4H ::::::::'  u$$$.\n  \".HHHHHHHHP\"     .,uHP :::::' uHHHHHHHHHHP\"\",e$$$$$c\n   HHHHHHHF'      dHHHHf `````.HHHHHHHHHHP\",d$$$$$$$P%C\n .dHHHP\"\"         JHHHHbuuuu,JHHHHHHHHP\",d$$$$$$$$$e=,z$$$$$$$$ee..\n \"\"              .HHHHHHHHHHHHHHHHHP\",gdP\"  ..3$$$Jd$$$$$$$$$$$$$$e.\n                 dHHHHHHHHHHHHHHP\".edP    \" .zd$$$$$$$$$$$\"3$$$$$$$$c\n                 `???\"\"??HHHHP\",e$$F\" .d$,?$$$$$$$$$$$$$F d$$$$$$$$F\"\n                       ?be.eze$$$$$\".d$$$$ $$$E$$$$P\".,ede`?$$$$$$$$\n                      4.\"?$$$$$$$  z$$$$$$ $$$$r.,.e ?$$$$ $$$$$$$$$\n                      '$c  \"$$$$ .d$$$$$$$ 3$$$.$$$$ 4$$$ d$$$$P\"`,,\n                       \"\"\"- \"$$\".`$$\"    \" $$f,d$$P\".$$P zeee.zd$$$$$.\n                     ze.    .C$C\"=^\"    ..$$$$$$P\".$$$'e$$$$$P?$$$$$$\n                 .e$$$$$$$\"=\"$f\",c,3eee$$$$$$$$P $$$P'd$$$$\"..::..\"?$%\n                4d$$$P d$$$dF.d$$$$$$$$$$$$$$$$f $$$ d$$$\" :::::::::.\n               $$$$$$ d$$$$$ $$$$$$$$$$$$$$$$$$ J$$\",$$$'.::::::::::::\n              \"$$$$$$ ?$$$$ d$$$$$$$$$$$$$$$P\".dP'e$$$$':::::::::::::::\n              4$$$$$$c $$$$b`$$$$$$$$$$$P\"\",e$$\",$$$$$' ::::::::::::::::\n              ' ?\"?$$$b.\"$$$$.?$$$$$$P\".e$$$$F,d$$$$$F ::::::::::::::::::\n                    \"?$$bc.\"$b.$$$$F z$$P?$$\",$$$$$$$ ::::::::::::::::::::\n                        `\"$$c\"?$$$\".$$$)e$$F,$$$$$$$' ::::::::::::::::::::\n                        ':. \"$b...d$$P4$$$\",$$$$$$$\" :::::::::::::::::::::\n                        ':::: \"$$$$$\".,\"\".d$$$$$$$F ::::::::::::::::::::::\n                         :::: be.\"\".d$$$4$$$$$$$$F :::::::::::::::::::::::\n                          :::: \"??$$$$$$$$$$?$P\" :::::::::::::::::::::::::\n                           :::::: ?$$$$$$$$f .::::::::::::::::::::::::::::\n                            :::::::`\"????\"\".::::::::::::::::::::::::::::::\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhumbug%2Fhumbug","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhumbug%2Fhumbug","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhumbug%2Fhumbug/lists"}