CodeIgniter4でMonologを使う

CodeIgniter4でMonologを使うように設定してみます。

CodeIgniter4はPSR-3に準拠していますので、PSR-3準拠のロガーなら簡単に置き換えることができます。

動作確認環境

  • CodeIgniter 4.1.4
  • Composer 2.1.6
  • Monolog 2.3.4
  • PHP 8.0.10
  • macOS 10.15.7

Monologのインストール

ComposerでMonologをインストールします。

$ composer require monolog/monolog

Servicesの設定

CodeIgniter4の Serviceslogger を設定します。

app/Config/Services.php:

<?php

namespace Config;

use CodeIgniter\Config\BaseService;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Psr\Log\LoggerInterface;

class Services extends BaseService
{
     public static function logger($getShared = true): LoggerInterface
     {
         if ($getShared) {
             return static::getSharedInstance('logger');
         }

         $log = new Logger('ci4');

         $logFile = WRITEPATH.'logs/app.log';
         $log->pushHandler(new StreamHandler(
             $logFile,
             Logger::DEBUG,
             true,
             null,
             true
         ));

         return $log;
     }
}

Config\Services::logger() を追加します。Monologをインスタンス化し、設定し、そのインスタンスを返します。

使い方

ログを出力する

log_message() がそのまま使えます。

log_message('error', 'This is error log.');

以下のようにログファイルに記録されました。

writable/logs/app.log:

[2021-09-16T09:11:47.125967+09:00] ci4.ERROR: This is error log. [] []

Monologインスタンスを取得する

CodeIgniter4の Services から logger を取得します。

$logger = service('logger');
$logger = \Config\Services::logger();

これで、Monolog\Loggerオブジェクトが取得できます。

参考

Tags: codeigniter, codeigniter4, monolog, logging

PHPUnitのブランチカバレッジの値が思っていたのと違った

PHPUnit 9.3からXdebugを使うと、今までのラインカバレッジに加えて、ブランチカバレッジ、パスカバレッジが計測できるようになりました。

動作確認環境

  • PHP 7.4.21
    • Xdebug 3.0.2
  • PHPUnit 9.5.8
    • php-code-coverage 9.2.6

PHPUnitの設定

ブランチカバレッジ、パスカバレッジを計測するには、 phpunit.xml にて、以下のように pathCoverage="true" を設定します。

<coverage cacheDirectory="/path/to/directory"
    pathCoverage="true">
    ...
</coverage>

用語の意味

PHPUnitのマニュアル でブランチカバレッジ、パスカバレッジの説明を確認しておきましょう。

ブランチカバレッジとは

The Branch Coverage software metric measures whether the boolean expression of each control structure evaluated to both true and false while running the test suite.

(私訳)ブランチカバレッジは、テストスイートの実行中に、各制御構造のブール式が真と偽の両方で評価されたかどうかを測定します。

パスカバレッジとは

The Path Coverage software metric measures whether each of the possible execution paths in a function or method has been followed while running the test suite. An execution path is a unique sequence of branches from the entry of the function or method to its exit.

(私訳)パスカバレッジ・ソフトウェアメトリックは、テストスイートの実行中に、関数やメソッドで可能な実行パスのそれぞれをたどったかどうかを測定します。実行パスとは、関数やメソッドの入口から出口までの、一意の分岐シーケンスのことです。

ラインカバレッジとの違い

上記から、以下のように理解していました。

  • ラインカバレッジは実行可能な行が実行されたかどうかのみを計測する
  • ブランチカバレッジは制御構造のtrue/falseの両方の場合がテスト時に実行されているかを計測する
  • パスカバレッジは全ての実行パスが実行されているかを計測する

カバレッジを計測してみる

では、実際にカバレッジを計測してみましょう。

elseがない場合

以下のクラスで確認してみます。

Sample.php:

<?php

declare(strict_types=1);

namespace Kenjis\Sample;

