tag:crieit.net,2005:https://crieit.net/tags/PHPUnit/feed 「PHPUnit」の記事 - Crieit Crieitでタグ「PHPUnit」に投稿された最近の記事 2021-01-05T22:40:17+09:00 https://crieit.net/tags/PHPUnit/feed tag:crieit.net,2005:PublicArticle/16539 2021-01-05T22:38:21+09:00 2021-01-05T22:40:17+09:00 https://crieit.net/posts/run-phpunit-on-github-actions-20210105 Github Actions で PHPUnit を走らせる <p>Github Actions で ESLint や Stylelint 、あるいはデプロイのワークフローは走らせたことがありますが、 Jest も行けるはず……と思い至ったところで、ふとそういえば PHPUnit はどうでしょうか、と思い実験。</p> <h2 id="検証"><a href="#%E6%A4%9C%E8%A8%BC">検証</a></h2> <p>検索すると、</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/blue32a/items/0661d70216051ad6552d">GitHub ActionsでPHPUnitを実行する - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://techblog.istyle.co.jp/archives/4143">GitHubActionsでPHP7.4環境のPHPUnitを実行する - istyle Tech Blog</a></li> </ul> <p>これらの記事がヒットしました。そこで、この記事を参考に <code>.github/workflows/test.yml</code> として作成。</p> <h3 id=".github/workflows/test.yml"><a href="#.github%2Fworkflows%2Ftest.yml">.github/workflows/test.yml</a></h3> <pre><code class="yml">name: PHPUnit test on: [push] jobs: test: name: Test runs-on: ubuntu-latest strategy: matrix: php-version: ['7.4'] steps: - name: Setup PHP $<span>{</span><span>{</span> matrix.php-version <span>}</span><span>}</span> uses: shivammathur/setup-php@v2 with: php-version: $<span>{</span><span>{</span> matrix.php-version <span>}</span><span>}</span> extension-csv: mbstring, xdebug, dom - name: Add Plugin run: sudo apt install -y php7.4-xml - name: Checkout uses: actions/checkout@v2 - name: Check PHP Version run: php -v - name: Check Composer Version run: composer -V - name: Check PHP Extensions run: php -m - name: Validate composer.json and composer.lock run: composer validate - name: Install dependencies run: composer install --prefer-dist --no-progress --no-suggest - name: Run test suite run: composer run-script test </code></pre> <p>試しに Github に push してみます。</p> <p><a href="https://crieit.now.sh/upload_images/5e7f8b136f405d78a18e5bea06bfba145ff4680848495.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5e7f8b136f405d78a18e5bea06bfba145ff4680848495.jpg?mw=700" alt="Github Actions で PHPUnit が走った結果の様子" /></a></p> <p>走りました。</p> <p>先人の知恵があればこそですが、 workflows の <code>yml</code> ファイルがあれば PHPUnit のテストも可能ということが分かりました。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <h3 id="Github Actions で PHPUnit"><a href="#Github+Actions+%E3%81%A7+PHPUnit">Github Actions で PHPUnit</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/blue32a/items/0661d70216051ad6552d">GitHub ActionsでPHPUnitを実行する - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://techblog.istyle.co.jp/archives/4143">GitHubActionsでPHP7.4環境のPHPUnitを実行する - istyle Tech Blog</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/nanasess/items/09b0798eb878328b195f">GitHub Actions で PHP の CI/CD をする - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.pnkts.net/2020/03/22/github-actions-phpunit">【Github Actions】プッシュ時にgithubに自動でテストを実行してもらおう! - ポンコツエンジニアのごじゃっぺ開発日記。</a></li> </ul> <h3 id="composer"><a href="#composer">composer</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://getcomposer.org/doc/03-cli.md#install-i">Command-line interface / Commands - Composer</a></li> <li><a target="_blank" rel="nofollow noopener" href="http://blog.tojiru.net/article/440339824.html">Composerの作者に会った (PHP勉強会 番外編レポート) #phpstudy #composerphp: Architect Note</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/tadsan/items/3a753f9eca83f2867a0a">composer.jsonのrequireを直接編集してはいけない - Qiita</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/16504 2021-01-04T23:43:49+09:00 2021-01-04T23:43:49+09:00 https://crieit.net/posts/phpunit-note-exclude-file-and-avoid-cannot-modify-header-20210104 PHPUnit のメモ(設定で特定のファイルを対象除外、 Cannot modify header information - headers already sent by ... のエラーの回避) <p>PHPUnit を使っていて少し躓いた部分のメモ。なお、 PHPUnit のバージョンは <code>9.5.0</code> で試しました。</p> <h2 id="設定で特定のファイルを対象除外"><a href="#%E8%A8%AD%E5%AE%9A%E3%81%A7%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E5%AF%BE%E8%B1%A1%E9%99%A4%E5%A4%96">設定で特定のファイルを対象除外</a></h2> <p>設定の値を返すだけの簡単な設定ファイルを作ってあり、それをテストから除外したい場合。</p> <pre><code class="xml"><phpunit bootstrap="./tests/bootstrap.php" addUncoveredFilesFromWhitelist="true" processUncoveredFilesFromWhitelist="true" stopOnFailure="false" colors="auto"> <testsuites> <testsuite> <directory suffix="Test.php">./tests</directory> </testsuite> </testsuites> <filter> <whitelist processUncoveredFilesFromWhitelist="true"> <directory suffix=".php">./src</directory> <exclude> <directory suffix=".php">./tests</directory> <directory>./template</directory> </exclude> </whitelist> </filter> </phpunit> </code></pre> <p>ディレクトリの除外ならば <code>phpunit.xml.dist</code> で上記の <code>whitelist</code> > <code>exclude</code> > <code>directory</code> で囲んだパスを除外できることは知っていました。</p> <pre><code class="php"><?php return [ 'base' => '/', 'appname' => 'Config Sample', ]; </code></pre> <p>今回のケースでは、例えばこんな <code>src/config.php</code> があったとします。また、 <code>src/</code> ディレクトリには他のコードもあるため、 <code>src/</code> 自体はテスト対象に含めたいとします。</p> <pre><code class="xml"><phpunit bootstrap="./tests/bootstrap.php" addUncoveredFilesFromWhitelist="true" processUncoveredFilesFromWhitelist="true" stopOnFailure="false" colors="auto"> <testsuites> <testsuite> <directory suffix="Test.php">./tests</directory> </testsuite> </testsuites> <filter> <whitelist processUncoveredFilesFromWhitelist="true"> <directory suffix=".php">./src</directory> <exclude> <directory suffix=".php">./tests</directory> <directory>./template</directory> <file>./src/config.php</file> </exclude> </whitelist> </filter> </phpunit> </code></pre> <p><code>whitelist</code> > <code>exclude</code> > <code>file</code> にすれば良し。</p> <h2 id="Cannot modify header information - headers already sent by ... のエラーの回避"><a href="#Cannot+modify+header+information+-+headers+already+sent+by+...+%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AE%E5%9B%9E%E9%81%BF">Cannot modify header information - headers already sent by ... のエラーの回避</a></h2> <p>とあるメソッドの中に <code>header()</code> 関数が記述されていると、テストの際に</p> <blockquote> <p>Cannot modify header information - headers already sent by (output started at PATH/TO/PROJECT/vendor/phpunit/phpunit/src/Util/Printer.php:104)</p> </blockquote> <p>のようなエラーが出てしまいました。</p> <p>これは PHPUnit はテスト中のメッセージを標準出力に吐き出すので、 <code>header()</code> の前に既に出力がされてしまっている状態になるため引っかかってしまうようです。</p> <p>対策としては、 PHPUnit の <code>@runInSeparateProcess</code> アノテーションを使用することで、そのテストケースを別プロセスとして動作させること。</p> <p>これにより <code>header()</code> 前に出力がない状態としてテストするため、引っかからなくなります。</p> <pre><code class="php"><?php class DullahanTest extends \PHPUnit\Framework\TestCase { /** * @test * @runInSeparateProcess */ public function testDullahan() { // some test code } } </code></pre> <p>こんなイメージです。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <h3 id="設定で特定のファイルを対象除外"><a href="#%E8%A8%AD%E5%AE%9A%E3%81%A7%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E5%AF%BE%E8%B1%A1%E9%99%A4%E5%A4%96">設定で特定のファイルを対象除外</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://phpunit.readthedocs.io/ja/latest/configuration.html">3. XML 設定ファイル — PHPUnit latest Manual</a></li> </ul> <h3 id="Cannot modify header information - headers already sent by ... のエラーの回避"><a href="#Cannot+modify+header+information+-+headers+already+sent+by+...+%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AE%E5%9B%9E%E9%81%BF">Cannot modify header information - headers already sent by ... のエラーの回避</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/1000k/items/65f64dd95c020639edbf">header() 関数を使ったメソッドを PHPUnit でテストする方法 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://blog.shimabox.net/2016/12/13/test_methods_that_use_the_header_function_in_phpunit/">PHPUnitでheader関数を使うメソッドのテスト | Shimabox Blog</a></li> </ul> <h2 id="余談"><a href="#%E4%BD%99%E8%AB%87">余談</a></h2> <p>今回ほんの些細なプログラムを書いたのですが、あまりにも些細なものだったので「どうせなら PHPUnit の練習にしよう」と思って取り組みました。結果、 PHPUnit で今まであまり触ってこなかったケースに当たったので、良い勉強になったのかな、と思います。</p> <h3 id="サンプルプログラムを書く際に参考にしたサイト ( PHPUnit とは関係なし)"><a href="#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%82%92%E6%9B%B8%E3%81%8F%E9%9A%9B%E3%81%AB%E5%8F%82%E8%80%83%E3%81%AB%E3%81%97%E3%81%9F%E3%82%B5%E3%82%A4%E3%83%88+%28+PHPUnit+%E3%81%A8%E3%81%AF%E9%96%A2%E4%BF%82%E3%81%AA%E3%81%97%29">サンプルプログラムを書く際に参考にしたサイト ( PHPUnit とは関係なし)</a></h3> <h4 id="password_hash"><a href="#password_hash">password_hash</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/function.password-hash.php">PHP: password_hash - Manual</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/rana_kualu/items/3ef57485be1103362f56">2018年のパスワードハッシュ - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yayoshM/items/8971e893c1bd95aa0284">PHPのPassword_hash関数をcrypt関数で再現する(メモ) - Qiita</a> <ul> <li><code>password_hash</code> の <code>salt</code> を指定するのは非推奨。仮に指定する場合、短すぎると警告が発せられる</li> </ul></li> </ul> <h4 id="call_user_func_array"><a href="#call_user_func_array">call_user_func_array</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/function.call-user-func-array.php">PHP: call_user_func_array - Manual</a></li> </ul> <p>変数の渡し方が若干疑問。</p> <h4 id="call_user_func_array + FastRoute"><a href="#call_user_func_array+%2B+FastRoute">call_user_func_array + FastRoute</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/masakielastic/items/0265ba85de113d06430c">FastRoute を試す - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://webty.jp/staffblog/production/post-2613/">Composerでオレオレフレームワークを作った話 │ Webty Staff Blog</a></li> </ul> <h4 id="str_pad"><a href="#str_pad">str_pad</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.php.net/manual/ja/function.str-pad.php">PHP: str_pad - Manual</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/14603 2018-11-14T20:26:19+09:00 2018-11-14T20:26:19+09:00 https://crieit.net/posts/Laravel-HTTP-output-buffers LaravelのHTTPテストでoutput buffersが閉じられていないエラー <p>Laravelのテストでいつの間にかRiskyテストが出るようになっていた。失敗ではないのでCIでも何も言われなかったようで、実行時にもエラーが発生していなかったので気づかずにいたらしい。</p> <p>具体的には下記のようなエラー。</p> <pre><code class="shell">Test code or tested code did not (only) close its own output buffers </code></pre> <p>結論としては、下記のようなテンプレートの書き方をしていたために正常にレスポンスが返っていなかったらしい。</p> <pre><code>@section('additionallTag', $data->tag) </code></pre> <p>これは特に記述自体は問題ないと思うが、変数の中に入っているのがHTMLタグだったため今回のエラーが発生しているっぽい。そのため下記のように修正したところ改善した。</p> <pre><code>@section('additionalTag') {!! $data->tag !!} @endsection </code></pre> <p>同じエラーの改善方法を解説している記事も見つけた。</p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/t_k_m_s_otya/items/6e973f90c09df40f2224">LaravelのHTTPテストでなぜかresponseが返ってこない件</a></p> <p>この場合はsectionが閉じられていないためとのことだが、今回のように変数の指定によってはうまく閉じられなくなってしまうということっぽい。</p> だら@Crieit開発者