Maison > développement back-end > tutoriel php > Comment écrire des observateurs de test de style JavaScript dans PHP

Comment écrire des observateurs de test de style JavaScript dans PHP

Lisa Kudrow
Libérer: 2025-02-09 10:58:10
original
687 Les gens l'ont consulté

How to Write JavaScript-Style Test Watchers in PHP

Points de base

  • Intégrer les observateurs de tests de style JavaScript dans les projets PHP, automatiser le prétraitement des conversions de fichiers et rediffuser les tests unitaires lorsque les fichiers changent, améliorant ainsi l'efficacité de développement.
  • Configurez des tests automatisés avec des outils tels que PHPUnit et observez les modifications de fichiers à l'aide de phpunit-watcher pour assurer une rétroaction immédiate et une détection des erreurs pendant le développement.
  • Implémentez les scripts de prétraitement dans les projets PHP, permettant des conversions de syntaxe similaires à JavaScript Babel, améliorant ainsi la compatibilité et réduisant les efforts de codage manuel.
  • Configurez l'environnement de test PHP pour reconstruire automatiquement les fichiers prétraités avant les tests, en maintenant une couverture de code précise et en simplifiant le processus de test.
  • Explorer des configurations avancées à l'aide d'observateurs de fichiers pour reconstruire sélectivement uniquement les fichiers modifiés, accélérant considérablement le cycle de test de grands nombres de fichiers dans de grands projets.

Cet article a été examiné par Younes Rafie. Merci à tous les pair de sitepoint pour avoir obtenu le contenu de sitepoint à son meilleur!


Je n'ai pas écrit de tests pour mon code au début. Comme beaucoup de gens, mon "test" écrit du code et rafraîchit la page. "Est-ce que ça a l'air bien?" Si je pense que c'est vrai, je vais continuer.

En fait, la plupart des travaux que j'ai faits sont pour les entreprises qui ne se soucient pas beaucoup d'autres formes de tests. Après des années d'expérience et des conseils judicieux de gens comme Chris Hartjes, j'ai vu la valeur des tests. Et j'apprends toujours à quoi ressemblent les bons tests.

How to Write JavaScript-Style Test Watchers in PHP

J'ai récemment commencé à travailler sur des projets JavaScript qui incluent des observateurs de test groupés.

Il s'agit d'un merveilleux tutoriel vidéo avancé sur le développement de NodeJS axé sur les tests!

Dans le monde de JavaScript, il n'est pas rare de prétraiter le code source. Dans le monde JavaScript, les développeurs écrivent du code en utilisant une syntaxe non pris en charge, puis convertissent le code en syntaxe largement prise en charge, souvent en utilisant un outil appelé Babel.

Pour réduire le fardeau de l'appel des scripts de conversion, le projet BULERPLAY a commencé à inclure des scripts qui surveillent automatiquement les modifications des fichiers; puis appellent ces scripts.

Les projets sur lesquels j'ai travaillé ont adopté une approche similaire aux tests unitaires de relance. Lorsque je modifie les fichiers JavaScript, les fichiers sont convertis et les tests unitaires sont redimensionnés. De cette façon, je peux voir immédiatement si quelque chose est cassé.

Le code de ce tutoriel peut être trouvé sur GitHub. Je l'ai testé avec PHP 7.1.

Paramètres du projet

J'ai commencé à mettre en place quelque chose de similaire pour Phpunit depuis que j'ai commencé à travailler sur ces projets. En fait, le premier projet que j'ai configuré le script PHPUnit Observer est un projet PHP qui prépare également des fichiers.

Après avoir ajouté un script de prétraitement à mon projet, tout a commencé:

composer require pre/short-closures
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ces scripts de prétraitement spécifiques me permettent de renommer les classes chargées automatiquement de PSR-4 (depuis path / to / file.php ⇒ path / to / file.pre) pour se opposer aux fonctionnalités qu'ils fournissent. J'ai donc ajouté ce qui suit à mon fichier composer.json:

