Schreiben hochwertiger Tests
Leider erhalten Tests in vielen Organisationen immer noch nicht die Aufmerksamkeit, die sie verdienen würden. Manchmal fühlt es sich so an, als hätten Entwickler ein schlechtes Gewissen, wenn sie keine Tests schreiben, und gleichzeitig wird der Testcode oft nicht ordnungsgemäß überprüft. Stattdessen wird in einer Rezension oft nur geprüft, ob es Tests gibt, was schade ist, denn nur Tests zu haben ist nicht gut genug. Eigentlich sollten sie mindestens die gleiche Qualität wie der gesamte andere Code in einem Projekt haben, wenn nicht sogar von höherer Qualität. Andernfalls könnten Tests Sie tatsächlich behindern, da Tests viel zu oft fehlschlagen, schwer zu verstehen sind oder viel zu lange in der Ausführung dauern. Einige dieser Punkte habe ich bereits in meinem Blogbeitrag über die Verwendung von In-Memory-Implementierungen anstelle von Repository-Mocks besprochen. Jetzt möchte ich einige andere, allgemeinere Dinge besprechen, auf die ich beim Schreiben von Tests achte.
Minimalismus ist der Schlüssel
Stack Overflow fordert Sie auf, den Fragen minimale, reproduzierbare Beispiele hinzuzufügen, und meiner Meinung nach ist dies aus genau den gleichen Gründen auch ein sehr guter Rat für das Schreiben von Tests. Besonders wenn man einen Test Monate nach dem Schreiben liest, ist es viel einfacher, vollständig zu verstehen, was passiert, wenn weniger Dinge passieren. Schreiben Sie also nur den Code, der für den Test unbedingt erforderlich ist, und widerstehen Sie der Versuchung, weitere Dinge hinzuzufügen, nur weil es einfach ist. Aber der Testcode muss natürlich trotzdem vollständig sein, d.h. ein Test sollte so viele Zeilen wie nötig, aber so wenig wie möglich enthalten.
Entscheiden Sie sich für eine Codeabdeckung von 100 %
Das mag eine unpopuläre Meinung sein, aber ich denke, dass es absolut sinnvoll ist, eine 100-prozentige Codeabdeckung anzustreben, auch wenn viele dies offenbar für eine schlechte Praxis halten.
Manchmal geben sich Teams mit einem niedrigeren Wert zufrieden, z.B. eine Codeabdeckung von 90 %. Allerdings macht das für mich wenig Sinn. Erstens sind alle diese Zahlen etwas willkürlich und schwer mit Daten zu belegen. Außerdem muss beim Schreiben von neuem Code nicht alles getestet werden, um diesen Schwellenwert zu erreichen. Und wenn es jemandem gelingt, die Abdeckung zu erhöhen, könnte die nächste Person damit durchkommen, überhaupt keine Tests zu schreiben und trotzdem eine Codeabdeckung von über 90 % beizubehalten, was zu einem falschen Vertrauensgefühl führt.
Eine der Ausreden, die ich oft höre, ist, dass es keinen Sinn macht, Tests für einfache Funktionen wie Getter und Setter zu schreiben. Und vielleicht überraschenderweise stimme ich dem voll und ganz zu. Aber hier ist der Haken: Wenn keiner der Tests tatsächlich diese Getter und Setter verwendet, besteht wahrscheinlich keine Notwendigkeit, sie zu haben. Anstatt sich also darüber zu beschweren, wie schwierig es ist, eine 100-prozentige Testabdeckung zu erreichen, Es wäre höchstwahrscheinlich besser, keinen Code zu schreiben, der überhaupt nicht benötigt wird. Dadurch wird auch der Wartungsaufwand vermieden, den jede Codezeile mit sich bringt.
Es gibt jedoch einen kleinen Haken: Manchmal macht Code seltsame Dinge, die dazu führen können, dass Code-Coverage-Tools einige Zeilen als nicht abgedeckt markieren, obwohl sie während des Testlaufs ausgeführt wurden. Ich bin nicht oft auf solche Situationen gestoßen, aber wenn es keine Möglichkeit gibt, dies zum Laufen zu bringen, schließe ich sie von der Codeabdeckung aus. Z.B. PHPUnit ermöglicht dies mithilfe der Annotation codeCoverageIgnore:
<?php class SomeClass { /** * @codeCoverageIgnore */ public function doSomethingNotDetectedAsCovered() { } }
Auf diese Weise wird diese Funktion nicht in die Codeabdeckungsanalyse einbezogen, was bedeutet, dass es immer noch möglich ist, eine Codeabdeckung von 100 % zu erreichen, und ich überprüfe diesen Wert auch weiterhin. Die Alternative besteht darin, sich mit einem niedrigeren Wert als 100 % zufrieden zu geben, aber dann gibt es die gleichen Probleme wie oben: Anderer Code wird möglicherweise auch nicht von Tests abgedeckt und wird möglicherweise übersehen.
Davon abgesehen gibt eine 100-prozentige Codeabdeckung sicherlich keine Garantie dafür, dass Ihr Code keine Fehler aufweist. Wenn Ihr Anwendungscode jedoch nicht abgedeckte Zeilen enthält, geben Sie Ihren Tests nicht einmal eine Änderung, um potenzielle Fehler in dieser Zeile zu erkennen.
Schreiben Sie gute Aussagen
Der Grund, warum Tests geschrieben werden, besteht darin, dass wir ein bestimmtes Verhalten des Codes sicherstellen möchten. Daher sind Behauptungen ein sehr wesentlicher Bestandteil des Testens.
Natürlich ist die wichtigste Überlegung beim Schreiben von Behauptungen, dass das Verhalten des Codes korrekt getestet wird. Aber eine sehr knappe Sekunde ist, wie sich die Behauptung verhält, wenn der Code fehlschlägt. Wenn eine Behauptung aus irgendeinem Grund fehlschlägt, sollte das Problem für den Entwickler so offensichtlich wie möglich sein. Eine Situation, in der dies offensichtlich ist, ist die Situation, an der derzeit in diesem Symfony-Pull-Request gearbeitet wird. Symfony verfügt über eine AssertResponseStatusCodeSame-Methode, die es ermöglicht, den Statuscode einer Antwort in einem Funktionstest zu überprüfen:
<?php declare(strict_types=1); class LoginControllerTest extends WebTestCase { public function testFormAttributes(): void { $client = static::createClient(); $client->request('GET', '/login'); $this->assertResponseStatusCodeSame(200); $this->assertSelectorCount(1, 'input[name="email"][required]'); } }
Das Problem bei diesem Test ist die Ausgabe, die er generiert, falls der Statuscode nicht 200 ist. Da Tests normalerweise in einer Entwicklungsumgebung ausgeführt werden, gibt Symfony eine Fehlerseite zurück, wenn auf diese URL zugegriffen wird, und die Methode „assertResponseStatusCodeSame“ gibt die aus gesamte Antwort für den Fall, dass die Behauptung fehlschlägt. Diese Ausgabe ist unglaublich lang, da sie nicht nur HTML, sondern auch CSS und JavaScript zurückgibt und mein Scrollback-Puffer buchstäblich zu klein ist, als dass ich die gesamte Nachricht lesen könnte.
Das ist absolut das schlechteste Beispiel, das mir bisher begegnet ist, aber es kann auch ärgerlich sein, wenn im Code die falschen Behauptungen verwendet werden. Schauen wir uns die Ausgabe der obigen Assertion „assetSelectorCount“ an, die mit der folgenden Meldung fehlschlägt, wenn der angegebene Selektor nicht genau ein Element liefert:
Failed asserting that the Crawler selector "input[name="email"][required]" was expected to be found 1 time(s) but was found 0 time(s).
Es gibt eine ziemlich gute Vorstellung von dem auftretenden Problem. Die Behauptung könnte jedoch auch anders geschrieben werden (tun Sie dies nicht zu Hause!):
<?php class SomeClass { /** * @codeCoverageIgnore */ public function doSomethingNotDetectedAsCovered() { } }
Jemand könnte argumentieren, dass dies genau das Gleiche bewirkt und es daher egal ist, welche Variante verwendet wird. Dies könnte nicht weiter von der Wahrheit entfernt sein, da die folgende Meldung angezeigt wird, wenn für eine E-Mail kein einziges erforderliches Eingabefeld vorhanden ist:
<?php declare(strict_types=1); class LoginControllerTest extends WebTestCase { public function testFormAttributes(): void { $client = static::createClient(); $client->request('GET', '/login'); $this->assertResponseStatusCodeSame(200); $this->assertSelectorCount(1, 'input[name="email"][required]'); } }
Das hilft überhaupt nicht, und wer an der Behebung des Problems arbeitet, muss zunächst einmal herausfinden, wo das Problem eigentlich liegt. Dies zeigt, dass immer eine passende Behauptung verwendet werden sollte, und PHPUnit verfügt über viele Behauptungen, die für alle Arten von Anwendungsfällen geeignet sind. Manchmal ist es sogar sinnvoll, eine benutzerdefinierte Behauptung zu erstellen.
Eine relativ neue Behauptung, die meiner Meinung nach in den letzten Jahren immer beliebter wurde, ist das Testen von Schnappschüssen. Besonders wenn man mit der Arbeit an einem Frontend-Projekt beginnt, scheint es sehr hilfreich zu sein. Ich habe es in der Vergangenheit oft mit React verwendet. Das Wesentliche ist, dass Ihre Tests etwa so aussehen:
Failed asserting that the Crawler selector "input[name="email"][required]" was expected to be found 1 time(s) but was found 0 time(s).
Die Magie geschieht in der toMatchSnapshot-Methode. Im allerersten Durchlauf schreibt es den Inhalt der Baumvariablen in eine separate Datei. Bei nachfolgenden Durchläufen vergleicht es den neuen Wert des Baumwerts mit dem, was es zuvor in seiner separaten Datei gespeichert hat. Wenn sich etwas ändert, schlägt der Test fehl und es wird ein Unterschied angezeigt, mit der Option, den Snapshot erneut zu aktualisieren, was bedeutet, dass Sie Ihre Tests im Handumdrehen reparieren können.
Das hört sich zwar wirklich gut an, bringt aber auch einige Nachteile mit sich. Erstens sind Snapshots ziemlich anfällig, da die Tests immer dann fehlschlagen, wenn sich das gerenderte Markup der Komponente ändert. Zweitens wird die Absicht des Tests verborgen, da er nicht erklärt, was der Autor eigentlich testen wollte.
Was mir jedoch wirklich gut gefallen hat, war, dass ich jedes Mal, wenn ich eine Komponente änderte, an alle anderen Komponenten erinnert wurde, die diese Komponente verwendeten, da alle diese Snapshots beim nächsten Durchlauf fehlschlugen. Aus diesem Grund gefiel es mir, mindestens einen Snapshot-Test pro Komponente durchzuführen.
Abschluss
Zusammenfassend denke ich, dass es ein paar Dinge gibt, mit denen Sie sofort beginnen können, um die Qualität Ihrer Tests zu verbessern:
- Beschränken Sie den Code in einem Test auf das unbedingt erforderliche Minimum
- Streben Sie eine Codeabdeckung von 100 % an und schließen Sie Code ordnungsgemäß aus dem Codeabdeckungsmechanismus aus, wenn er nicht getestet werden kann
- Verwenden Sie die richtigen Behauptungen, um bessere Fehlermeldungen zu erhalten, wenn Ihre Tests fehlschlagen
Meiner Meinung nach wird das Befolgen dieser wenigen Regeln bereits einen großen Unterschied machen und dazu beitragen, dass Sie lange Freude an der Arbeit in der Codebasis haben!
Das obige ist der detaillierte Inhalt vonSchreiben hochwertiger Tests. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Alipay PHP ...

