Die sprechende Walnuss fragt:
Was sind einige gute Möglichkeiten, um die skeptischen Entwickler im Team vom Wert von Unit Testing zu überzeugen?
Jeder hier wird aus heiterem Himmel viele Gründe anhäufen, warum Unit-Tests gut sind. Ich finde jedoch, dass der beste Weg, jemanden von etwas zu überzeugen, oft darin besteht, auf seine Argumentation zu hören und sie Punkt für Punkt anzusprechen. Wenn Sie zuhören und ihnen helfen, ihre Bedenken zu verbalisieren, können Sie jedes einzelne ansprechen und sie möglicherweise in Ihre Sichtweise umwandeln (oder sie zumindest ohne ein Bein stehen lassen, auf dem sie stehen können). Wer weiß? Vielleicht überzeugen sie Sie, warum Unit-Tests für Ihre Situation nicht geeignet sind. Nicht wahrscheinlich, aber möglich. Wenn Sie ihre Argumente gegen Unit-Tests veröffentlichen, können wir Ihnen möglicherweise dabei helfen, die Gegenargumente zu identifizieren.
Es ist wichtig, beide Seiten des Arguments anzuhören und zu verstehen. Wenn Sie versuchen, Unit-Tests ohne Rücksicht auf die Bedenken der Menschen zu eifrig durchzuführen, kommt es zu einem Religionskrieg (und wahrscheinlich zu wirklich wertlosen Unit-Tests). Wenn Sie es langsam anwenden und es zunächst dort anwenden, wo Sie den größten Nutzen bei geringsten Kosten sehen, können Sie möglicherweise den Wert von Komponententests demonstrieren und haben eine bessere Chance, Menschen zu überzeugen. Mir ist klar, dass dies nicht so einfach ist, wie es sich anhört - es erfordert normalerweise einige Zeit und sorgfältige Metriken, um ein überzeugendes Argument zu erstellen.
Unit-Tests sind wie jedes andere Tool und sollten so angewendet werden, dass die Vorteile (das Auffinden von Fehlern) die Kosten (den Aufwand beim Schreiben) überwiegen. Verwenden Sie sie nicht, wenn / wo sie keinen Sinn ergeben, und denken Sie daran, dass sie nur ein Teil Ihres Arsenals an Werkzeugen sind (z. B. Inspektionen, Behauptungen, Codeanalysatoren, formale Methoden usw.). Was ich meinen Entwicklern sage, ist Folgendes:
Sie können das Schreiben eines Tests für eine Methode überspringen, wenn sie ein gutes Argument dafür haben, warum dies nicht erforderlich ist (z. B. zu einfach, um es wert zu sein, oder zu schwierig, um es wert zu sein) und wie die Methode anderweitig überprüft wird (z. B. Inspektion, Behauptungen , formale Methoden, interaktive / Integrationstests). Sie müssen berücksichtigen, dass einige Überprüfungen wie Inspektionen und formale Nachweise zu einem bestimmten Zeitpunkt durchgeführt werden und dann jedes Mal wiederholt werden müssen, wenn sich der Produktionscode ändert, während Komponententests und Zusicherungen als Regressionstests verwendet werden können (einmal geschrieben und danach wiederholt ausgeführt) ). Manchmal stimme ich ihnen zu, aber öfter werde ich darüber diskutieren, ob eine Methode wirklich zu einfach oder zu schwer zu testen ist.
Wenn ein Entwickler argumentiert, dass eine Methode zu einfach zu scheitern scheint, lohnt es sich dann nicht, sich die 60 Sekunden zu nehmen, um einen einfachen 5-Zeilen-Komponententest dafür zu erstellen? Diese 5 Codezeilen werden jede Nacht (Sie erstellen jede Nacht Builds, oder?) Für das nächste Jahr oder länger ausgeführt und sind die Mühe wert, wenn auch nur einmal ein Problem erkannt wird, dessen Identifizierung möglicherweise 15 Minuten oder länger gedauert hat und debuggen. Außerdem erhöht das Schreiben der einfachen Komponententests die Anzahl der Komponententests, wodurch der Entwickler gut aussieht.
Wenn ein Entwickler hingegen argumentiert, dass eine Methode zu schwierig zu testen scheint (was den erheblichen Aufwand nicht wert ist), ist dies möglicherweise ein guter Hinweis darauf, dass die Methode aufgeteilt oder überarbeitet werden muss, um die einfachen Teile zu testen. In der Regel sind dies Methoden, die auf ungewöhnlichen Ressourcen wie Singletons, der aktuellen Zeit oder externen Ressourcen wie einer Datenbank-Ergebnismenge beruhen. Diese Methoden müssen normalerweise in eine Methode umgestaltet werden, die die Ressource abruft (z. B. ruft getTime () auf), und in eine Methode, die die Ressource als Argument verwendet (z. B. den Zeitstempel als Parameter verwendet). Ich lasse sie das Testen der Methode überspringen, mit der die Ressource abgerufen wird, und sie schreiben stattdessen einen Komponententest für die Methode, die die Ressource jetzt als Argument verwendet. In der Regel ist das Schreiben des Unit-Tests dadurch viel einfacher und es lohnt sich daher, ihn zu schreiben.
Der Entwickler muss eine "Linie in den Sand" ziehen, wie umfassend seine Unit-Tests sein sollten. Wenn wir später in der Entwicklung einen Fehler finden, sollten sie feststellen, ob umfassendere Komponententests das Problem erkannt hätten. Wenn dies der Fall ist und solche Fehler wiederholt auftreten, müssen sie die "Linie" verschieben, um in Zukunft umfassendere Komponententests zu schreiben (beginnend mit dem Hinzufügen oder Erweitern des Komponententests für den aktuellen Fehler). Sie müssen das richtige Gleichgewicht finden.
Es ist wichtig , die Unit - Tests zu realisieren sind kein Allheilmittel , und es ist so etwas wie zu viel Unit - Tests. Wenn wir an meinem Arbeitsplatz Lehren ziehen, höre ich unweigerlich "wir müssen mehr Komponententests schreiben". Das Management nickt zustimmend, weil ihnen "Unit Tests" == "gut" in den Kopf geschlagen wurde.
Wir müssen jedoch die Auswirkungen von "mehr Unit-Tests" verstehen. Ein Entwickler kann nur ~ N Codezeilen pro Woche schreiben, und Sie müssen herausfinden, wie viel Prozent dieses Codes Unit-Test-Code gegenüber Produktionscode sein sollten. Ein lockerer Arbeitsplatz verfügt möglicherweise über 10% des Codes als Komponententests und 90% des Codes als Produktionscode, was zu einem Produkt mit vielen (wenn auch sehr fehlerhaften) Funktionen führt (denken Sie an MS Word). Auf der anderen Seite wird ein strenger Laden mit 90% Unit-Tests und 10% Produktionscode ein absolut solides Produkt mit sehr wenigen Merkmalen haben (denken Sie an "vi"). Sie werden vielleicht nie Berichte über den Absturz des letzteren Produkts hören, aber das hat wahrscheinlich genauso viel damit zu tun, dass sich das Produkt nicht sehr gut verkauft, wie es mit der Qualität des Codes zu tun hat.
Schlimmer noch, vielleicht ist die einzige Gewissheit in der Softwareentwicklung, dass "Veränderungen unvermeidlich sind". Angenommen, der strenge Shop (90% Komponententests / 10% Produktionscode) erstellt ein Produkt mit genau 2 Merkmalen (unter der Annahme, dass 5% des Produktionscodes == 1 Merkmal sind). Wenn der Kunde vorbeikommt und eine der Funktionen ändert, werden durch diese Änderung 50% des Codes (45% der Komponententests und 5% des Produktionscodes) verworfen. Der laxe Laden (10% Unit-Tests / 90% Produktionscode) bietet ein Produkt mit 18 Funktionen, von denen keine sehr gut funktioniert. Ihr Kunde überarbeitet die Anforderungen für 4 seiner Funktionen vollständig. Obwohl die Änderung viermal so groß ist, wird nur die Hälfte der Codebasis verworfen (~ 25% = ~ 4,4% Komponententests + 20% des Produktionscodes).
Mein Punkt ist, dass Sie kommunizieren müssen, dass Sie das Gleichgewicht zwischen zu wenig und zu viel Unit-Test verstehen - im Wesentlichen, dass Sie beide Seiten des Problems durchdacht haben. Wenn Sie Ihre Kollegen und / oder Ihr Management davon überzeugen können, gewinnen Sie an Glaubwürdigkeit und haben möglicherweise eine bessere Chance, sie für sich zu gewinnen.