ホームページ >バックエンド開発 >PHPチュートリアル >PHPでJavaScriptスタイルのテストウォッチャーを書く方法

PHPでJavaScriptスタイルのテストウォッチャーを書く方法

Lisa Kudrow
Lisa Kudrowオリジナル
2025-02-09 10:58:10775ブラウズ

How to Write JavaScript-Style Test Watchers in PHP

コアポイント

    JavaScriptスタイルのテストオブザーバーをPHPプロジェクトに統合し、ファイル変換の前処理を自動化し、ファイルが変更されたときにユニットテストを再実行し、開発効率を改善します。
  • phpunitなどのツールを使用して自動テストをセットアップし、phpunit-watcherを使用してファイル変更を観察し、開発中の即時のフィードバックとエラーの検出を確保します。
  • PHPプロジェクトに前処理スクリプトを実装し、JavaScript Babelと同様の構文変換を許可するため、互換性を向上させ、手動エンコードの取り組みを削減します。
  • PHPテスト環境を構成して、テストする前に事前に処理されたファイルを自動的に再構築し、正確なコードカバレッジを維持し、テストプロセスを簡素化します。
  • ファイルオブザーバーを使用して高度な構成を調査して、変更されたファイルのみを選択的に再構築し、大規模プロジェクトの多数のファイルのテストサイクルを大幅に高速化します。
この記事は、Younes Rafieによってレビューされました。 SitePointコンテンツを最高の状態にしてくれたすべてのSitePointピアレビューアに感謝します!

最初にコードのテストを書きませんでした。多くの人と同様に、私の「テスト」はコードを書き、ページを更新しています。 「それは正しく見えますか?」それが正しいと思うなら、私は続けます。

実際には、私が行った仕事のほとんどは、他の形式のテストについてあまり気にしない企業にとってです。長年の経験と、クリス・ハルジェスのような人々からの賢明なアドバイスの後、私はテストの価値を見ました。そして、私はまだ良いテストがどのように見えるかを学んでいます。

How to Write JavaScript-Style Test Watchers in PHP 私は最近、バンドルされたテストオブザーバーを含むいくつかのJavaScriptプロジェクトの取り組みを開始しました。

これは、テスト駆動型のnodejs開発に関する素晴らしい高度なビデオチュートリアルです!

JavaScriptの世界では、ソースコードを前処理することは珍しくありません。 JavaScriptの世界では、開発者はサポートされていない構文を使用してコードを作成し、多くの場合Babelと呼ばれるツールを使用して、コードを広くサポートされている構文に変換します。

変換スクリプトを呼び出すための負担を減らすために、VoilerPlateプロジェクトはファイルの変更を自動的に監視するスクリプトを含め始めました。

私が取り組んだプロジェクトは、再実行ユニットテストに対して同様のアプローチを取りました。 JavaScriptファイルを変更すると、ファイルが変換され、ユニットテストが再実行されます。これにより、何かが壊れているかどうかをすぐに確認できます。

このチュートリアルのコードはgithubで見つけることができます。 PHP 7.1でテストしました。

プロジェクト設定

これらのプロジェクトに取り組み始めて以来、phpunitに似たようなもののセットアップを開始しました。実際、PHPunitオブザーバースクリプトをセットアップした最初のプロジェクトは、ファイルを事前に処理するPHPプロジェクトです。

プロジェクトにプリプロセシングスクリプトを追加した後、それはすべて始まった:

<code class="language-bash">composer require pre/short-closures</code>

これらの特定の前処理スクリプトを使用すると、PSR-4の自動ロードされたクラス(Path/to/file.php⇒Path/to/file.pre)を変更して、提供する機能にオプトインできます。そこで、私は私のcomposer.jsonファイルに次のものを追加しました:

<code class="language-json">"autoload": {
    "psr-4": {
        "App\": "src"
    }
},
"autoload-dev": {
    "psr-4": {
        "App\Tests\": "tests"
    }
}</code>

これはcomposer.json

からです

次に、現在のユーザーセッションの詳細を含む関数を生成するクラスを追加しました:

<code class="language-php">namespace App;

use Closure;

class Session
{
    private $user;

    public function __construct(array $user)
    {
        $this->user = $user;
    }

    public function closureWithUser(Closure $closure)
    {
        return () => {
            $closure($this->user);
        };
    }
}</code>

これはsrc/session.pre