JWT ist ein offener Standard, der auf JSON basiert und zur sicheren Übertragung von Informationen zwischen Parteien verwendet wird, hauptsächlich für die Identitätsauthentifizierung und den Informationsaustausch. 1. JWT besteht aus drei Teilen: Header, Nutzlast und Signatur. 2. Das Arbeitsprinzip von JWT enthält drei Schritte: Generierung von JWT, Überprüfung von JWT und Parsingnayload. 3. Bei Verwendung von JWT zur Authentifizierung in PHP kann JWT generiert und überprüft werden, und die Funktionen und Berechtigungsinformationen der Benutzer können in die erweiterte Verwendung aufgenommen werden. 4. Häufige Fehler sind Signaturüberprüfungsfehler, Token -Ablauf und übergroße Nutzlast. Zu Debugging -Fähigkeiten gehört die Verwendung von Debugging -Tools und Protokollierung. 5. Leistungsoptimierung und Best Practices umfassen die Verwendung geeigneter Signaturalgorithmen, das Einstellen von Gültigkeitsperioden angemessen.

Die Hijacking der Sitzung kann in den folgenden Schritten erreicht werden: 1. Erhalten Sie die Sitzungs -ID, 2. Verwenden Sie die Sitzungs -ID, 3. Halten Sie die Sitzung aktiv. Zu den Methoden zur Verhinderung der Sitzung der Sitzung in PHP gehören: 1. Verwenden Sie die Funktion Session_regenerate_id (), um die Sitzungs -ID zu regenerieren. 2. Store -Sitzungsdaten über die Datenbank, 3. Stellen Sie sicher, dass alle Sitzungsdaten über HTTPS übertragen werden.

