Unit-Tests mit PHPUnit schreiben, Teil 3: XML-Konfiguration
In den vergangenen Beiträgen dieser Serie habe ich die folgenden zwei Themen behandelt:
- Unit-Tests mit PHPUnit schreiben, Teil 1: Die Einrichtung. Ein Leitfaden für die ersten Schritte beim Schreiben von PHPUnit-Tests durch die Verwendung eines einfachen Caches und die Verwendung der setUp-Methode des Frameworks.
- Unit-Tests mit PHPUnit schreiben, Teil 2: Der Teardown. Ein Tutorial zum Schreiben von Unit-Tests, die die setUp- und tearDown-Methoden von PHPUnit richtig nutzen.
Jeder der oben genannten Punkte soll eine Einführung in die ersten Schritte beim Schreiben sehr einfacher Unit-Tests bieten. Die Dinge können komplexer werden, besonders wenn eine Anwendung oder ein Projekt wächst (aber das ist immer wahr, oder?).
Aber um sicherzustellen, dass man darauf vorbereitet ist, gibt es eine letzte Komponente des Komponententests, auf die wir uns meiner Meinung nach konzentrieren sollten, und das ist das Verständnis der PHPUnit-XML-Konfigurationsdatei (die Sie vielleicht in anderen Projekten als phpunit.xml gesehen haben).
PHPUnit-XML-Konfiguration
In diesem Beitrag werde ich also ein einfaches Projekt einrichten, das PHPUnit verwendet, einige Tests wie die, die wir bereits gesehen haben, schreibt und eine Konfigurationsdatei zum Automatisieren von Tests nutzt.
Außerdem werde ich tun, was ich kann, um die notwendigen Teile der Konfigurationsdatei so gut wie möglich zu erklären, damit Sie einen in Ihr nächstes Projekt aufnehmen können.
1 Stubbing der Dateien
Bevor Sie tatsächlich testbaren Code schreiben, ist es wichtig, die Dateien zu kennen, die benötigt werden, damit der Prozess funktioniert.
So organisieren wir die Dinge mehr oder weniger von Beginn eines Projekts an:
- ein Verzeichnis für Tests,
- die Datei phpunit.xml
Schließlich sehen Sie auch:
- die Dateien, aus denen das Projekt besteht,
- die Tests, die diese Dateien überprüfen.
An dieser Stelle werfen wir jedoch einen Blick auf die XML-Konfigurationsdatei und versuchen dann, PHPUnit automatisch ohne weitere Parameter auszuführen.
2 Grundlagen zur Konfigurationsdatei
Schauen wir uns zunächst die grundlegende Konfigurationsdatei an:
<?xml version="1.0" encoding="UTF-8"?>
<!-- http://phpunit.de/manual/4.1/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
bootstrap="./tests/bootstrap.php"
backupGlobals="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
>
<testsuites>
<testsuite name="AcmeTests">
<directory>./tests</directory>
</testsuite>
</testsuites>
<logging>
<log type="coverage-text" target="php://stdout" showUncoveredFiles="true"></log>
</logging>
</phpunit>
Lassen Sie uns nun verstehen, was wir genau betrachten (außer einfachem XML).
- phpunit. Der übergeordnete Knoten erledigt die übliche Aufgabe, das Schema für die XML-Datei zu definieren, aber es gibt noch ein paar andere Komponenten, mit denen wir uns nämlich befassen:
- backupGlobals. Dies hängt tatsächlich mit einer Anmerkung zusammen, die wir in unserem Quellcode vornehmen können. Globals sind etwas, das wir in der objektorientierten Programmierung vermeiden sollten, aber wenn Sie sich entscheiden, eines zu verwenden oder eines verwenden müssen, dann wird PHPUnit angewiesen, die Werte zu handhaben, die die globalen Variablen verwalten (und Ihnen die Möglichkeit geben, sie wiederherzustellen Sie). Ich lasse das grundsätzlich so wie es ist.
- Bootstrap. Dies ist optional, aber wenn Sie sich dafür entscheiden, andere Dateien in Ihre Tests aufzunehmen (z. B. das Einbringen einer spöttischen Bibliothek, eines Teils von WordPress oder einer Bibliothek eines Drittanbieters), dann reicht dies aus, um den Speicherort des erforderlichen Skripts zu definieren ausführen. Das Verspotten und Einbringen von WordPress würde den Rahmen dieses Beitrags sprengen, aber wir werden uns wahrscheinlich in Zukunft damit befassen, da es beim Testen von Plugins nützlich ist. Im Moment füge ich einen einfachen Autoloader hinzu, der im Grunde alle Dateien im Stammverzeichnis des Projektverzeichnisses hinzufügt. Die vollständige Quelle dafür wird später in diesem Beitrag geteilt.
- Farben. Wenn Sie möchten, dass die Konsole einen Bericht Ihrer Tests ausdruckt und dies mit Farben tut (um Warnungen, Hinweise, Fehler usw. leichter identifizieren zu können), dann setzen Sie dies auf true.
- Die folgenden sind alle booleschen Werte. Ich empfehle, sie für möglichst aggressive Berichte auf „ true “ zu setzen. Auf diese Weise kommen Sie nicht damit davon, dass Hinweise oder Warnungen einfach durchgehen, während Sie sich nur um Fehler kümmern. Dies ist eher eine Übung in Bezug auf die Codequalität als alles andere.
- convertErrorsToExceptions
- convertNoticesToExceptions
- convertWarningsToExceptions
- Testsuiten bestehen aus Sammlungen von Tests. Da ein bestimmtes Projekt mehrere Tests haben kann, ist es wichtig sicherzustellen, dass Sie jeder Suite einen eindeutigen Namen geben und auf den richtigen Pfad zu der Testgruppe verweisen. In unserem Beispiel haben wir nur eine einzige Testsuite, die sich im Verzeichnis tests befindet .
- Die Protokollierung ist eine Funktion, die so einfach sein kann wie das Drucken von Daten in die Konsole oder die Verwendung einer Bibliothek eines Drittanbieters (wie Clover ), um Berichte zu erstellen, die bei der kontinuierlichen Integration helfen. Da ich letzteres noch in keinem meiner vorherigen Posts besprochen habe, werden wir bei der Konsole als unserer Hauptausgabemethode bleiben. Daher haben wir php ://stdout als unsere einzige Protokollausgabe.
Mit all dem hat unsere XML-Datei alles, was PHPUnit braucht, um ohne andere Parameter zu laufen.
Denken Sie jedoch daran, bevor Sie mit dem Rest dieses Artikels fortfahren, dass Sie PHPUnit mithilfe von Composer global auf Ihrem System installiert haben. Wenn nicht, lesen Sie diesen Artikel, da er Ihnen Anweisungen dazu gibt.
Sobald Sie fertig sind, können Sie überprüfen, ob PHPUnit installiert ist, indem Sie den folgenden Befehl in Ihr Terminal eingeben:
$ which phpunit
Und Sie sollten so etwas wie das Folgende sehen:
Wenn Sie so etwas wie oben sehen, können Sie PHPUnit überall auf Ihrem System ausführen.
3 Die Bootstrap-Datei
Bevor wir fortfahren, schreiben wir eine grundlegende Bootstrap-Datei. Wir nennen es bootstrap.php und legen es in unserem Testverzeichnis ab. Es wird Folgendes enthalten:
<?php
// This array has a single file but could whole the contents of an entire directory.
$files = [
dirname(__DIR__).'/AcmeCache.php',
];
foreach ($files as $file) {
if (file_exists($file)) {
require_once $file;
}
}
Dies ist ein einfacher „Autoloader“ (den ich zögernd so nenne, da er nur Dateien durchläuft und sie benötigt, aber für unsere Zwecke funktioniert er).
Lassen Sie uns an dieser Stelle einen grundlegenden Test einrichten.
4 Ein grundlegender, fehlgeschlagener Test
Wenn Sie etwas über testgetriebene Entwicklung lesen, werden Sie wahrscheinlich von einem Rot-Grün-Wiederholungszyklus hören. Dazu gibt es viel zu sagen, und ich empfehle , darüber nachzulesen, aber das ist nicht der Zweck dieses Beitrags.
Stattdessen konzentrieren wir uns mehr darauf, Tests zu schreiben, die dem entsprechen, was wir tun müssen, richtig? Lassen Sie uns also Folgendes tun:
- Erstellen Sie ein Verzeichnis, in dem Sie einige grundlegende PHP-Dateien haben, die wir testen werden.
- Erstellen Sie im Stammverzeichnis des Verzeichnisses auch phpunit.xml und füllen Sie es mit dem zuvor in diesem Beitrag geteilten Code
- Erstellen Sie ein Testverzeichnis, in dem wir unsere Tests platzieren.
Wechseln Sie nun vom Terminal aus in das Verzeichnis des Projekts (das zugegebenermaßen vorerst fehlt) und führen Sie dann einfach php unit aus:
$ phpunit
Vorausgesetzt, alles ist korrekt eingerichtet, sollten Sie so etwas sehen:
Da wir keinen Code und keine Tests haben, sehen wir natürlich die obige Ausgabe, richtig? Lassen Sie uns also einen einzelnen Test schreiben, der ausgeführt wird (und fehlschlägt), da es keinen Code zum Testen gibt.
Erstellen Sie zunächst im Verzeichnis tests eine Datei namens AcmeCacheTest.php. Und lassen Sie es etwas Einfaches tun, z. B. ein Cache-Objekt instanziieren, das wir schließlich erstellen werden.
<?php
namespace AcmeTests;
use PHPUnitFrameworkTestCase;
use AcmeAcmeCache;
class AcmeCacheTest extends TestCase
{
private $cache;
public function setUp()
{
$this->cache = new AcmeCache();
}
public function testCacheExists()
{
$this->assertNotNull($this->cache);
}
}
Beachten Sie vor dem Ausführen des Tests Folgendes:
- Stellen Sie sicher, dass Sie PHPUnitFrameworkTestCase verwenden
- Und lassen Sie unsere Klasse TestCase erweitern
Dies ist ein Teil dessen, was die Verwendung von PHPUnit so einfach macht. Führen Sie anschließend den folgenden Code im Stammverzeichnis Ihres Projekts aus:
$ phpunit
Danach sollten Sie Folgendes sehen:
Beachten Sie, dass dies zu einem fehlgeschlagenen Test führt und Ihnen mitteilt, wo das Problem gefunden wurde, die Datei und die Zeile.
Um dies zu beheben, müssen wir eine Klasse schreiben:
<?php
namespace Acme;
class AcmeCache
{
private $duration;
public function __construct()
{
$this->duration = 43200;
}
public function setDuration(int $duration)
{
$this->duration = $duration;
}
public function getDuration(): int
{
return $this->duration;
}
}
4 Ein paar grundlegende, bestandene Tests
Der grundlegende Bestehenstest (der auf dem vorherigen Code basiert) umfasst Folgendes:
- eine Namespace-Datei,
- stellt einen einfachen Cache dar,
- wird automatisch von PHPUnit geladen, indem die oben freigegebene Datei bootstrap.php verwendet wird
- und hat eine in seinem Konstruktor festgelegte Dauer zusammen mit einem Setter und Getter für den Wert
Lassen Sie uns zunächst testen, ob wir die Klasse einrichten können und ob sie nicht null ist. Dies ist eine etwas unnötige Behauptung, da wir wissen, dass wir eine Klasse richtig instanziiert haben, aber es bringt uns in den Groove des Schreibens von Tests:
<?php
namespace AcmeTests;
use PHPUnitFrameworkTestCase;
use AcmeAcmeCache;
class AcmeCacheTest extends TestCase
{
private $cache;
public function setUp()
{
$this->cache = new AcmeCache();
}
public function testCacheExists()
{
$this->assertNotNull($this->cache);
}
}
Und führen Sie den Test durch:
Lassen Sie uns als Nächstes überprüfen, ob der Standardwert des Caches festgelegt ist:
<?php
namespace AcmeTests;
use PHPUnitFrameworkTestCase;
use AcmeAcmeCache;
class AcmeCacheTest extends TestCase
{
private $cache;
public function setUp()
{
$this->cache = new AcmeCache();
}
public function testCacheExists()
{
$this->assertNotNull($this->cache);
}
public function testDefaultCacheValue()
{
$this->assertSame(43200, $this->cache->getDuration());
}
}
Führen Sie wie im vorherigen Schritt die Tests aus, und Sie sollten jetzt zwei bestandene Tests sehen:
Lassen Sie uns abschließend testen, ob wir den Wert erfolgreich ändern können:
<?php
namespace AcmeTests;
use PHPUnitFrameworkTestCase;
use AcmeAcmeCache;
class AcmeCacheTest extends TestCase
{
private $cache;
public function setUp()
{
$this->cache = new AcmeCache();
}
public function testCacheExists()
{
$this->assertNotNull($this->cache);
}
public function testDefaultCacheValue()
{
$this->assertSame(43200, $this->cache->getDuration());
}
public function testSetCustomDuration()
{
$duration = 4200;
$this->cache->setDuration($duration);
$this->assertSame($duration, $this->cache->getDuration());
}
}
Und die letzten drei bestandenen Tests:
Und da hast du es:
- eine PHPUnit-XML-Datei,
- ein einfacher Bootstrap,
- eine einzelne Klasse mit Namespace,
- Unit-Tests für jede Methode der Klasse
Zugegeben, es ist einfach, aber dies legt die Grundlagen für so viel mehr als das, was viele Menschen bereits mit ihren Tests tun.
Darüber hinaus gibt es Ihnen etwas, worauf Sie aufbauen können, wenn Ihre Testkünste stärker werden.
Ist da mehr? (Immer richtig?)
Wenn Sie wirklich in die Konfigurationsdatei eintauchen möchten, können Sie schließlich die ausführliche Erklärung dazu im Handbuch lesen.
Beachten Sie jedoch, dass alles, was oben beschrieben wurde, darauf abzielt, das zu sein, was Sie benötigen, um mit der Einrichtung Ihrer eigenen PHPUnit-XML-Konfigurationsdatei zu beginnen.