に由来します

これが機能するかどうかを確認するには、小さなサンプルスクリプトをセットアップします。

<code class="language-php">require_once __DIR__ . "/vendor/autoload.php";

$session = new App\Session(["id" => 1]);

$closure = ($user) => {
    print "user: " . $user["id"] . PHP_EOL;
};

$closureWithUser = $session->closureWithUser($closure);
$closureWithUser();</code>
これはexample.pre

に由来します

…そして、非PSR-4クラスで短い閉鎖を使用したいので、ローダーをセットアップする必要があります:

<code class="language-php">require_once __DIR__ . "/vendor/autoload.php";

Pre\Plugin\process(__DIR__ . "/example.pre");</code>
これはroader.php

に由来します

コードのこのセクションは、小さなポイントを説明することがたくさんあります。セッションクラスには、1つの閉鎖を受け入れ、別の閉鎖を返す閉鎖的な方法があります。呼び出されると、この新しい閉鎖は元の閉鎖を呼び出し、ユーザーセッションアレイをパラメーターとして提供します。

このすべてを実行するには、端末を入力してください:

<code class="language-bash">php loader.php</code>

サイドノートとして、これらの前処理は非常に美しい効果的なPHP構文を生成します。このように見えます:

<code class="language-php">$closure = function ($user) {
   print "user: " . $user["id"] . PHP_EOL;
};</code>

…および

<code class="language-php">public function closureWithUser(Closure $closure)
{
   return [$closure = $closure ?? null, "fn" => function () use (&$closure) {
       $closure($this->user);
   }]["fn"];
}</code>

PHPとPREファイルの両方をリポジトリに送信したくない場合があります。これを行うには、app/**/*。php and emply.phpを.gitignoreに追加しました。

テストの設定

では、これをどのようにテストしますか? Phpunit:

のインストールから始めましょう

<code class="language-bash">composer require --dev phpunit/phpunit</code>
次に、構成ファイルを作成する必要があります:

<code class="language-xml"><?xml version="1.0" encoding="UTF-8"?>
<phpunit backupglobals="false" backupstaticattributes="false" bootstrap="vendor/autoload.php" colors="true" converterrorstoexceptions="true" convertnoticestoexceptions="true" convertwarningstoexceptions="false" processisolation="false" stoponfailure="false" syntaxcheck="false">
    <testsuites>
        <testsuite>
            <directory suffix="Test.php">tests</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist adduncoveredfilesfromwhitelist="true">
            <directory suffix=".php">src</directory>
        </whitelist>
    </filter>
</phpunit></code>
これはphpunit.xml

からです

ベンダー/bin/phpunitを実行すると、機能します。しかし、私たちはまだテストしていません。やりましょう:

<code class="language-php">namespace App\Tests;

use App\Session;
use PHPUnit\Framework\TestCase;

class SessionTest extends TestCase
{
    public function testClosureIsDecorated()
    {
        $user = ["id" => 1];
        $session = new Session($user);

        $expected = null;

        $closure = function($user) use (&$expected) {
            $expected = "user: " . $user["id"];
        };

        $closureWithUser = $session
            ->closureWithUser($closure);

        $closureWithUser();

        $this->assertEquals("user: 1", $expected);
    }
}</code>
これは、tests/sessiontest.php

に由来します

ベンダー/bin/phpunitを実行すると、単一のテストが渡されます。うん!

何が欠けているのですか?

これまでのところ、すべてがうまくいきました。このコードの小さな部分とこのコードのテストを書きました。プリプロセシングがどのように機能するかを心配する必要さえありません(JavaScriptプロジェクトよりもステップアップ)。

コードカバレッジを確認しようとすると問題が始まります。

セッションをテストしたときに、カバレッジが報告されます。シンプルなクラスなので、100%のカバレッジを達成しました。ただし、別のクラスを追加する場合:
<code class="language-bash">vendor/bin/phpunit --coverage-html coverage</code>

namespace App; class BlackBox { public function get($key) { return $GLOBALS[$key]; } }から来ています

カバレッジをチェックするとどうなりますか?まだ100%。

これは、blackbox.preをロードするテストがないために発生します。つまり、コンパイルされていないことを意味します。したがって、Phpunitが上書きされたPHPファイルを探すと、この前処理可能なファイルが表示されません。

テストする前にすべてのファイルを構築します