Die Anwendung des soliden Prinzips in der PHP -Entwicklung umfasst: 1. Prinzip der Einzelverantwortung (SRP): Jede Klasse ist nur für eine Funktion verantwortlich. 2. Open and Close Principle (OCP): Änderungen werden eher durch Erweiterung als durch Modifikation erreicht. 3.. Lischs Substitutionsprinzip (LSP): Unterklassen können Basisklassen ersetzen, ohne die Programmgenauigkeit zu beeinträchtigen. 4. Schnittstellen-Isolationsprinzip (ISP): Verwenden Sie feinkörnige Schnittstellen, um Abhängigkeiten und nicht verwendete Methoden zu vermeiden. 5. Abhängigkeitsinversionsprinzip (DIP): Hoch- und niedrige Module beruhen auf der Abstraktion und werden durch Abhängigkeitsinjektion implementiert.

Wie debugge ich den CLI -Modus in PhpStorm? Bei der Entwicklung mit PHPSTORM müssen wir manchmal den PHP im CLI -Modus (COMS -Zeilenschnittstellen) debuggen ...

Die Aufzählungsfunktion in Php8.1 verbessert die Klarheit und Type des Codes, indem benannte Konstanten definiert werden. 1) Aufzählungen können Ganzzahlen, Zeichenfolgen oder Objekte sein, die die Lesbarkeit der Code und die Type der Type verbessern. 2) Die Aufzählung basiert auf der Klasse und unterstützt objektorientierte Merkmale wie Traversal und Reflexion. 3) Die Aufzählung kann zum Vergleich und zur Zuordnung verwendet werden, um die Sicherheit der Typ zu gewährleisten. 4) Aufzählung unterstützt das Hinzufügen von Methoden zur Implementierung einer komplexen Logik. 5) Strenge Typ Überprüfung und Fehlerbehandlung können häufig auftretende Fehler vermeiden. 6) Die Aufzählung verringert den magischen Wert und verbessert die Wartbarkeit, achten Sie jedoch auf die Leistungsoptimierung.

So setzen Sie die Berechtigungen von Unixsocket automatisch nach dem Neustart des Systems. Jedes Mal, wenn das System neu startet, müssen wir den folgenden Befehl ausführen, um die Berechtigungen von Unixsocket: sudo ...

Statische Bindung (statisch: :) implementiert die späte statische Bindung (LSB) in PHP, sodass das Aufrufen von Klassen in statischen Kontexten anstatt Klassen zu definieren. 1) Der Analyseprozess wird zur Laufzeit durchgeführt.
