Anfängerleitfaden für Unit-Tests: Was ist Unit-Test?
German (Deutsch) translation by Władysław Łucyszyn (you can also view the original English article)
Abhängig von Ihrem Hintergrund haben Sie möglicherweise von Unit-Tests, testgetriebener Entwicklung, verhaltensgetriebener Entwicklung oder einer anderen Art von Testmethode gehört oder auch nicht. Oft werden diese Methoden im Kontext größerer Softwaresysteme oder -anwendungen und weniger im Kontext von WordPress-basierten Projekten angewendet (obwohl es immer besser wird!).
Ehrlich gesagt ist die Entwicklergemeinde in Bezug auf automatisierte Softwaretests ein wenig gespalten - Sie haben einige Leute, die denken, Sie sollten Tests für 100% Ihres gesamten Codes durchführen, einige glauben, dass 80% ausreichend sind, einige 50% und einige sind zufrieden damit 20% oder so. Was auch immer der Fall sein mag, in diesem Artikel geht es weder darum, einen Fall für die Teststufe zu argumentieren, die Sie in Ihrem Projekt haben sollten, noch um eine Position zu allgemeinen Softwaretests.
Stattdessen schauen wir uns an, was erforderlich ist, um Unit-Tests für Ihre WordPress-Entwicklungsprojekte durchzuführen. Wir werden uns dieser Serie aus der Perspektive eines absoluten Anfängers nähern, damit wir die Vorteile von Unit-Tests verstehen und unsere Umgebung so konfigurieren können, dass sie Unit-Test-Bibliotheken unterstützt, damit wir dies in unserer zukünftigen Arbeit tun können. Schließlich wird all dies durch Erstellen und Testen eines einfachen, testbaren Plugins von Grund auf erreicht.
Was ist Unit Testing?
Bevor wir mit dem Einrichten unserer Umgebung und dem Schreiben von Code beginnen, definieren wir genau, was Unit-Tests sind, warum es sich lohnt und wie Sie damit beginnen, sie in unsere Projekte zu integrieren.
Auf hoher Ebene bezieht sich Unit-Test auf die Praxis, bestimmte Funktionen und Bereiche - oder Einheiten - unseres Codes zu testen. Dies gibt uns die Möglichkeit zu überprüfen, ob unsere Funktionen wie erwartet funktionieren. Das heißt, dass wir für jede Funktion und mit einer Reihe von Eingaben bestimmen können, ob die Funktion die richtigen Werte zurückgibt und Fehler im Verlauf der Ausführung ordnungsgemäß behandelt, falls ungültige Eingaben bereitgestellt werden.
Letztendlich hilft uns dies, Fehler in unseren Algorithmen und/oder unserer Logik zu identifizieren, um die Qualität des Codes zu verbessern, aus dem eine bestimmte Funktion besteht. Wenn Sie mehr und mehr Tests schreiben, erstellen Sie eine Reihe von Tests, die Sie jederzeit während der Entwicklung ausführen können, um die Qualität Ihrer Arbeit kontinuierlich zu überprüfen.
Ein zweiter Vorteil bei der Annäherung an die Entwicklung aus Sicht der Komponententests besteht darin, dass Sie wahrscheinlich Code schreiben, der einfach zu testen ist. Da Unit-Tests erfordern, dass Ihr Code leicht testbar ist, bedeutet dies, dass Ihr Code diese bestimmte Art der Auswertung unterstützen muss. Daher ist es wahrscheinlicher, dass Sie eine größere Anzahl kleinerer, fokussierterer Funktionen haben, die eine einzelne Operation für einen Datensatz bereitstellen, als große Funktionen, die eine Reihe verschiedener Operationen ausführen.
Ein dritter Vorteil beim Schreiben solider Komponententests und gut getesteten Codes besteht darin, dass Sie verhindern können, dass zukünftige Änderungen die Funktionalität beeinträchtigen. Da Sie Ihren Code testen, während Sie Ihre Funktionalität einführen, werden Sie mit der Entwicklung einer Reihe von Testfällen beginnen, die jedes Mal ausgeführt werden können, wenn Sie an Ihrer Logik arbeiten. Wenn ein Fehler auftritt, wissen Sie, dass Sie etwas zu beheben haben.
Dies geht natürlich zu Lasten des Zeitaufwands für das Schreiben einer Reihe von Tests zu Beginn der Entwicklung. Wenn das Projekt jedoch wächst, können Sie einfach die von Ihnen entwickelten Tests ausführen, um sicherzustellen, dass vorhandene Funktionen nicht beschädigt werden, wenn neue Funktionen verfügbar sind eingeführt.
Planen Sie unser Plugin
Eine der besten Möglichkeiten, um mit Unit-Tests zu beginnen, besteht darin, dies im Rahmen einer praktischen Anwendung zu tun. In dieser zweiteiligen Serie werden wir ein einfaches Plugin erstellen und Tests schreiben, um alle Funktionen abzudecken.
Planen wir zunächst das Projekt: Wir werden ein kleines Plugin schreiben, das oben in einem einzelnen Beitrag eine einfache Nachricht hinzufügt, die den Benutzer basierend darauf begrüßt, wie er einen bestimmten Blog-Beitrag gefunden hat. Die Idee ist der von Welcome Reader sehr ähnlich, enthält jedoch nicht annähernd so viele Funktionen. Wir erstellen lediglich eine Demo, um die Vor- und Nachteile des Testens kennenzulernen.
Wie auch immer, so funktioniert das Plugin:
- Wenn der Nutzer von Google zur Website navigiert, erhalten Sie eine eindeutige Nachricht
- Wenn der Benutzer von Twitter zur Website navigiert, erhalten Sie eine eindeutige Nachricht
- Andernfalls wird nichts angezeigt
Einfach genug, oder? Dies bietet auch eine Grundlage, auf der Sie benutzerdefinierte Nachrichten für andere Dienste hinzufügen und unsere Unit-Test-Funktionen weiter ausbauen können, falls Sie dies wünschen.
Umwelt vorbereiten
Um unseren Code zu testen, benötigen wir eine Bibliothek eines Drittanbieters, die wir in unser Projekt aufnehmen und die von uns geschriebenen Tests tatsächlich ausführen. In dieser Serie werden wir PHPUnit verwenden. Eine Kopie davon können Sie hier herunterladen.
Als nächstes müssen wir unsere Entwicklungsumgebung vorbereiten, unser Plugin stubben und die notwendigen Bibliotheken zum Testen unseres Codes einbinden. In diesem Artikel wird davon ausgegangen, dass bereits eine funktionierende WordPress-Installation ausgeführt wird.
Bereiten wir also zuerst das Plugin-Verzeichnis vor:
- Erstellen Sie in /wp-content/plugins ein Verzeichnis namens Hello-Reader
- Erstellen Sie im Hello-Reader-Verzeichnis eine Datei mit dem Namen plugin.php und ein Verzeichnis mit dem Namen tests
- Wir werden das Plugin löschen, um sicherzustellen, dass WordPress unser Projekt richtig sieht
- Wir werden die Unit-Test-Bibliotheken importieren, damit wir mit dem Schreiben unserer Tests beginnen können
Hier ist das Grundgerüst für das Plugin, das wir erstellen werden:
1 |
/*
|
2 |
Plugin Name: Hello Reader
|
3 |
Plugin URI: http://github.com/tommcfarlin/Hello-Reader
|
4 |
Description: A simple plugin used to help demonstrate unit testing in the context of WordPress.
|
5 |
Version: 1.0
|
6 |
Author: Tom McFarlin
|
7 |
Author URI: http://tom.mcfarl.in
|
8 |
Author Email: tom@tommcfarlin.com
|
9 |
License:
|
10 |
|
11 |
Copyright 2012 Tom McFarlin (tom@tommcfarlin.com)
|
12 |
|
13 |
This program is free software; you can redistribute it and/or modify
|
14 |
it under the terms of the GNU General Public License, version 2, as
|
15 |
published by the Free Software Foundation.
|
16 |
|
17 |
This program is distributed in the hope that it will be useful,
|
18 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
19 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
20 |
GNU General Public License for more details.
|
21 |
|
22 |
You should have received a copy of the GNU General Public License
|
23 |
along with this program; if not, write to the Free Software
|
24 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
25 |
|
26 |
*/
|
27 |
// Only create an instance of the plugin if it doesn't already exists in GLOBALS
|
28 |
if( ! array_key_exists( 'hello-reader', $GLOBALS ) ) { |
29 |
|
30 |
class Hello_Reader { |
31 |
|
32 |
function __construct() { |
33 |
|
34 |
} // end constructor |
35 |
|
36 |
} // end class |
37 |
|
38 |
// Store a reference to the plugin in GLOBALS so that our unit tests can access it
|
39 |
$GLOBALS['hello-reader'] = new Hello_Reader(); |
40 |
|
41 |
} // end if |
Zu diesem Zeitpunkt sollten Sie in der Lage sein, zu den "Plugins" in Ihrem WordPress-Dashboard zu navigieren und einen Eintrag für "Hello Reader" anzuzeigen. Offensichtlich macht dieses Plugin noch nichts - wir werden uns im nächsten Artikel darauf konzentrieren (und warum wir das $GLOBALS-Array nutzen).
Lassen Sie uns abschließend das Test-Framework einrichten, damit wir unsere Tests schreiben können. Zuerst müssen wir PHPUnit installieren und dann müssen wir die WordPress-Tests installieren.
Hinweis: Im nächsten Abschnitt müssen Sie einige Arbeiten mit dem Terminal ausführen und wahrscheinlich einige Befehle eingeben, um symbolische Links zu erstellen. Ich habe versucht, dies so einfach und unkompliziert wie möglich zu gestalten, aber jedes Betriebssystem und jede Konfiguration wird anders sein. Bitte folgen Sie genau und ich lade Sie ein, Ihre Anweisungen für Ihre Betriebssysteme in den Kommentaren zu teilen.
PHPUnit installieren
PHPUnit ist ein Unit-Test-Framework-Paket speziell für PHP. Davon hängen die WordPress-Tests und das Framework ab, das wir zum Schreiben unserer WordPress-Tests verwenden werden. Leider hängt die Installation von Ihrer Plattform ab. Ich verwende derzeit Mac OS X Lion mit MAMP Pro und PHP 5.3.6. Wenn Sie eine andere Plattform verwenden, lesen Sie unbedingt die Dokumentation und/oder teilen Sie Ihre Schritte in den Kommentaren mit.
Öffnen Sie zuerst ein Terminal und aktualisieren Sie pear (dies ist die Funktion, mit der wir PHPUnit installieren):
$ cd /Applications/MAMP/bin/php/php5.3.6/bin$ sudo ./pear upgrade pear
Weisen Sie Pear als Nächstes an, Repositorys zu verwenden, die wir im Terminal angeben:
$ sudo /Applications/MAMP/bin/php/php5.3.6/bin/pear config-set auto_discover 1
Installieren Sie danach Pear, indem Sie den folgenden Befehl eingeben:
$ sudo /Applications/MAMP/bin/php/php5.3.6/bin/pear install pear.phpunit.de/PHPUnit
Dadurch wird PHPUnit im Kontext Ihrer MAMP-Installation installiert. Führen Sie zum Testen den folgenden Befehl in Ihrer Terminalsitzung aus:
$ /Applications/MAMP/bin/php/php5.3.6/bin/phpunit --version
Danach sollte die folgende Meldung angezeigt werden:
PHPUnit 3.6.11 by Sebastian Bergmann.
Hinweis: Wenn Sie einen Terminalfehler erhalten, der "unserialize()" erwähnt, besteht eine Diskrepanz zwischen der Birnenkonfiguration und Ihrer Birnenversion. Geben Sie zum Auflösen den folgenden Befehl ein (dies benennt die Datei einfach um, falls Sie sie später wiederherstellen möchten):
$ /Applications/MAMP/bin/php/php5.3.6/conf/pear.conf /Applications/MAMP/bin/php/php5.3.6/conf/pear.conf.old
Installieren der WordPress-Tests
Nachdem wir PHPUnit installiert haben und funktionieren, ist es Zeit, das WordPress Testing Framework einzurichten. Sie können das Paket von GitHub herunterladen. Wenn Sie das Repository bequem klonen möchten, können Sie dies jederzeit tun. Andernfalls laden Sie einfach ein Archiv des Projekts herunter und extrahieren Sie es in das test-Verzeichnis, das wir zuvor in diesem Artikel erstellt haben.
Bevor wir die Tests tatsächlich ausführen können, müssen wir eine Konfigurationsdatei zum Ausführen von WordPress-Tests erstellen. Dies ist genau wie das Bearbeiten der Datei wp-config.php mit einer neuen WordPress-Installation, aber wir tun dies stattdessen für eine Testdatenbank. Unten habe ich meine Konfigurationsdatei eingefügt und Kommentare hinzugefügt. Ich werde dies sicher auch in das GitHub-Repository dieses Artikels übernehmen.
1 |
/* Path to the WordPress codebase in relation to the location of these tests. Since they are included with our plugin, we refer to a few directories above. */
|
2 |
define( 'ABSPATH', '../../../../../' ); |
3 |
|
4 |
/* The name of the database for running the tests. Make sure this is a database just for testing as it's created and trashed during tests. */
|
5 |
define( 'DB_NAME', 'throwaway' ); |
6 |
|
7 |
/* The usual credentials for a local database. */
|
8 |
define( 'DB_USER', 'root' ); |
9 |
define( 'DB_PASSWORD', '' ); |
10 |
define( 'DB_HOST', 'localhost' ); |
11 |
define( 'DB_CHARSET', 'utf8' ); |
12 |
define( 'DB_COLLATE', '' ); |
13 |
|
14 |
define( 'WPLANG', '' ); |
15 |
define( 'WP_DEBUG', true ); |
16 |
define( 'WP_DEBUG_DISPLAY', true ); |
17 |
|
18 |
define( 'WP_TESTS_DOMAIN', 'localhost' ); |
19 |
define( 'WP_TESTS_EMAIL', 'tom@tommcfarlin.com' ); |
20 |
define( 'WP_TESTS_TITLE', 'Test Blog' ); |
21 |
|
22 |
/* Not worried about testing networks or subdomains, so setting to false. */
|
23 |
define( 'WP_TESTS_NETWORK_TITLE', 'Test Network' ); |
24 |
define( 'WP_TESTS_SUBDOMAIN_INSTALL', false ); |
25 |
$base = '/'; |
26 |
|
27 |
/* Cron tries to make an HTTP request to the blog, which always fails, because tests are run in CLI mode only */
|
28 |
define( 'DISABLE_WP_CRON', true ); |
29 |
|
30 |
/* Also not interested in testing multisite for this project, so setting to false. */
|
31 |
define( 'WP_ALLOW_MULTISITE', false ); |
32 |
if ( WP_ALLOW_MULTISITE ) { |
33 |
define( 'WP_TESTS_BLOGS', 'first,second,third,fourth' ); |
34 |
}
|
35 |
if ( WP_ALLOW_MULTISITE && !defined('WP_INSTALLING') ) { |
36 |
define( 'SUBDOMAIN_INSTALL', WP_TESTS_SUBDOMAIN_INSTALL ); |
37 |
define( 'MULTISITE', true ); |
38 |
define( 'DOMAIN_CURRENT_SITE', WP_TESTS_DOMAIN ); |
39 |
define( 'PATH_CURRENT_SITE', '/' ); |
40 |
define( 'SITE_ID_CURRENT_SITE', 1); |
41 |
define( 'BLOG_ID_CURRENT_SITE', 1); |
42 |
}
|
43 |
|
44 |
$table_prefix = 'wp_'; |
Um zu überprüfen, ob Sie die Tests ordnungsgemäß installiert haben, können Sie den folgenden Befehl in Ihrem Terminal ausführen:
$ /Applications/MAMP/bin/php/php5.3.6/bin/phpunit all
Wenn Sie einen Fehler erhalten, liegt dies daran, dass die WordPress-Tests versuchen, einen Socket für die MySQL-Datenbank zu verwenden, anstatt den von MAMP verwendeten. Um dies zu beheben, müssen wir eine symbolische Verknüpfung vom MAMP-Socket zu dem Speicherort auf der Festplatte erstellen, den die Komponententests verwenden. Geben Sie in Ihrer Terminalsitzung die folgenden Befehle aus:
1 |
$ sudo mkdir /var/mysql |
2 |
$ sudo ln -s /Applications/MAMP/tmp/mysql/mysql.sock /var/mysql/mysql.sock |
3 |
$ sudo ln -s /Applications/MAMP/tmp/mysql/mysql.sock /var/mysql/mysql.sock |
Versuchen Sie nun erneut, die Tests auszuführen, und Sie sollten etwa den folgenden Screenshot sehen.


Auch hier kann Ihr Kilometerstand je nach Plattform variieren, die Sie verwenden. Teilen Sie Ihre Erfahrungen in den Kommentaren mit oder verpflichten Sie sich sogar zur README-Datei auf GitHub, damit andere einen Bezugspunkt haben können.
An diesem Punkt können wir mit dem Erstellen unseres Plugins und dem Schreiben unserer Unit-Tests beginnen. Der obige Code wurde zu GitHub hinzugefügt und ich werde ihn ausbauen, während wir den nächsten Artikel in der Reihe durcharbeiten. Stellen Sie in der Zwischenzeit sicher, dass Sie Ihre Umgebung eingerichtet haben und bereit sind, mit der Entwicklung zu beginnen. Im nächsten Artikel werden wir tatsächlich damit beginnen, Tests zu schreiben, unser Plugin zu erstellen und zu sehen, wie das gesamte Projekt von Anfang bis Ende zusammenkommt.