テストを実行しようとする前に、すべてのPREファイルを作成する新しいスクリプトを作成しましょう。

<code class="language-bash">composer require pre/short-closures</code>
これは、テスト/bootstrap.php
に由来します

ここでは、3つの関数を作成します。1つは再帰ファイルイテレータ(パスから)、1つはこのイテレーターを削除し、1つはPREファイルを再コンパイルするためです。

Phpunit.xmlの現在のBootstrapファイルを置き換える必要があります:

<code class="language-json">"autoload": {
    "psr-4": {
        "App\": "src"
    }
},
"autoload-dev": {
    "psr-4": {
        "App\Tests\": "tests"
    }
}</code>
これはphpunit.xml
からです

さて、テストを実行するたびに、このスクリプトは最初にすべての事前ファイルをPHPファイルにクリーニングして再構築します。カバレッジが正しく報告されており、幸せな旅を続けることができます…
これとは別に...

コードベースは小さいですが、小さい必要はありません。これを実際のアプリケーションで試してみることができ、テストするたびにファイルを再構築する必要があることをすぐに後悔します。

このプロジェクトでは、私が言及したこのプロジェクトでは、101の事前ファイルがあります。私の(できれば迅速な)ユニットテストスイートを実行するためには、これには多くの前処理が必要です。変更を監視し、重要な部分のみを再構築する方法が必要です。まず、ファイルオブザーバーをインストールしてみましょう:

次に、テストスクリプトを作成しましょう:

<code class="language-php">namespace App;

use Closure;

class Session
{
    private $user;

    public function __construct(array $user)
    {
        $this->user = $user;
    }

    public function closureWithUser(Closure $closure)
    {
        return () => {
            $closure($this->user);
        };
    }
}</code>

これは、スクリプト/ウォッチテスト

に由来します
<code class="language-php">require_once __DIR__ . "/vendor/autoload.php";

$session = new App\Session(["id" => 1]);

$closure = ($user) => {
    print "user: " . $user["id"] . PHP_EOL;
};

$closureWithUser = $session->closureWithUser($closure);
$closureWithUser();</code>
このスクリプトは、Symfony Finderを作成します(SRCとテストフォルダーをスキャンするために使用されます)。一時的な変更ファイルを定義しましたが、これは私たちがしていることに厳密に必要ではありません。次に、無限ループを使用します。 ResourceWatcherには、ファイルが作成、変更、または削除されたかどうかを確認するために使用できる方法があります。

新規、どのファイルが変更されたかを見つけて再構築しましょう。

これは、スクリプト/ウォッチテスト

に由来します

<code class="language-php">require_once __DIR__ . "/vendor/autoload.php";

Pre\Plugin\process(__DIR__ . "/example.pre");</code>
このコードは、Bootstrapファイルで行うことに似ていますが、変更されたファイルにのみ適用されます。また、ファイルが変更されたら、テストを再実行する必要があります。

これは、スクリプト/ウォッチテスト
に由来します

いくつかの環境変数を導入しています。これらの変数を好みに合わせて管理できますが、作曲家スクリプトに追加することをお勧めします。
<code class="language-bash">php loader.php</code>

これはcomposer.json

からです

app_coverはそれほど重要ではありません。スクリプトにコードカバレッジが含まれているかどうかをオブザーバーに伝えるだけです。 APP_REBUILDはより重要な役割を再生します。TESTS/bootstrap.phpファイルがロードされたときにpreファイルが再構築されるかどうかを制御します。ファイルが要求されたときにのみ再構築されるように、ファイルを変更する必要があります:

<code class="language-php">$closure = function ($user) {
   print "user: " . $user["id"] . PHP_EOL;
};</code>

これは、テスト/bootstrap.php

に由来します
また、ブートストラップコードを含める前に、この環境変数を設定するためにオブザーバースクリプトを変更する必要があります。オブザーバースクリプト全体が次のようになります:

<code class="language-php">public function closureWithUser(Closure $closure)
{
   return [$closure = $closure ?? null, "fn" => function () use (&$closure) {
       $closure($this->user);
   }]["fn"];
}</code>
これは、スクリプト/ウォッチテスト

に由来します

今では、事前に処理可能なファイルが変更されるたびにテストを開始し、テストを実行できるはずです...

How to Write JavaScript-Style Test Watchers in PHP

