diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..729b662 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,39 @@ +name: Tests + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test: + name: PHP ${{ matrix.php-version }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php-version: ['8.2', '8.3', '8.4'] + + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: none + tools: composer:v2 + + - name: Validate composer.json + run: composer validate --strict + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: Check coding standards + run: composer cs-check + + - name: Run tests + run: composer test diff --git a/.gitignore b/.gitignore index 416985d..14db4cc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,9 @@ vendor/ composer.lock .project +.idea/ +.vscode/ +.DS_Store +.phpunit.cache/ +.phpunit.result.cache +.php-cs-fixer.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..93be12f --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,19 @@ +in([__DIR__ . '/lib', __DIR__ . '/tests']); + +return (new PhpCsFixer\Config()) + ->setRiskyAllowed(true) + ->setRules([ + '@PSR12' => true, + 'declare_strict_types' => true, + 'strict_param' => true, + 'array_syntax' => ['syntax' => 'short'], + 'ordered_imports' => true, + 'no_unused_imports' => true, + 'trailing_comma_in_multiline' => true, + ]) + ->setFinder($finder); diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 991f324..0000000 --- a/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: php -php: - - 5.4 - - 5.5 - - 5.6 - - nightly -script: - - php composer.phar self-update - - php composer.phar install --dev - - ./vendor/bin/phpunit diff --git a/README.md b/README.md index f2b8f9e..e2fea9e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# PHPUnit Skeleton [![Build Status](https://travis-ci.org/jasdeepkhalsa/phpunit-skeleton.svg)](https://travis-ci.org/jasdeepkhalsa/phpunit-skeleton) +# PHPUnit Skeleton [![Tests](https://github.com/jasdeepkhalsa/phpunit-skeleton/actions/workflows/tests.yml/badge.svg)](https://github.com/jasdeepkhalsa/phpunit-skeleton/actions/workflows/tests.yml) + _Get up and running with PHPUnit testing easily for your project with this skeleton_ * Are you frustrated with trying to install and configure PHPUnit? @@ -9,60 +10,68 @@ Well, I'm happy to let you know that you just need to `clone` this repo and all We have also included a sample PHP class so you can learn a few tricks in how to use PHPUnit in your projects! -## Simple-tastic 3 Step Installation ## -* Open a Terminal. Download the repo with `git clone https://github.com/jasdeepkhalsa/phpunit-skeleton.git` -* `cd` into where you downloaded your repo and run `php composer.phar self-update` -* Now, run `php composer.phar install --dev` +## Requirements ## +* PHP 8.2 or higher +* [Composer](https://getcomposer.org/) -Note: `php` refers to the location of your php executable, if its not on your system's path +## Simple-tastic 2 Step Installation ## +* Open a Terminal. Download the repo with `git clone https://github.com/jasdeepkhalsa/phpunit-skeleton.git` +* `cd` into where you downloaded your repo and run `composer install` ## Run PHPUnit ## * Open a Terminal * `cd` to your project root -* Type `./vendor/bin/phpunit` and...magic! Tests (should) now be running! +* Run `composer test` (or `./vendor/bin/phpunit` directly) and...magic! Tests (should) now be running! You should see something like... - PHPUnit 3.7.19 by Sebastian Bergmann. - - Configuration read from /(directory)/phpunit-skeleton/phpunit.xml - - .... - - Time: 0 seconds, Memory: 3.00Mb - - OK (4 tests, 4 assertions) - -## Customizing PHPUnit Skeleton ## +``` +PHPUnit 11.x by Sebastian Bergmann and contributors. + +Runtime: PHP 8.3.x +Configuration: /(directory)/phpunit-skeleton/phpunit.xml + +.. 2 / 2 (100%) + +Time: 00:00.010, Memory: 8.00 MB + +OK (2 tests, 3 assertions) +``` + +## Checking coding standards ## +This skeleton ships with [PHP-CS-Fixer](https://cs.symfony.com/) configured for the PSR-12 coding standard. + +* Check for violations: `composer cs-check` +* Automatically fix violations: `composer cs-fix` + +## Customizing PHPUnit Skeleton ## Once you've successfully installed PHPUnit Skeleton, you'll probably want to customize it to your application. ### How do I change the name of the application? ### Once you have the name of your application which we shall refer to as `YourApp`, then do the following: -1. First you have to change the entry `Application` in the `composer.json` file to `YourApp` under the object `psr-0`: - - > { - > "require-dev": { - > "phpunit/phpunit": "3.7.*", - > "phpunit/dbunit": ">=1.2", - > "phpunit/phpunit-selenium": ">=1.2" - > }, - > "autoload": { - > "psr-0": { - > "YourApp": "lib/" - > } - > } - > } - > - -2. Next, rename the following two directories from `Application` to `YourApp`: - * Rename `/lib/Application/` to `/lib/YourApp/` - * Rename `/tests/Application/` to `/tests/YourApp/` -3. Finally update the `namespace` inside the following php files: - * Inside `/lib/YourApp/Example.php` update `namespace Application;` to `namespace YourApp;` - * Inside `/tests/YourApp/ExampleTest.php` update `$this->obj = new Application\Example;` to `$this->obj = new YourApp\Example;` -4. Run `php composer.phar update` again to update the sources -5. Run `./vendor/bin/phpunit` again to make sure all tests are passing again +1. First you have to change the entry `Application` in the `composer.json` file to `YourApp` under `autoload.psr-4` (and `autoload-dev.psr-4` if you keep the same pattern for tests): + + ```json + { + "autoload": { + "psr-4": { + "YourApp\\": "lib/" + } + }, + "autoload-dev": { + "psr-4": { + "Tests\\": "tests/" + } + } + } + ``` + +2. Update the `namespace` inside the following PHP files: + * Inside `/lib/Example.php` update `namespace Application;` to `namespace YourApp;` + * Inside `/tests/ExampleTest.php` update `use Application\Example;` to `use YourApp\Example;` +3. Run `composer dump-autoload` to refresh the autoloader +4. Run `composer test` again to make sure all tests are passing again ## Credits ## * To the wonderful people on [Stack Overflow](http://stackoverflow.com/questions/15710410/autoloading-classes-in-phpunit-using-composer-and-autoload-php) for helping me understand PHPUnit better diff --git a/composer.json b/composer.json index f3da931..d3f4914 100644 --- a/composer.json +++ b/composer.json @@ -1,12 +1,39 @@ -{ - "require-dev": { - "phpunit/phpunit": "3.7.*", - "phpunit/dbunit": ">=1.2", - "phpunit/phpunit-selenium": ">=1.2" - }, - "autoload": { - "psr-0": { - "Application": "lib/" - } - } -} \ No newline at end of file +{ + "name": "jasdeepkhalsa/phpunit-skeleton", + "description": "A minimal, modern skeleton for getting started with PHPUnit testing in your PHP project.", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Jasdeep Khalsa" + } + ], + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0 || ^12.0", + "friendsofphp/php-cs-fixer": "^3.75" + }, + "autoload": { + "psr-4": { + "Application\\": "lib/" + } + }, + "autoload-dev": { + "psr-4": { + "Tests\\": "tests/" + } + }, + "config": { + "sort-packages": true, + "optimize-autoloader": true + }, + "minimum-stability": "stable", + "prefer-stable": true, + "scripts": { + "test": "phpunit", + "cs-check": "php-cs-fixer fix --dry-run --diff", + "cs-fix": "php-cs-fixer fix" + } +} diff --git a/composer.phar b/composer.phar deleted file mode 100644 index 08561ed..0000000 Binary files a/composer.phar and /dev/null differ diff --git a/lib/Application/Example.php b/lib/Application/Example.php deleted file mode 100644 index d509dbc..0000000 --- a/lib/Application/Example.php +++ /dev/null @@ -1,21 +0,0 @@ -number = 0; - } - - public function add($x, $y) { - if(!is_numeric($x) || !is_numeric($y)){ - throw new \InvalidArgumentException; - } - $this->number = $x + $y; - return $this->number; - } - -} -?> \ No newline at end of file diff --git a/lib/Example.php b/lib/Example.php new file mode 100644 index 0000000..1b4087f --- /dev/null +++ b/lib/Example.php @@ -0,0 +1,24 @@ +number = $x + $y; + + return $this->number; + } +} diff --git a/phpunit.xml b/phpunit.xml index ebee0ce..00129ac 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,8 +1,19 @@ - - - - - ./tests - - - \ No newline at end of file + + + + + ./tests + + + + + + ./lib + + + diff --git a/tests/Application/ExampleTest.php b/tests/Application/ExampleTest.php deleted file mode 100644 index 8581b12..0000000 --- a/tests/Application/ExampleTest.php +++ /dev/null @@ -1,36 +0,0 @@ -obj = new Application\Example; - } - - public function data() { - $data = array(); - $data[] = array(3,1,2); - $data[] = array(-5,-1,-4); - $data[] = array(10.5,10,0.5); - return $data; - } - - /** - * @dataProvider data - */ - public function testAddNumbers($expected, $actual_1, $actual_2) { - $this->assertEquals($expected, $this->obj->add($actual_1,$actual_2)); - } - - /** - * @expectedException InvalidArgumentException - */ - public function testThrowsExceptionForNonNumeric(){ - $this->assertEquals(3, $this->obj->add(1, array())); - } - - protected function tearDown() { - unset($this->obj); - } -} -?> \ No newline at end of file diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php new file mode 100644 index 0000000..82855d5 --- /dev/null +++ b/tests/ExampleTest.php @@ -0,0 +1,50 @@ +example = new Example(); + } + + /** + * @return array + */ + public static function numberProvider(): array + { + return [ + [3, 1, 2], + [-5, -1, -4], + [10.5, 10, 0.5], + ]; + } + + #[DataProvider('numberProvider')] + public function testAddReturnsTheSumOfTwoNumbers(int|float $expected, int|float $x, int|float $y): void + { + $this->assertEquals($expected, $this->example->add($x, $y)); + } + + public function testAddThrowsExceptionForNonNumericArgument(): void + { + $this->expectException(InvalidArgumentException::class); + + $this->example->add(1, []); + } + + protected function tearDown(): void + { + unset($this->example); + } +}