MacのPhpStormでLaravelプロジェクトでPHPUnitをできるようにする記録
- 以前、Laravelのプロジェクトを作ったことがありましたが、今回はPhpStormを使ってやります。
- PhpStormをインストールします。
- 新規にComposerプロジェクトを作成します。
- Xdebugをインストールします。
- プロジェクトを設定します。
- PHPUnitの設定をします。
- テストコードを作る
- PHPUnitでテストコードを実行します。
- 環境
- macOS Mojave バージョン10.14.4
- Composer version 1.8.0
以前、Laravelのプロジェクトを作ったことがありましたが、今回はPhpStormを使ってやります。
PhpStormをインストールします。
- JetBeanのPHPStormのサイトからダウンロードします。
- ダウンロードしたPhpStorm-yyyy.x.x.dmgをクリックします。
新規にComposerプロジェクトを作成します。
# 事前にインストールしてあるComposerの場所を確認 $ which composer /usr/local/bin/composer
Composerがインストールされていない場合はPhpStormのサイトを参照して作成します。
以下サイトの[新しいComposerプロジェクトを作成するには] > [2. ダイアログで、プロジェクトのパラメータを指定します。] > [b. Composerコマンドの実行方法を選択します。]を参照
pleiades.io
Command line parameterで指定した「–prefer-dist」はLaravelをZIPでダウンロードするということです。
# こんなコマンドが動きます。 /usr/local/bin/composer create-project laravel/laravel /path/to/project/directory/tryPhp/composer --prefer-dist
Laravelのバージョンを確認します。
# ウィンドウの下にある[Terminal]またはMacのターミナルで確認します。 $ php artisan -V Laravel Framework 5.8.14
LaravelにくっついているサーバでLaravelの初期画面を確認します。
# サーバを起動します $ php artisan serve Laravel development server started: <http://127.0.0.1:8000> # 表示されたURLにブラウザでアクセスします。 [Wed Apr 24 23:58:16 2019] 127.0.0.1:51584 [200]: /favicon.ico
プロジェクトを設定します。
PHP language levelを使っているPHPのバージョンに合わせます。
# [PHP language level]用に使っているPHPのバージョンを確認します $ php --version PHP 7.3.1 (cli) (built: Jan 10 2019 13:15:37) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.1, Copyright (c) 1998-2018 Zend Technologies with Xdebug v2.7.2, Copyright (c) 2002-2019, by Derick Rethans with Zend OPcache v7.3.1, Copyright (c) 1999-2018, by Zend Technologies # [CLI Interpreter]用に使っているPHPのディレクトリを確認します $ which php /usr/local/bin/php $ ls -la /usr/local/bin/ | grep php # 省略 lrwxr-xr-x 1 mana admin 27 1 20 14:09 php -> ../Cellar/php/7.3.1/bin/php # 省略
PHPUnitは、プロジェクトを作ったときに配置されています。
プロジェクトの直下にあるcomposer.jsonを確認するとデフォルトでインストールされています。
venderディレクトリにもphpunitディレクトリが配置されています。
"require-dev": { "beyondcode/laravel-dump-server": "^1.0", "filp/whoops": "^2.0", "fzaninotto/faker": "^1.4", "mockery/mockery": "^1.0", "nunomaduro/collision": "^2.0", "phpunit/phpunit": "^7.5" },
$ ls -l vendor/ | grep phpunit drwxr-xr-x@ 8 mana staff 256 4 24 23:47 phpunit
PHPUnitの設定をします。
(Macのターミナルを使う場合)PHPUnitのパスを通します。
# .bash_profileにphpunitのパスを書いて $ echo 'export PATH="/Path/To/vendor/phpunit/phpunit:$PATH"' >> ~/.bash_profile # 反映して $ source ~/.bash_profile # 確認します。 $ phpunit --version PHPUnit 7.5.9 by Sebastian Bergmann and contributors.
パスはbin配下ではなくphpunit配下を指定します。
以前PHPStormを使わなかった時は、PHPUnitのPathにbin配下を指定しました。
$ echo 'export PATH="/Path/To/vendor/bin/phpunit:$PATH"' >> ~/.bash_profile
今回はうまくいきませんでした。
$ echo 'export PATH="/Path/To/vendor/bin/phpunit:$PATH"' >> ~/.bash_profile $ source ~/.bash_profile $ phpunit --version -bash: phpunit: command not found
シンボリックリンクが貼ってあるけどだめなのですね。
$ ls -la vendor/bin/ total 32 drwxr-xr-x@ 6 mana staff 192 5 6 14:50 . drwxr-xr-x@ 47 mana staff 1504 5 6 14:43 .. -rwxr-xr-x@ 1 mana staff 6028 2 17 05:54 php-parse lrwxr-xr-x 1 mana staff 26 5 6 14:43 phpunit -> ../phpunit/phpunit/phpunit -rwxr-xr-x@ 1 mana staff 4305 10 14 2018 psysh lrwxr-xr-x 1 mana staff 51 5 6 14:43 var-dump-server -> ../symfony/var-dumper/Resources/bin/var-dump-server
composer.jsonにautoloadの定義があることを確認します。
定義がなければ環境に合わせて定義します。
"autoload": { "psr-4": { "App\\": "app/" }, "classmap": [ "database/seeds", "database/factories" ] }, "autoload-dev": { "psr-4": { "Tests\\": "tests/" } },
対応付けのためのクラスマップ生成を行います。
# クラスマップ生成 $ composer dump-autoload Generating optimized autoload files> Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: beyondcode/laravel-dump-server Discovered Package: fideloper/proxy Discovered Package: laravel/nexmo-notification-channel Discovered Package: laravel/slack-notification-channel Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Discovered Package: nunomaduro/collision Package manifest generated successfully. Generated optimized autoload files containing 3759 classes # 確認します $ cat vendor/composer/autoload_psr4.php <?php // autoload_psr4.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( 'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'), 'Zend\\Diactoros\\' => array($vendorDir . '/zendframework/zend-diactoros/src'), 'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'), 'Whoops\\' => array($vendorDir . '/filp/whoops/src/Whoops'), 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), 'TijsVerkoyen\\CssToInlineStyles\\' => array($vendorDir . '/tijsverkoyen/css-to-inline-styles/src'), 'Tests\\' => array($baseDir . '/tests'), 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'), 'Symfony\\Polyfill\\Iconv\\' => array($vendorDir . '/symfony/polyfill-iconv'), 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), 'Symfony\\Contracts\\' => array($vendorDir . '/symfony/contracts'), 'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'), 'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'), 'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'), 'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'), 'Symfony\\Component\\HttpKernel\\' => array($vendorDir . '/symfony/http-kernel'), 'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'), 'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'), 'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'), 'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'), 'Symfony\\Component\\CssSelector\\' => array($vendorDir . '/symfony/css-selector'), 'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'), 'Ramsey\\Uuid\\' => array($vendorDir . '/ramsey/uuid/src'), 'Psy\\' => array($vendorDir . '/psy/psysh/src'), 'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'), 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), 'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'), 'Opis\\Closure\\' => array($vendorDir . '/opis/closure/src'), 'NunoMaduro\\Collision\\' => array($vendorDir . '/nunomaduro/collision/src'), 'Nexmo\\' => array($vendorDir . '/nexmo/client/src'), 'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'), 'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'), 'Lcobucci\\JWT\\' => array($vendorDir . '/lcobucci/jwt/src'), 'Laravel\\Tinker\\' => array($vendorDir . '/laravel/tinker/src'), 'JakubOnderka\\PhpConsoleHighlighter\\' => array($vendorDir . '/jakub-onderka/php-console-highlighter/src'), 'JakubOnderka\\PhpConsoleColor\\' => array($vendorDir . '/jakub-onderka/php-console-color/src'), 'Illuminate\\Notifications\\' => array($vendorDir . '/laravel/nexmo-notification-channel/src', $vendorDir . '/laravel/slack-notification-channel/src'), 'Illuminate\\' => array($vendorDir . '/laravel/framework/src/Illuminate'), 'Http\\Promise\\' => array($vendorDir . '/php-http/promise/src'), 'Http\\Client\\' => array($vendorDir . '/php-http/httplug/src'), 'Http\\Adapter\\Guzzle6\\' => array($vendorDir . '/php-http/guzzle6-adapter/src'), 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), 'Fideloper\\Proxy\\' => array($vendorDir . '/fideloper/proxy/src'), 'Faker\\' => array($vendorDir . '/fzaninotto/faker/src/Faker'), 'Egulias\\EmailValidator\\' => array($vendorDir . '/egulias/email-validator/EmailValidator'), 'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'), 'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'), 'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Common/Inflector'), 'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'), 'Cron\\' => array($vendorDir . '/dragonmantank/cron-expression/src/Cron'), 'BeyondCode\\DumpServer\\' => array($vendorDir . '/beyondcode/laravel-dump-server/src'), 'App\\' => array($baseDir . '/app'), '' => array($vendorDir . '/nesbot/carbon/src'), );
PHPUnitの設定ファイルとなるphpunit.xmlを確認します。
自動でできるなんて素敵ですね。
<?xml version="1.0" encoding="UTF-8"?> <phpunit backupGlobals="false" backupStaticAttributes="false" bootstrap="vendor/autoload.php" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false"> <testsuites> <testsuite name="Unit"> <directory suffix="Test.php">./tests/Unit</directory> </testsuite> <testsuite name="Feature"> <directory suffix="Test.php">./tests/Feature</directory> </testsuite> </testsuites> <filter> <whitelist processUncoveredFilesFromWhitelist="true"> <directory suffix=".php">./app</directory> </whitelist> </filter> <php> <env name="APP_ENV" value="testing"/> <env name="BCRYPT_ROUNDS" value="4"/> <env name="CACHE_DRIVER" value="array"/> <env name="MAIL_DRIVER" value="array"/> <env name="QUEUE_CONNECTION" value="sync"/> <env name="SESSION_DRIVER" value="array"/> </php> </phpunit>
PhpStormにPHPUnitを設定します。
テストコードを作る
以前作ったファイルを流用します。なのでLaravelのディレクトリ構成とかからとっても外れています。
qiita.com
テスト対象ソースのエディタ上からテストクラスを生成します。
継承しているクラスをPHPUnit\Framework\TestCaseへ変更します。
自動生成時はHPUnit_Framework_TestCaseとなっていますがエラーとなるため変更します。
tomomik.hatenablog.com
Macのデフォルトではバックスラッシュが円マークになる事があるので以下のサイトを見てバックスラッシュで記載します。
Macにおけるバックスラッシュ(\)の入力方法 - Qiita
<?php namespace App; use PHPUnit\Framework\TestCase; class controlStdClassArrayTest extends TestCase { // 省略
自動生成されたメソッドへテストコードを記載して保存します。
<?php namespace App; use PHPUnit\Framework\TestCase; class controlStdClassArrayTest extends TestCase { public function testCreateStdClassArrayNew() { $target = new controlStdClassArray(); $stdList = $target->createStdClassArrayNew(); foreach ($stdList as $std) { $this->assertInstanceOf(\stdClass::class, $std); } } // 省略