"autoload": {
    "psr-4": {
        "App\": "src"
    }
},
"autoload-dev": {
    "psr-4": {
        "App\Tests\": "tests"
    }
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

C'est de composer.json

Ensuite, j'ai ajouté une classe pour générer une fonction contenant les détails de la session utilisateur actuelle:

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);
        };
    }
}
Copier après la connexion
Copier après la connexion

Cela vient de src / session.pre

Pour vérifier si cela fonctionne, j'ai configuré un petit exemple de script:

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();
Copier après la connexion
Copier après la connexion

Cela vient de l'exemple.pre

… et parce que je veux utiliser de courtes fermetures dans les classes non PSR-4, j'ai également besoin de configurer un chargeur:

require_once __DIR__ . "/vendor/autoload.php";

Pre\Plugin\process(__DIR__ . "/example.pre");
Copier après la connexion
Copier après la connexion

Cela vient de Loader.php

Cette section de code est beaucoup pour illustrer un petit point. La classe de session a une méthode CLOSUREWITHUSER qui accepte une fermeture et en retourne une autre. Lorsqu'il est appelé, cette nouvelle fermeture appellera la fermeture d'origine, fournissant le tableau de session utilisateur en tant que paramètre.

Pour exécuter tout cela, tapez le terminal:

php loader.php
Copier après la connexion
Copier après la connexion

En tant que note latérale, ces préprocesseurs génèrent une syntaxe PHP efficace qui est assez belle. Cela ressemble à ceci:

$closure = function ($user) {
   print "user: " . $user["id"] . PHP_EOL;
};
Copier après la connexion
Copier après la connexion

… et

public function closureWithUser(Closure $closure)
{
   return [$closure = $closure ?? null, "fn" => function () use (&$closure) {
       $closure($this->user);
   }]["fn"];
}
Copier après la connexion
Copier après la connexion

Vous ne voudrez peut-être pas soumettre des fichiers PHP et PRE au référentiel. Pour ce faire, j'ai ajouté App / ** / *. Php et Examples.php à .gitignore.

Test de réglage

Alors, comment tester cela? Commençons par installer phpunit:

composer require --dev phpunit/phpunit
Copier après la connexion
Copier après la connexion

Ensuite, nous devons créer un fichier de configuration:

<?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>
Copier après la connexion

C'est de phpunit.xml

Si nous exécutons le fournisseur / bin / phpunit, cela fonctionnera. Mais nous n'en avons pas encore testé. Faisons-en un:

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);
    }
}
Copier après la connexion

Cela provient de tests / sessiontest.php

Lorsque nous exécutons le fournisseur / bin / phpunit, un seul test passe. Ouais!

Que nous manque-t-il?

Jusqu'à présent, tout s'est bien passé. Nous avons écrit un petit code et des tests de ce morceau de code. Nous n'avons même pas à nous soucier du fonctionnement du prétraitement (une étape qu'un projet JavaScript).

Le problème commence lorsque nous essayons de vérifier la couverture du code:

vendor/bin/phpunit --coverage-html coverage
Copier après la connexion

Au moment où nous avons testé la session, la couverture sera signalée. C'est une classe simple, nous avons donc obtenu une couverture à 100%. Mais si nous ajoutons une autre classe:

namespace App;

class BlackBox
{
    public function get($key)
    {
        return $GLOBALS[$key];
    }
}
Copier après la connexion

Cela vient de SRC / BlackBox.Pre

Que se passe-t-il lorsque nous vérifions la couverture? Toujours à 100%.

Cela se produit parce que nous n'avons pas de tests chargeant BlackBox.pre, ce qui signifie qu'il n'est jamais compilé. Par conséquent, lorsque PHPUnit recherche un fichier PHP écrasé, il ne peut pas voir ce fichier pré-cours.

Créez tous les fichiers avant de tester

Créons un nouveau script pour créer tous les fichiers pré avant d'essayer d'exécuter le test:

composer require pre/short-closures
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cela provient des tests / bootstrap.php

Ici, nous créons 3 fonctions;

Nous devons remplacer le fichier bootstrap actuel dans phpunit.xml:

"autoload": {
    "psr-4": {
        "App\": "src"
    }
},
"autoload-dev": {
    "psr-4": {
        "App\Tests\": "tests"
    }
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

C'est de phpunit.xml

Maintenant, chaque fois que nous exécutons le test, ce script nettoyera et reconstruia d'abord tous les fichiers pré au fichier PHP. La couverture est correctement signalée et nous pouvons continuer notre heureux voyage…

à part cela ...

Notre base de code est petite, mais elle n'a pas besoin d'être petite. Nous pouvons essayer ceci dans une vraie application et regretter immédiatement d'avoir à reconstruire le fichier chaque fois que nous voulons le tester.

Dans ce projet que j'ai mentionné, j'ai 101 fichiers pré. Juste pour exécuter ma suite de test unitaire (espérons-le rapide), cela nécessite beaucoup de prétraitement. Nous avons besoin d'un moyen de surveiller les changements et de reconstruire uniquement les pièces importantes. Tout d'abord, installons un observateur de fichiers:

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);
        };
    }
}
Copier après la connexion
Copier après la connexion

Ensuite, créons un script de test:

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();
Copier après la connexion
Copier après la connexion

Cela provient des scripts / test de montre

Ce script crée un Symfony Finder (utilisé pour scanner nos dossiers SRC et tests). Nous avons défini un fichier de changement temporaire, mais ce n'est pas strictement requis pour ce que nous faisons. Nous utilisons ensuite une boucle infinie. ResourceWatcher a une méthode que nous pouvons utiliser pour voir si un fichier a été créé, modifié ou supprimé.

Nouveau, trouvons quels fichiers ont été modifiés et les reconstruisez:

require_once __DIR__ . "/vendor/autoload.php";

Pre\Plugin\process(__DIR__ . "/example.pre");
Copier après la connexion
Copier après la connexion

Cela provient des scripts / test de montre

Ce code est similaire à ce que nous faisons dans le fichier bootstrap, mais il ne s'applique qu'aux fichiers modifiés. Nous devons également relancer le test lorsque le fichier change:

php loader.php
Copier après la connexion
Copier après la connexion

Cela provient des scripts / test de montre

Nous introduisons plusieurs variables d'environnement. Vous pouvez gérer ces variables à votre goût, mais je préfère les ajouter au script compositeur:

$closure = function ($user) {
   print "user: " . $user["id"] . PHP_EOL;
};
Copier après la connexion
Copier après la connexion

C'est de composer.json

App_cover n'est pas si important. Il indique simplement à l'observateur si le script contient une couverture de code. App_rebuild joue un rôle plus important: il contrôle si le fichier pré est reconstruit lorsque le fichier tests / bootstrap.php est chargé. Nous devons modifier le fichier afin que le fichier soit reconstruit uniquement à la demande:

public function closureWithUser(Closure $closure)
{
   return [$closure = $closure ?? null, "fn" => function () use (&$closure) {
       $closure($this->user);
   }]["fn"];
}
Copier après la connexion
Copier après la connexion

Cela provient des tests / bootstrap.php

Nous devons également modifier le script Observer pour définir cette variable d'environnement avant d'inclure le code bootstrap. L'ensemble du script d'observateur ressemble à ceci:

composer require --dev phpunit/phpunit
Copier après la connexion
Copier après la connexion

Cela provient des scripts / test de montre

Maintenant, nous devrions être en mesure de le démarrer et d'exécuter nos tests chaque fois que le fichier pré-cours change ...

How to Write JavaScript-Style Test Watchers in PHP

quelques choses à retenir (RAWR). Tout d'abord, vous avez besoin de scripts CHMOD X / * pour exécuter le script Observer. Deuxièmement, vous devez définir la configuration: {Process-Timeout: 0} (dans Composer.json), sinon l'observateur mourra après 300 secondes.

Récompense Round!

Cet observateur de test a également permis un effet secondaire frais: la possibilité d'utiliser un préprocesseur / conversion dans nos tests de phpunit. Si nous ajoutons du code aux tests / bootstrap.php:

composer require pre/short-closures
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cela provient des tests / bootstrap.php

