From af34c70b90bb0db2ab6880f203965fed9043d8bd Mon Sep 17 00:00:00 2001 From: thisfro Date: Thu, 6 May 2021 11:31:06 +0200 Subject: [PATCH] setup phpunit for testing --- .gitignore | 225 ++++++++++++++++++ composer.json | 3 + composer.lock | 295 +++++++++++++++++++++++- phpunit.xml.dist | 40 ++++ src/Repository/UserRepository.php | 4 +- symfony.lock | 27 +++ tests/Controller/UserControllerTest.php | 28 +++ tests/bootstrap.php | 11 + 8 files changed, 629 insertions(+), 4 deletions(-) create mode 100644 phpunit.xml.dist create mode 100644 tests/Controller/UserControllerTest.php create mode 100644 tests/bootstrap.php diff --git a/.gitignore b/.gitignore index 4ee69d6..8b0d6b7 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,228 @@ npm-debug.log yarn-error.log ###< symfony/webpack-encore-bundle ### + +# ----------------------------------------------------------- +# Created by https://www.toptal.com/developers/gitignore/api/node,phpunit,symfony,composer,yarn +# Edit at https://www.toptal.com/developers/gitignore?templates=node,phpunit,symfony,composer,yarn + +### Composer ### +composer.phar +/vendor/ + +# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control +# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file +# composer.lock + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test +.env*.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Storybook build outputs +.out +.storybook-out +storybook-static + +# rollup.js default build output +dist/ + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# Temporary folders +tmp/ +temp/ + +### PHPUnit ### +# Covers PHPUnit +# Reference: https://phpunit.de/ + +# Generated files +.phpunit.result.cache +.phpunit.cache + +# PHPUnit +/app/phpunit.xml +/phpunit.xml + +# Build data +/build/ + +### Symfony ### +# Cache and logs (Symfony2) +/app/cache/* +/app/logs/* +!app/cache/.gitkeep +!app/logs/.gitkeep + +# Email spool folder +/app/spool/* + +# Cache, session files and logs (Symfony3) +/var/cache/* +/var/logs/* +/var/sessions/* +!var/cache/.gitkeep +!var/logs/.gitkeep +!var/sessions/.gitkeep + +# Logs (Symfony4) +/var/log/* +!var/log/.gitkeep + +# Parameters +/app/config/parameters.yml +/app/config/parameters.ini + +# Managed by Composer +/app/bootstrap.php.cache +/var/bootstrap.php.cache +/bin/* +!bin/console +!bin/symfony_requirements + +# Assets and user uploads +/web/bundles/ +/web/uploads/ + +# PHPUnit + +# Build data + +# Composer PHAR +/composer.phar + +# Backup entities generated with doctrine:generate:entities command +**/Entity/*~ + +# Embedded web-server pid file +/.web-server-pid + +### Symfony Patch ### +/web/css/ +/web/js/ + +### yarn ### +# https://yarnpkg.com/advanced/qa#which-files-should-be-gitignored + +.yarn/* +!.yarn/releases +!.yarn/plugins +!.yarn/sdks +!.yarn/versions + +# if you are NOT using Zero-installs, then: +# comment the following lines +!.yarn/cache + +# and uncomment the following lines +# .pnp.* + +# End of https://www.toptal.com/developers/gitignore/api/node,phpunit,symfony,composer,yarn diff --git a/composer.json b/composer.json index b3b84a7..1c270d9 100644 --- a/composer.json +++ b/composer.json @@ -77,8 +77,11 @@ } }, "require-dev": { + "symfony/browser-kit": "^5.2", + "symfony/css-selector": "^5.2", "symfony/debug-bundle": "^5.2", "symfony/maker-bundle": "^1.30", + "symfony/phpunit-bridge": "^5.2", "symfony/stopwatch": "^5.2", "symfony/var-dumper": "^5.2", "symfony/web-profiler-bundle": "^5.2" diff --git a/composer.lock b/composer.lock index eb6769a..0b99f80 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "17c34311a2696b4e9d060e5d8855bf05", + "content-hash": "1f9fc9192bfbe54250ceaa48c03368ad", "packages": [ { "name": "composer/package-versions-deprecated", @@ -7279,6 +7279,142 @@ } ], "packages-dev": [ + { + "name": "symfony/browser-kit", + "version": "v5.2.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/browser-kit.git", + "reference": "b1c9d5701273a255da3a580f85066b83bd94e97d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/b1c9d5701273a255da3a580f85066b83bd94e97d", + "reference": "b1c9d5701273a255da3a580f85066b83bd94e97d", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/dom-crawler": "^4.4|^5.0" + }, + "require-dev": { + "symfony/css-selector": "^4.4|^5.0", + "symfony/http-client": "^4.4|^5.0", + "symfony/mime": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0" + }, + "suggest": { + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\BrowserKit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/browser-kit/tree/v5.2.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-04-08T10:27:02+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v5.2.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "59a684f5ac454f066ecbe6daecce6719aed283fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/59a684f5ac454f066ecbe6daecce6719aed283fb", + "reference": "59a684f5ac454f066ecbe6daecce6719aed283fb", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Converts CSS selectors to XPath expressions", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v5.3.0-BETA1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-04-07T16:07:52+00:00" + }, { "name": "symfony/debug-bundle", "version": "v5.2.4", @@ -7357,6 +7493,80 @@ ], "time": "2021-01-10T16:30:10+00:00" }, + { + "name": "symfony/dom-crawler", + "version": "v5.2.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "400e265163f65aceee7e904ef532e15228de674b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/400e265163f65aceee7e904ef532e15228de674b", + "reference": "400e265163f65aceee7e904ef532e15228de674b", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "masterminds/html5": "<2.6" + }, + "require-dev": { + "masterminds/html5": "^2.6", + "symfony/css-selector": "^4.4|^5.0" + }, + "suggest": { + "symfony/css-selector": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases DOM navigation for HTML and XML documents", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dom-crawler/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-15T18:55:04+00:00" + }, { "name": "symfony/maker-bundle", "version": "v1.30.2", @@ -7445,6 +7655,89 @@ ], "time": "2021-03-23T13:53:38+00:00" }, + { + "name": "symfony/phpunit-bridge", + "version": "v5.2.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/phpunit-bridge.git", + "reference": "f530f0153f4a871b2c65dd6b295d7b8d03a16eac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/f530f0153f4a871b2c65dd6b295d7b8d03a16eac", + "reference": "f530f0153f4a871b2c65dd6b295d7b8d03a16eac", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0|<6.4,>=6.0|9.1.2" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.1", + "symfony/error-handler": "^4.4|^5.0" + }, + "suggest": { + "symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" + }, + "bin": [ + "bin/simple-phpunit" + ], + "type": "symfony-bridge", + "extra": { + "thanks": { + "name": "phpunit/phpunit", + "url": "https://github.com/sebastianbergmann/phpunit" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Bridge\\PhpUnit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides utilities for PHPUnit, especially user deprecation notices management", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/phpunit-bridge/tree/v5.2.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-04-11T22:55:21+00:00" + }, { "name": "symfony/web-profiler-bundle", "version": "v5.2.7", diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..0bd20c8 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + tests + + + + + + src + + + + + + + + + + diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index 1a38975..f1fb55c 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -39,8 +39,7 @@ class UserRepository extends ServiceEntityRepository implements PasswordUpgrader // /** // * @return User[] Returns an array of User objects // */ - /* - public function findByExampleField($value) + public function findByEmail($value) { return $this->createQueryBuilder('u') ->andWhere('u.exampleField = :val') @@ -51,7 +50,6 @@ class UserRepository extends ServiceEntityRepository implements PasswordUpgrader ->getResult() ; } - */ /* public function findOneBySomeField($value): ?User diff --git a/symfony.lock b/symfony.lock index 387c7ce..2887603 100644 --- a/symfony.lock +++ b/symfony.lock @@ -139,6 +139,9 @@ "symfony/asset": { "version": "v5.2.4" }, + "symfony/browser-kit": { + "version": "v5.2.7" + }, "symfony/cache": { "version": "v5.2.6" }, @@ -160,6 +163,9 @@ "bin/console" ] }, + "symfony/css-selector": { + "version": "v5.2.7" + }, "symfony/debug-bundle": { "version": "4.1", "recipe": { @@ -184,6 +190,9 @@ "symfony/doctrine-bridge": { "version": "v5.2.6" }, + "symfony/dom-crawler": { + "version": "v5.2.4" + }, "symfony/dotenv": { "version": "v5.2.4" }, @@ -297,6 +306,21 @@ "symfony/orm-pack": { "version": "v2.1.0" }, + "symfony/phpunit-bridge": { + "version": "5.1", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "5.1", + "ref": "bf16921ef8309a81d9f046e9b6369c46bcbd031f" + }, + "files": [ + ".env.test", + "bin/phpunit", + "phpunit.xml.dist", + "tests/bootstrap.php" + ] + }, "symfony/polyfill-intl-grapheme": { "version": "v1.22.1" }, @@ -380,6 +404,9 @@ "symfony/string": { "version": "v5.2.6" }, + "symfony/test-pack": { + "version": "v1.0.7" + }, "symfony/translation": { "version": "3.3", "recipe": { diff --git a/tests/Controller/UserControllerTest.php b/tests/Controller/UserControllerTest.php new file mode 100644 index 0000000..e029bde --- /dev/null +++ b/tests/Controller/UserControllerTest.php @@ -0,0 +1,28 @@ +get(UserRepository::class); + + $client->catchExceptions(false); + + // retrieve the test user + $testUser = $userRepository->findOneByEmail('jannis@thisfro.ch'); + + // simulate $testUser being logged in + $client->loginUser($testUser); + + // test e.g. the profile page + $client->request('GET', '/user'); + $this->assertResponseIsSuccessful(); + $this->assertSelectorTextContains('h1', 'Hello thisfro!'); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..469dcce --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,11 @@ +bootEnv(dirname(__DIR__).'/.env'); +}