覚えておくべきいくつかのこと(rawr)。まず、オブザーバースクリプトを実行するには、chmod xスクリプト/*が必要です。次に、config:{process-timeout:0}(composer.json)を設定する必要があります。そうしないと、オブザーバーは300秒後に死亡します。

報酬ラウンド!

このテストオブザーバーは、クールな副作用も有効にしました。これは、PHPunitテストでプリプロセッサ/変換を使用する機能です。テスト/bootstrap.phpにコードを追加した場合:

<code class="language-bash">composer require pre/short-closures</code>

これは、テスト/bootstrap.php

に由来します

…そして、テストファイルでの前処理を有効にします(preの場合、それを.preに変更することを意味します)。次に、テストファイルで同じプリプロセッサの使用を開始できます。

<code class="language-json">"autoload": {
    "psr-4": {
        "App\": "src"
    }
},
"autoload-dev": {
    "psr-4": {
        "App\Tests\": "tests"
    }
}</code>
これは、テスト/sessiontest.pre

に由来します

結論

このようなテストオブザーバーを作成しようとする前に、私が非常に多くのプリプロセッサの作業をしたとは信じられません。これは、他の言語やフレームワークから学ぶことができることを証明します。これらのJavaScriptプロジェクトに関与していない場合は、各テストを実行する前にファイルを再構築し続ける場合があります。吐き気!

この方法はあなたにとって効果的ですか?非同期HTTPサーバーまたはその他の長期にわたるプロセスに適応できます。コメントであなたの考えを教えてください。

JavaScriptスタイルテストオブザーバーのFAQ(FAQ)

PHPでJavaScriptスタイルのテストオブザーバーをセットアップする方法は? PHPでJavaScriptスタイルのテストオブザーバーをセットアップするには、複数のステップが含まれます。まず、phpunitとphpunit-watcherをインストールする必要があります。 Phpunitは、コードのテストを作成する方法を提供するPHPのテストフレームワークです。 Phpunit-watcherは、ファイルを保存するときにコードを監視し、phpunitテストを実行するツールです。これらのツールをインストールした後、コードを監視してテストを自動的に実行するようにphpunit-watcherを構成できます。この設定を使用すると、コードの変更に関するフィードバックをすぐに取得できます。これにより、エラーをより迅速に発見して修正するのに役立ちます。

PHPでテストオブザーバーを使用することの利点は何ですか?

PHPでテストオブザーバーを使用することには多くの利点があります。コードの変更に関する即時フィードバックを提供します。これにより、エラーをより速く検出および修正するのに役立ちます。また、コードを変更するたびに手動でテストを実行する必要がないため、時間を節約できます。さらに、コードのテストを作成することをお勧めします。これにより、コードの品質が向上し、維持が容易になります。

JavaScript関数内でPHPコードを使用できますか?

はい、JavaScript関数内でPHPコードを使用できますが、これは推奨されません。 PHPはサーバー側の言語であり、JavaScriptはクライアント側の言語です。これは、ページがクライアントに送信される前にPHPコードがサーバーで実行され、ページが受信された後にJavaScriptコードがクライアントで実行されることを意味します。したがって、JavaScript関数内でPHPコードを使用しようとすると、PHPコードはJavaScript関数の前に実行され、予期しない結果につながる可能性があります。

Codeceptionを使用してPHPコードをテストする方法は?

Codeceptionは、単体テスト、機能テスト、および受け入れテストをサポートするPHPのテストフレームワークです。 CodeceptionでPHPコードをテストするには、まずCodeceptionをインストールし、プロジェクト用に構成する必要があります。次に、Codeceptionの構文を使用してコードのテストを作成し、CodeCeptionのコマンドラインツールを使用してテストを実行できます。

JavaScriptでPHPコードを書き込む方法は?

技術的にはJavaScriptでPHPコードを記述できますが、これは推奨されません。 PHPはサーバー側の言語であり、JavaScriptはクライアント側の言語です。これは、ページがクライアントに送信される前にPHPコードがサーバーで実行され、ページが受信された後にJavaScriptコードがクライアントで実行されることを意味します。したがって、JavaScriptでPHPコードを記述しようとすると、PHPコードがJavaScriptコードの前に実行され、予期しない結果につながる可能性があります。代わりに、Ajaxを使用してクライアントからサーバーにデータを送信する方が良いでしょう。

以上がPHPでJavaScriptスタイルのテストウォッチャーを書く方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。