Kernpunkte
Dieser Artikel wurde von Younes Rafie überprüft. Vielen Dank an alle SitePoint -Peer -Rezensenten, die SidePoint -Inhalte für die Besten erhalten haben!
Ich habe am Anfang keine Tests für meinen Code geschrieben. Wie viele Menschen besteht mein "Test" darin, Code zu schreiben und die Seite zu aktualisieren. "Sieht es richtig aus?" Wenn ich denke, dass es richtig ist, werde ich weitermachen.
In der Tat ist die meisten Arbeiten, die ich geleistet habe, an Unternehmen, die sich nicht viel für andere Testformen interessieren. Nach jahrelanger Erfahrung und weisen Ratschlägen von Menschen wie Chris Hartjes sah ich den Wert des Tests. Und ich lerne immer noch, wie gute Tests aussehen.
Ich habe kürzlich angefangen, an einigen JavaScript -Projekten zu arbeiten, die gebündelte Testbeobachter enthalten.
Dies ist ein wunderbares fortgeschrittenes Video-Tutorial zur testgesteuerten NodeJS-Entwicklung!
In der Welt von JavaScript ist es nicht ungewöhnlich, Quellcode vorzubereiten. In der JavaScript -Welt schreiben Entwickler Code mit einer nicht unterstützten Syntax und konvertieren den Code dann in eine weit verbreitete Syntax, häufig mit einem Tool namens Babel.
Um die Belastung für das Aufrufen von Konvertierungsskripten zu verringern, hat das Boilerplate -Projekt begonnen, Skripte einzubeziehen, die automatisch Dateiänderungen überwachen.
Die Projekte, an denen ich gearbeitet habe, verfolgte einen ähnlichen Ansatz, um Unit -Tests wiederzugeben. Wenn ich die JavaScript -Dateien ändere, werden die Dateien konvertiert und die Unit -Tests werden erneut gestellt. Auf diese Weise kann ich sofort sehen, ob etwas gebrochen ist.
Der Code für dieses Tutorial finden Sie in GitHub. Ich habe es mit PHP 7.1 getestet.
Ich habe angefangen, für Phpunit etwas Ähnliches einzurichten, seit ich an diesen Projekten gearbeitet habe. Tatsächlich ist das erste Projekt, das ich das Phpunit Observer -Skript eingerichtet habe, ein PHP -Projekt, das auch Dateien vorbereitet.
Nachdem ich meinem Projekt ein Vorverarbeitungsskript hinzugefügt hatte, begann alles:
composer require pre/short-closures
Diese spezifischen Vorverarbeitungsskripte ermöglichen es mir, die automatisch geladenen Klassen von PSR-4 (von Pfad/to/file.php ⇒ path/to/file.pre) umzubenennen, um sich in die von ihnen bereitgestellten Funktionen zu deaktivieren. Also habe ich meine Composer.json -Datei Folgendes hinzugefügt:
"autoload": { "psr-4": { "App\": "src" } }, "autoload-dev": { "psr-4": { "App\Tests\": "tests" } }
Dies ist von Composer.json
Dann habe ich eine Klasse hinzugefügt, um eine Funktion zu generieren, die die Details der aktuellen Benutzersitzung enthält:
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); }; } }
Dies stammt von SRC/Session.pre
Um zu überprüfen, ob dies funktioniert, habe ich ein kleines Beispielskript eingerichtet:
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();
Dies stammt von Beispiel.pre
… und weil ich kurze Verschlüsse in Nicht-PSR-4-Klassen verwenden möchte, muss ich auch einen Loader einrichten:
require_once __DIR__ . "/vendor/autoload.php"; Pre\Plugin\process(__DIR__ . "/example.pre");
Dies stammt von lader.php
Dieser Codeabschnitt ist viel zu veranschaulichen, um einen kleinen Punkt zu veranschaulichen. Die Sitzungsklasse verfügt über eine Verschlussmethode, die einen Verschluss akzeptiert und eine andere zurückgibt. Bei der Aufforderung wird dieser neue Verschluss den ursprünglichen Verschluss aufgerufen und das Array der Benutzersitzung als Parameter bereitgestellt.
Geben Sie all dies in das Terminal ein:
php loader.php
Als Randnotiz erzeugen diese Präprozessoren eine effektive PHP -Syntax, die ziemlich schön ist. Es sieht so aus:
$closure = function ($user) { print "user: " . $user["id"] . PHP_EOL; };
… und
public function closureWithUser(Closure $closure) { return [$closure = $closure ?? null, "fn" => function () use (&$closure) { $closure($this->user); }]["fn"]; }
Sie möchten möglicherweise nicht sowohl PHP als auch Pre -Dateien an das Repository senden. Dazu habe ich App/**/*. PHP und Beispiele.Php zu .Gitignore hinzugefügt.
Wie testen wir das? Beginnen wir mit der Installation von Phpunit:
composer require --dev phpunit/phpunit
Dann sollten wir eine Konfigurationsdatei erstellen:
<?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>
Dies ist von phpunit.xml
Wenn wir Anbieter/bin/phpunit ausführen, wird es funktionieren. Aber wir haben noch keine getestet. Lass uns einen machen:
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); } }
Dies stammt aus Tests/SessionTest.php
Wenn wir Anbieter/bin/phpunit ausführen, besteht ein einzelner Test. Ja!
Bisher lief alles gut. Wir haben ein kleines Code und Tests dieses Codes geschrieben. Wir müssen uns nicht einmal Sorgen machen, wie die Vorverarbeitung funktioniert (ein Schritt -up als ein JavaScript -Projekt).
Das Problem beginnt, wenn wir versuchen, die Codeabdeckung zu überprüfen:
vendor/bin/phpunit --coverage-html coverage
Beim Testen der Sitzung wird die Berichterstattung gemeldet. Es ist eine einfache Klasse, also haben wir eine 100% ige Abdeckung erreicht. Aber wenn wir eine andere Klasse hinzufügen:
namespace App; class BlackBox { public function get($key) { return $GLOBALS[$key]; } }
Dies kommt von SRC/Blackbox.pre
Was passiert, wenn wir die Abdeckung überprüfen? Immer noch 100%.
Dies geschieht, weil wir keine Tests zum Laden von Blackbox.pre haben, was bedeutet, dass es nie kompiliert wird. Wenn Phpunit nach einer überschriebenen PHP -Datei sucht, kann diese vorverarbeitbare Datei daher nicht angezeigt werden.
Erstellen wir ein neues Skript, um alle Pre -Dateien zu erstellen, bevor wir versuchen, den Test auszuführen:
composer require pre/short-closures
Dies stammt aus Tests/Bootstrap.php
Hier erstellen wir 3 Funktionen;
Wir müssen die aktuelle Bootstrap -Datei in phpunit.xml ersetzen:
"autoload": { "psr-4": { "App\": "src" } }, "autoload-dev": { "psr-4": { "App\Tests\": "tests" } }
Dies ist von phpunit.xml
Wenn wir jetzt den Test ausführen, wird dieses Skript zuerst alle Pre -Dateien in die PHP -Datei reinigen und umstellen. Die Berichterstattung wird richtig gemeldet und wir können unsere glückliche Reise fortsetzen…
Unsere Codebasis ist klein, muss aber nicht klein sein. Wir können dies in einer echten Anwendung versuchen und es sofort bedauern, die Datei jedes Mal wieder aufzubauen, wenn wir sie testen möchten.
In diesem Projekt habe ich 101 Pre -Dateien. Nur um meine (hoffentlich schnelle) Unit -Testsuite zu betreiben, erfordert dies eine Menge Vorverarbeitung. Wir brauchen eine Möglichkeit, Änderungen zu überwachen und nur wichtige Teile wieder aufzubauen. Lassen Sie uns zunächst einen Dateibeobachter installieren:
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); }; } }
Erstellen wir dann ein Testskript:
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();
Dies stammt aus Skripten/Uhr-Test
Dieses Skript erstellt einen Symfony -Finder (zum Scannen unserer SRC -Ordner). Wir haben eine temporäre Änderungsdatei definiert, aber dies ist nicht ausschließlich für das, was wir tun, erforderlich. Als nächstes verwenden wir eine unendliche Schleife. ResourceWatcher verfügt über eine Methode, mit der wir feststellen können, ob eine Datei erstellt, geändert oder gelöscht wurde.
Neu, lasst uns herausfinden, welche Dateien geändert wurden, und sie neu aufbauen:
require_once __DIR__ . "/vendor/autoload.php"; Pre\Plugin\process(__DIR__ . "/example.pre");
Dies stammt aus Skripten/Uhr-Test
Dieser Code ähnelt dem, was wir in der Bootstrap -Datei tun, aber er gilt nur für die geänderten Dateien. Wir sollten auch den Test erneut ausführen, wenn sich die Datei ändert:
php loader.php
Dies stammt aus Skripten/Uhr-Test
Wir stellen mehrere Umgebungsvariablen ein. Sie können diese Variablen nach Ihren Wünschen verwalten, aber ich füge sie lieber zum Komponisten -Skript hinzu:
$closure = function ($user) { print "user: " . $user["id"] . PHP_EOL; };
Dies ist von Composer.json
app_cover ist nicht so wichtig. Es sagt nur dem Beobachter, ob das Skript die Codeabdeckung enthält. App_Rebuild spielt eine wichtigere Rolle: Sie steuert, ob die Pre -Datei wieder aufgebaut wird, wenn die Datei Tests/Bootstrap.php geladen wird. Wir müssen die Datei so ändern, dass die Datei nur dann wieder aufgebaut wird:
public function closureWithUser(Closure $closure) { return [$closure = $closure ?? null, "fn" => function () use (&$closure) { $closure($this->user); }]["fn"]; }
Dies stammt aus Tests/Bootstrap.php
Wir müssen auch das Observer -Skript ändern, um diese Umgebungsvariable vor dem Einbeziehen von Bootstrap -Code festzulegen. Das gesamte Observer -Skript sieht so aus:
composer require --dev phpunit/phpunit
Dies stammt aus Skripten/Uhr-Test
Jetzt sollten wir in der Lage sein, es zu starten und unsere Tests jedes Mal auszuführen, wenn sich die vorverarbeitbare Datei ändert ...
Ein paar Dinge, an die man sich erinnern sollte (RAWR). Zunächst benötigen Sie CHMOD X -Skripte/*, um das Observer -Skript auszuführen. Zweitens müssen Sie die Konfiguration festlegen: {Process-Timeout: 0} (in Composer.json), andernfalls stirbt der Beobachter nach 300 Sekunden.
Dieser Testbeobachter ermöglichte auch einen coolen Nebeneffekt: die Fähigkeit, Precessor/Conversion in unseren Phpunit -Tests zu verwenden. Wenn wir einen Code zum Testen/Bootstrap.php hinzufügen:
composer require pre/short-closures
Dies stammt aus Tests/Bootstrap.php
… und wir aktivieren die Vorverarbeitung in der Testdatei (für Pre, das bedeutet, sie in .pre umbenennen). Dann können wir in unserer Testdatei denselben Präprozessor verwenden:
"autoload": { "psr-4": { "App\": "src" } }, "autoload-dev": { "psr-4": { "App\Tests\": "tests" } }
Dies stammt aus Tests/SessionTest.pre
Ich kann nicht glauben, dass ich so viel Vorprozessorarbeit gemacht habe, bevor ich versuchte, einen solchen Testbeobachter zu erstellen. Dies beweist, was wir aus anderen Sprachen und Frameworks lernen können. Wenn ich nicht an diesen JavaScript -Projekten beteiligt bin, kann ich meine Dateien vor jedem Testlauf weiter wieder aufbauen. Brechreiz!
Ist diese Methode für Sie effektiv? Es kann sich an einen asynchronen HTTP-Server oder andere langlebige Prozesse anpassen. Bitte teilen Sie uns mit, was Sie in den Kommentaren denken.
Einrichten von Testbeobachtern im JavaScript-Stil in PHP umfasst mehrere Schritte. Zuerst müssen Sie Phpunit und Phpunit-Watcher installieren. PHPUnit ist ein Testframework für PHP, der eine Möglichkeit bietet, Tests für Code zu schreiben. Phpunit-Watcher ist ein Tool, das Ihren Code überwacht und beim Speichern von Dateien Phpunit-Tests ausführt. Nach der Installation dieser Tools können Sie Phpunit-Watcher so konfigurieren, dass Sie Ihren Code überwachen und Ihre Tests automatisch ausführen. Mit dieser Einstellung können Sie sofort Feedback zu Codeänderungen abrufen, um Fehler schneller zu ermitteln und zu beheben.
Es gibt viele Vorteile für die Verwendung von Testbeobachtern in PHP. Es bietet sofortige Feedback zu Codeänderungen, mit denen Sie Fehler schneller ermitteln und beheben können. Es spart Ihnen auch Zeit, weil Sie den Test nach jeder Codeänderung nicht manuell ausführen müssen. Darüber hinaus ermutigt es Sie, Tests für Ihren Code zu schreiben, die die Qualität Ihres Codes verbessern und die Wartung erleichtern können.
Ja, Sie können PHP -Code in JavaScript -Funktionen verwenden, dies wird jedoch nicht empfohlen. PHP ist eine serverseitige Sprache, während JavaScript eine clientseitige Sprache ist. Dies bedeutet, dass der PHP -Code auf dem Server ausgeführt wird, bevor die Seite an den Client gesendet wird, während der JavaScript -Code nach Empfang der Seite auf dem Client ausgeführt wird. Wenn Sie versuchen, den PHP -Code in einer JavaScript -Funktion zu verwenden, wird der PHP -Code vor der JavaScript -Funktion ausgeführt, was zu unerwarteten Ergebnissen führen kann.
Codecception ist ein Testframework für PHP, das Unit -Tests, Funktionstests und Akzeptanztests unterstützt. Um Ihren PHP -Code mit Codecception zu testen, müssen Sie zunächst die Codecception installieren und für Ihr Projekt konfigurieren. Sie können dann Tests für Ihren Code über die Syntax der Codecception schreiben und Ihre Tests mit dem Befehlszeilen -Tool der Codekzeption ausführen.
Während Sie technisch gesehen PHP -Code in JavaScript schreiben können, wird dies nicht empfohlen. PHP ist eine serverseitige Sprache, während JavaScript eine clientseitige Sprache ist. Dies bedeutet, dass der PHP -Code auf dem Server ausgeführt wird, bevor die Seite an den Client gesendet wird, während der JavaScript -Code nach Empfang der Seite auf dem Client ausgeführt wird. Wenn Sie versuchen, PHP -Code in JavaScript zu schreiben, wird der PHP -Code vor dem JavaScript -Code ausgeführt, was zu unerwarteten Ergebnissen führen kann. Stattdessen ist es besser, AJAX zu verwenden, um Daten vom Client an den Server zu senden und umgekehrt.
Das obige ist der detaillierte Inhalt vonSo schreiben Sie Testbeobachter im JavaScript-Stil in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!