final class Sample
{
    public function check(int $x): bool
    {
        $ret = false;

        if ($x <= 1) {
            $ret = true;
        }

        return $ret;
    }
}

if 文が1つだけあるメソッドです。

テストコードを作成します。

SampleTest.php:

<?php

declare(strict_types=1);

namespace Kenjis\Sample;

use PHPUnit\Framework\TestCase;

class SampleTest extends TestCase
{
    /** @var Sample */
    protected $sample;

    protected function setUp(): void
    {
        $this->sample = new Sample();
    }

    public function test_CheckIfTrue(): void
    {
        $this->assertTrue($this->sample->check(1));
    }
}

if の条件が true になるケースだけテストを書きました。

if の条件が false の場合はテストがありませんので、ブランチカバレッジは 100% にはならないはずです。

カバレッジを計測してみましょう。

おかしいですね。

ラインカバレッジ、ブランチカバレッジともに 100% になっています。

一方、パスカバレッジは 50% になっています。

左のファイル名「Sample.php」の下の [branch] を押して、ブランチを確認してみます。

return が 2つありますが、どちらも実行されており(グリーン)、全行グリーンになっています。

どうもブランチカバレッジの計測結果は思っていたものと少し違うようです。バグでしょうか?

elseがある場合

Sample.php に以下のように else を追加してみます。

Sample.php:

<?php

declare(strict_types=1);

namespace Kenjis\Sample;

final class Sample
{
    public function check(int $x): bool
    {
        $ret = false;

        if ($x <= 1) {
            $ret = true;
        } else {
            $ret = false;
        }

        return $ret;
    }
}

ラインカバレッジが 80%、ブランチカバレッジが 75%になりました。

パスカバレッジは 50% で変わりません。

左のファイル名「Sample.php」の下の [branch] を押して、ブランチを確認します。

if の条件が false の場合がテストされておらず、レッドになっています。

else がある場合は、ブランチカバレッジが 100% になっておらず、想定された結果になっています。

早期returnした場合

Sample.php を以下のように変更してみます。

Sample.php:

<?php

declare(strict_types=1);

namespace Kenjis\Sample;

final class Sample
{
    public function check(int $x): bool
    {
        if ($x <= 1) {
            return true;
        }

        return false;
    }
}

ラインカバレッジ、ブランチカバレッジともに 66.67%になりました。

パスカバレッジは 50% で変わりません。

ブランチも確認しておきます。

早期returnした場合も、ブランチカバレッジが 100% になっておらず、想定された結果になっています。

まとめ

  • if 文の書き方により、テストケースが不足する場合でも、ブランチカバレッジが 100% になることがある
  • パスカバレッジについては、そのようなことはない

参考

Tags: testing, phpunit

travis-ci.orgからtravis-ci.comへの移行

2021年6月15日以降、travis-ci.org でのビルドが停止したようですので、 travis-ci.org でビルドしていた公開リポジトリを travis-ci.com へ移行しました。

travis-ci.com へGitHubでサインインします。

右上のアイコンから「Settings」へ移動します。

「Merge」タブへ移動します。 「Activate all repositores using GitHub Apps」ボタンをクリックします。

移行するリポジトリを選択します。 「Approve & Install」ボタンをクリックします。

完了後、移動しようとすると何故かログアウトされたので、再度、GitHubでサインインしました。

「Settings」→「Merge」タブを見ると、ベータにサインアップする必要があると表示されています。 「Sign up for the beta」ボタンをクリックします。

確認のウインドウが表示されます。 「Join the beta」ボタンをクリックします。

「Settings」→「Merge」タブに戻り、移行するリポジトリを選択します。 「Migrate selected repositories to travis-ci.com」ボタンをクリックします。

確認のウインドウが表示されます。 「Migrate」ボタンをクリックします。

これで、リポジトリが travis-ci.com に移行されました。

参考

Tags: continuous-integration