{"id":14985413,"url":"https://github.com/inventor96/fatfree-test-manager","last_synced_at":"2026-02-07T07:01:21.488Z","repository":{"id":56992821,"uuid":"346186863","full_name":"inventor96/fatfree-test-manager","owner":"inventor96","description":"A lightweight class to run and report the results from unit tests using the Fat-Free Framework Test class.","archived":false,"fork":false,"pushed_at":"2021-03-12T02:20:00.000Z","size":12,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-29T21:37:17.277Z","etag":null,"topics":["composer","fat-free-framework","fatfree-framework","fatfreeframework","testing","unit-testing"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/inventor96.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-10T00:45:45.000Z","updated_at":"2021-03-12T02:16:24.000Z","dependencies_parsed_at":"2022-08-21T10:40:38.546Z","dependency_job_id":null,"html_url":"https://github.com/inventor96/fatfree-test-manager","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/inventor96/fatfree-test-manager","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inventor96%2Ffatfree-test-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inventor96%2Ffatfree-test-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inventor96%2Ffatfree-test-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inventor96%2Ffatfree-test-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/inventor96","download_url":"https://codeload.github.com/inventor96/fatfree-test-manager/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inventor96%2Ffatfree-test-manager/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29188304,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T05:07:31.176Z","status":"ssl_error","status_checked_at":"2026-02-07T05:06:15.227Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["composer","fat-free-framework","fatfree-framework","fatfreeframework","testing","unit-testing"],"created_at":"2024-09-24T14:10:56.181Z","updated_at":"2026-02-07T07:01:21.467Z","avatar_url":"https://github.com/inventor96.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fat-Free Test Manager\nA lightweight class to run and report the results from unit tests using the [Fat-Free Framework `Test` class](https://fatfreeframework.com/3.7/test).\n\n## Installation\n```\ncomposer require --dev inventor96/fatfree-test-manager\n```\n\n## Usage\nThe goal of this tool is to be as simple and lightweight as possible.\n\n### Overview\nThe idea is that we'll scan one folder (non-recursively) for all files that end with `Test.php` (e.g. `MyAwesomeTest.php`). For each of the files found, we find the first class definition, instantiate that class, and then call all public methods in that class that start with `test` (e.g. `public function testIfThisWorks() { ... }`).\n\nWith this structure in place, simply call `TestManager::runAndReportTests('directory/with/test/files');`.\n\n### Extending `TestBase`\nThe test classes must extend `TestBase`, directly or indirectly. If indirectly (the test classes extend another class that extends `TestBase`), the constructor of the class(es) in the middle will want to pass an array as the second parameter to the parent constructor of class names that includes their own. This will allow the report to include the correct class and method name of the testing method.\n\nFor example:\n```php\nclass MyTestBase extends TestBase {\n\tpublic function __construct(\\Test \u0026$test_instance) {\n\t\tparent::__construct($test_instance, [get_class()]);\n\t}\n}\n```\n\n### Running code before/after test classes and methods\nIf a test class (or a class it extends) has a method named `preClass()`, `preTest()`, `postTest()`,  or `postClass()`; each method will be called at the respective time.\n\n| Method | Called Time |\n| ------ | ----------- |\n| `preClass()` | Immediately after the class is instantiated |\n| `preTest()` | Before each `test*()` method in the class |\n| `postTest()` | After each `test*()` method in the class |\n| `postClass()` | After all tests in the class have been run, and `postTest()` has been called (if present) |\n\n### Multiple Folders\nIf you have more than one folder with tests, you can create an instance of the [Fat-Free Framework `Test` class](https://fatfreeframework.com/3.7/test) and call `TestManager::runTests('a/directory/with/tests', $your_instance_of_Test);` for each directory, then call `TestManager::reportTests($your_instance_of_Test);` at the end.\n\n### Exit Codes\nBy default, `runAndReportTests()` and `reportTests()` will end the PHP process with an exit code of 1 if there were failed tests, or 0 if all were successful. To disable this behavior and allow the script to continue, set the last parameter to `false`.\n\n## General Example\n`example_dir/ExampleTest.php`:\n```php\n\u003c?php\n\nuse inventor96\\F3TestManager\\TestBase;\n\nclass ExampleTest extends TestBase {\n\tprivate $pre_class_called = 0;\n\tprivate $post_class_called = 0;\n\tprivate $pre_test_called = 0;\n\tprivate $post_test_called = 0;\n\n\tpublic function preClass() {\n\t\t$this-\u003epre_class_called++;\n\t}\n\n\tpublic function postClass() {\n\t\t$this-\u003epost_class_called++;\n\n\t\techo \"preClass() called: {$this-\u003epre_class_called}\".PHP_EOL;\n\t\techo \"postClass() called: {$this-\u003epost_class_called}\".PHP_EOL;\n\t\techo \"preTest() called: {$this-\u003epre_test_called}\".PHP_EOL;\n\t\techo \"postTest() called: {$this-\u003epost_test_called}\".PHP_EOL;\n\t}\n\n\tpublic function preTest() {\n\t\t$this-\u003epre_test_called++;\n\t}\n\n\tpublic function postTest() {\n\t\t$this-\u003epost_test_called++;\n\t}\n\n\tprivate function testThisShouldNeverGetCalled() {\n\t\t// private methods should never get called by the TestManager\n\t\t$this-\u003eexpect(false, 'This is not the method you are looking for...');\n\t}\n\n\tpublic function testPassExample() {\n\t\t$this-\u003eexpect(true, 'the message for a passing test');\n\t}\n\n\tpublic function testFailExample() {\n\t\t$this-\u003eexpect(false, 'the message for a failed test');\n\t}\n\n\tpublic function testPassAndFailExample() {\n\t\t$this-\u003eexpect(true);\n\t\t$this-\u003eexpect(false);\n\t}\n\n\tpublic function testWithException() {\n\t\tthrow new Exception(\"This is the message for an exception\");\n\t}\n}\n```\n\n`example_dir/test_runner.php`:\n```php\n\u003c?php\n\nuse inventor96\\F3TestManager\\TestManager;\n\nrequire_once('../vendor/autoload.php');\n\necho PHP_EOL.\"Running tests using separate calls.\".PHP_EOL;\n$test1 = new Test();\nTestManager::runTests(__DIR__, $test1);\nTestManager::reportTests($test1, false);\n\necho PHP_EOL.\"Running tests using one call.\".PHP_EOL;\nTestManager::runAndReportTests(__DIR__);\n```\n\nRunning the tests would look like this:\n```\n$ php test_runner.php \n\nRunning tests using separate calls.\npreClass() called: 1\npostClass() called: 1\npreTest() called: 4\npostTest() called: 4\nPASS: ExampleTest::testPassExample() // ExampleTest.php:38 - the message for a passing test\nFAIL: ExampleTest::testFailExample() // ExampleTest.php:42 - the message for a failed test\nPASS: ExampleTest::testPassAndFailExample() // ExampleTest.php:46\nFAIL: ExampleTest::testPassAndFailExample() // ExampleTest.php:47\nFAIL: ExampleTest::testWithException() // ExampleTest.php:51 - Exception: This is the message for an exception\n\nRunning tests using one call.\npreClass() called: 1\npostClass() called: 1\npreTest() called: 4\npostTest() called: 4\nPASS: ExampleTest::testPassExample() // ExampleTest.php:38 - the message for a passing test\nFAIL: ExampleTest::testFailExample() // ExampleTest.php:42 - the message for a failed test\nPASS: ExampleTest::testPassAndFailExample() // ExampleTest.php:46\nFAIL: ExampleTest::testPassAndFailExample() // ExampleTest.php:47\nFAIL: ExampleTest::testWithException() // ExampleTest.php:51 - Exception: This is the message for an exception\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finventor96%2Ffatfree-test-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finventor96%2Ffatfree-test-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finventor96%2Ffatfree-test-manager/lists"}