… et nous permettons le prétraitement dans le fichier de test (pour pré, cela signifie le renommer à .pre). Ensuite, nous pouvons commencer à utiliser le même préprocesseur dans notre fichier de test:

"autoload": {
    "psr-4": {
        "App\": "src"
    }
},
"autoload-dev": {
    "psr-4": {
        "App\Tests\": "tests"
    }
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cela provient de tests / sessiontest.pre

Conclusion

Je ne peux pas croire que j'ai fait tellement de travail de préprocesseur avant d'essayer de créer un tel observateur de test. Cela prouve ce que nous pouvons apprendre des autres langues et cadres. Si je ne suis pas impliqué dans ces projets JavaScript, je peux continuer à reconstruire mes fichiers avant chaque test. nausée!

Cette méthode est-elle efficace pour vous? Il peut s'adapter à un serveur HTTP asynchrone ou à d'autres processus de longue durée. Veuillez nous dire ce que vous pensez dans les commentaires.

FAQS pour les observateurs de test de style JavaScript en php (FAQ)

Comment configurer un observateur de test de style JavaScript dans PHP?

La configuration des observateurs de test de style JavaScript dans PHP implique plusieurs étapes. Tout d'abord, vous devez installer PHPUNIT et PHPUnit-watcher. PHPUnit est un cadre de test pour PHP qui fournit un moyen d'écrire des tests de code. Phpunit-watcher est un outil qui surveille votre code et exécute des tests PHPUnit lors de l'enregistrement des fichiers. Après avoir installé ces outils, vous pouvez configurer Phpunit-watcher pour surveiller votre code et exécuter automatiquement vos tests. Ce paramètre vous permet d'obtenir immédiatement des commentaires sur les modifications de code, ce qui peut vous aider à découvrir et à corriger les erreurs plus rapidement.

Quels sont les avantages de l'utilisation d'observateurs de test en PHP?

Il y a de nombreux avantages à utiliser des observateurs de test dans PHP. Il fournit des commentaires instantanés sur les modifications de code, ce qui peut vous aider à découvrir et à corriger les erreurs plus rapidement. Cela vous fait également gagner du temps car vous n'avez pas à exécuter le test manuellement après chaque changement de code. De plus, il vous encourage à rédiger des tests pour votre code, ce qui peut améliorer la qualité de votre code et faciliter la maintenance.

Puis-je utiliser du code PHP dans une fonction JavaScript?

Oui, vous pouvez utiliser le code PHP dans les fonctions JavaScript, mais cela n'est pas recommandé. PHP est un langage côté serveur, tandis que JavaScript est un langage côté client. Cela signifie que le code PHP est exécuté sur le serveur avant l'envoi de la page au client, tandis que le code JavaScript est exécuté sur le client après la réception de la page. Par conséquent, si vous essayez d'utiliser du code PHP dans une fonction JavaScript, le code PHP sera exécuté avant la fonction JavaScript, ce qui peut conduire à des résultats inattendus.

Comment utiliser CodeCection pour tester mon code PHP?

CodeCection est un cadre de test pour PHP qui prend en charge les tests unitaires, les tests fonctionnels et les tests d'acceptation. Pour tester votre code PHP avec CodeCeception, vous devez d'abord installer CodeCeception et le configurer pour votre projet. Vous pouvez ensuite rédiger des tests pour votre code à l'aide de la syntaxe de CodeCection et exécuter vos tests à l'aide de l'outil de ligne de commande de codeceception.

Comment écrire du code PHP dans JavaScript?

Bien que techniquement, vous pouvez écrire du code PHP en JavaScript, cela n'est pas recommandé. PHP est un langage côté serveur, tandis que JavaScript est un langage côté client. Cela signifie que le code PHP est exécuté sur le serveur avant l'envoi de la page au client, tandis que le code JavaScript est exécuté sur le client après la réception de la page. Par conséquent, si vous essayez d'écrire du code PHP dans JavaScript, le code PHP sera exécuté avant le code JavaScript, ce qui peut conduire à des résultats inattendus. Au lieu de cela, il est préférable d'utiliser Ajax pour envoyer des données du client au serveur et vice versa.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal