Versandtestcode. Warum würdest du nicht?

17

Ich möchte Testcode zusammen mit einem Produkt versenden. Stellen Sie insbesondere eine Option bereit, mit der jeder, der eine Kopie unseres Programms besitzt, auf die Schaltfläche "Selbsttest" klicken oder den Selbsttest in der Befehlszeile bestehen und die gesamte Unit-Suite | durchlaufen kann Integrationstests.

Ich möchte dies hauptsächlich tun, um Fehlerbehebungsprobleme zu beheben, die im Feld festgestellt wurden. Wenn also ein Fehlerbericht von einem Endbenutzer eingeht, besteht die Möglichkeit, dass er von "und auch, dass diese drei Tests auf meinem Computer fehlgeschlagen sind" unterstützt wird. Ich möchte, dass manuelle Tester das Gerät betreiben können Integrationstests auch.

Der Test des Teams geht jedoch davon aus, dass der Testcode kein Seriencode ist und daher nicht versandt werden darf. Ich verstehe dieses Argument nicht wirklich, da die meisten Open Source-Projekte eine Testsuite enthalten. In geschlossener Software scheint dies ungewöhnlich zu sein.

Ich möchte Beweise oder Anekdoten für jede Seite des Arguments unterstützen. Ich habe nach besten Kräften geraten, welche Stack-Exchange-Site am besten geeignet ist, aber lassen Sie mich bitte wissen, wenn dies nicht der Fall ist.

Jon Chesterfield
quelle
8
Warum würde ein Komponententest in einem Closed-Source-Programm (oder einem Open-Source-Programm, das nicht geändert wurde) jemals fehlschlagen? Wenn für Ihr Produkt eine große Anzahl von Setups erforderlich ist und Setup-Probleme häufig Fehler verursachen, ist es möglicherweise sinnvoll, eine App zur "Überprüfung meiner Konfiguration" zu liefern, mit der beispielsweise die Datenbankverbindung überprüft und Verbindungen zu anderen externen Diensten überprüft werden können Ihr Code hängt von usw. ab. Es wäre jedoch nicht sinnvoll, wenn ein Komponententest jemals fehlschlagen würde, da Sie bereits überprüft haben, ob der Code funktioniert.
Justin Cave
15
Warum sollte ein Unit-Test im Feld scheitern? Aus dem Häuschen: Korruptes Programm. Dodgy Hardware. Rennbedingungen haben wir vor Ort nicht gesehen. Verknüpft mit einer anderen dynamischen Bibliothek. Konflikte mit Antivirus oder Betriebssystem. Wird mit einer überraschenden Version verwandter Software aufgrund eines unvollständigen Updates verwendet. Interaktion mit anderen Prozessen verhält sich nicht wie erwartet. Es gibt eine Menge Gründe, warum Bugs auf dem Feld auftauchen, und viele von ihnen könnten bei einem Unit-Test (für eine bestimmte Definition von Unit) gefunden werden
Jon Chesterfield,
7
@ JonChesterfield: Das Erstellen einer Selbsttestfunktion in Ihrem Programm ist wahrscheinlich eine gute Sache. Und wenn diese Selbsttestfunktion Code aus Ihren Komponententests teilweise wiederverwenden kann, warum nicht? Aber eine solche Funktion sowie die wiederverwendbaren Teile sollten unter dem Gesichtspunkt "Es ist Produktionscode" entwickelt werden.
Doc Brown
2
@ JonChesterfield Es fällt mir schwer, mir vorzustellen, dass ein Komponententest auf den meisten dieser Ursachen fehlschlägt. Integrationstests sind jedoch eine andere Sache - ich kann sie als nützlich erachten, wenn sie ohne zu viel zusätzliches Material durchgeführt werden können.
Loren Pechtel

Antworten:

19

Manchmal enthält Testcode Codeausschnitte von externen und internen Drittanbietern. Dies geschieht, wenn Benutzer Fehler einreichen. Ihre Tests (z. B. Regressionstests) enthalten dann den von ihnen zur Reproduktion bereitgestellten Code. Oft ist die Lizenzierung solcher Code-Schnipsel zur Reproduktion von Fehlern unklar. Sie sollten sich also des geistigen Eigentums bewusst sein. Sie möchten keinen Testcode versenden, der versehentlich Geschäftsgeheimnisse oder geistiges Eigentum einer anderen Abteilung Ihres Unternehmens oder Ihrer externen Partner preisgibt.

Außerdem wird Testcode selten an Produktionscode-Standards gebunden: Codeüberprüfungen werden nicht unbedingt durchgeführt. Codierungsstandards werden nicht durchgesetzt, usw. Dies ist bedauerlich, aber alltäglich und sollte das Testteam nicht unbedingt schlecht einschätzen, wenn es dieses Ziel zum Zeitpunkt der Entwicklung dieser Tests nicht hatte.

Auf der anderen Seite sind viele Tests einfach nur peinlich schlecht und testen nicht einmal, was manche für einen Test halten. Das ist ein anderes Thema ...

Aufgrund all dieser Faktoren möchten Sie Ihre Tests möglicherweise als solche klassifizieren, die als Open Source ausgeliefert werden können , und als solche, die dies einfach nicht können. (Möglicherweise möchten Sie einige benutzerdefinierte Tests schreiben, um sie zu versenden, und die anderen langsam in diesen Satz migrieren.)

Erik Eidt
quelle
Das Drittanbieterproblem ist ein wirklich guter Punkt. Das Gruppieren des Testcodes in "extern sichtbar" und "möglicherweise vertraulich" wäre fehleranfällig und mit einem erheblichen Aufwand verbunden. Das ist so ziemlich ein Deal Breaker, danke.
Jon Chesterfield
Ja, schwer zu machen. Ich würde denken, Sie hätten mehr Glück mit einer engagierten Anstrengung, Versandtests zu entwickeln.
Erik Eidt
@ErikEidt: Ich habe mir die Freiheit genommen, einen Vorschlag zum Entfernen von "als Open Source" zu machen, da dies wahrscheinlich nicht das Ziel des OP ist - ich denke, er möchte die Tests als Closed Source versenden.
Doc Brown
@ DocBrown, ich nehme Ihren Punkt. Wahrscheinlich eine Frage der Interpretation, da das OP irgendwo in der Post "Open Source" erwähnte. In jedem Fall verallgemeinert Ihre Bearbeitung den Punkt gut.
Erik Eidt
18

Versandtests? Ja. Versandeinheitstests? Nein.

Wie Sie in dem Kommentar sagen, wird das Problem, das beim Ausführen des Produkts auf einem Client-Computer auftreten kann, Probleme wie das Verknüpfen mit der falschen DLL beinhalten. Im Allgemeinen ist dies nichts, was ein Komponententest erkennen kann (was die DLL zweifellos verspottet hat) um den Code zu testen).

Jetzt wird eine Integrationstestsuite ausgeliefert, die die Benutzeroberfläche aufruft, die die Logik aufruft, die die DLL aufruft ... und die viel besser funktioniert. Integrationstests können andere Aspekte fehlgeschlagener Installationen aufzeigen, die bei Komponententests nicht angezeigt werden. (Mein aktuelles Produkt erfordert z. B. die Installation von K-Lite-Codecs, die wir aufgrund der Lizenzierung nicht bündeln dürfen. Bei Unit-Tests kann sich herausstellen, dass unser Code einwandfrei funktioniert, aber immer noch nicht zur Zufriedenheit des Kunden. Ebenso unsere Konfiguration der Codecs möglicherweise nicht richtig funktioniert haben, würden Unit-Tests dies auch nicht aufzeigen).

Versenden Sie stattdessen einige Ihrer Integrationstests, die genau das sind, was Sie für ein installiertes, integriertes Produkt wünschen.

gbjbaanb
quelle
2

Ich verstehe diese Besorgnis sehr gut in Bereichen, in denen Sie jeden einzelnen Zentimeter der Hardware abdecken, wie z. B. eine Multithread-AAA-Game-Engine der nächsten Generation, die jeden einzelnen CPU-Kern, SIMD-Intrinsics, GPU, GPGPU usw. verwendet und gleichzeitig eine plattformübergreifende Lösung bereitstellt Produkt.

In diesen Fällen ist der schlimmste Albtraum häufig der, in dem Ihre Tests (Einheit und Integration) für die ersten 5.000 getesteten Maschinen / Plattformen bestanden werden, aber für die 5.001 aufgrund eines Treiberfehlers für ein undurchsichtiges GPU-Modell fehlschlagen darüber zittere ich - das kann man unmöglich im voraus testen oder vorhersehen.

Insbesondere wenn Sie GPU-Shader schreiben, können Sie eine umgekehrte Lotterie spielen, bei der der halbe Code, den Sie schreiben, undefiniertes Verhalten hervorruft, da es nur wenige tragbare Standardgarantien gibt, die von allen beteiligten GPU-Modellen / Treibern durchgesetzt werden. Obwohl es heutzutage immer weniger so aussieht wie Minensuchboot zu spielen, sollte dies den Leuten eine Idee geben: http://theorangeduck.com/page/writing-portable-opengl . Dies in den späten 90ern und frühen 2000ern zu versuchen war wirklich schrecklich und es war Minensuchboot den ganzen Weg.

Für diese Art von Fällen benötigen Sie häufig Teams mit mehr als 10.000 Testern mit einem breiten Palette von Hardware und Betriebssystemen , um wirklich das Produkt erstarren und darüber vor einem stabilen Release sicher zu fühlen. Nicht alle Unternehmen können es sich leisten, eine so breite Testbasis zu haben, und nicht alle haben die Disziplin, es richtig zu machen (alle allgemein wahrnehmbaren Probleme sollten behoben werden, bevor so viele Tester in einer internen Pre-Alpha / Alpha-Phase oder anderswo sind Eine Flut redundanter Berichte kann Entwickler in Panik versetzen.

Was ich in diesem Fall empfehle, ist das, was andere vorgeschlagen haben. Konzentrieren Sie sich auf verteilte Integrationstests. Sie können es mit dem Installationsprogramm bündeln. Die Benutzer müssen eine grundlegende Diagnoseprüfung durchführen und dabei sorgfältig prüfen, ob die Installation fehlgeschlagen ist. Diese Prüfung kann an Sie als Entwickler weitergegeben werden.

Eine andere Sache (wenn Sie den Chef überzeugen können) ist, eine breite Palette von Hardware zur Verfügung zu haben, um eine zusammenhängende Integration durchzuführen. Je mehr Hardware / Betriebssystem-Kombinationen zur Auswahl stehen, desto besser. Sie möchten sogar eine Vielzahl von Misthardware, die die minimalen Hardwareanforderungen für Ihre CI-Server modelliert: Sie wissen es nie.

Aber noch etwas würde ich vorschlagen:

Protokollierung

Wenn Sie es mit etwas wie dem oben beschriebenen Szenario zu tun haben, können Sie oft nicht auf diese Dinge testen, die in der Regel am problematischsten sind (diese schlimmsten Fälle, die zum schlimmsten Zeitpunkt auftreten und nicht einmal im Szenario auftreten können) umfassendste Testsuite, da es sich um ein Problem handelt, das auf eine bestimmte Hardware / Betriebssystem-Kombination beschränkt ist).

Die meisten dieser Probleme, wie obskure Hardware-Inkompatibilitäten oder regelrechte Treiberfehler oder das Verknüpfen mit der falschen Dylib (ich habe mich dieser Sorge nie gestellt), bringen Sie jedoch nicht weit über das Starten der Software hinaus. Es wird normalerweise ziemlich bald abstürzen und brennen, grob gesagt.

Ich empfehle aus Gründen der Vernunft, das Unvermeidliche zu umarmen. Sie können unmöglich etwas gegen diese Dinge unternehmen, die Sie möglicherweise nicht umfassend testen können. Versuchen Sie nicht, den Hurrikan zu verhindern (unmöglich), sondern steigen Sie in diese Fenster.

In der Regel können wir das Problem so schnell wie möglich herausfinden, wo es so detailliert wie möglich auftritt (um die Liste der Verdächtigen einzugrenzen), und das Problem so schnell wie möglich beheben lassen, nachdem es gemeldet wurde.

In diesem Fall kann die Protokollierung ein Lebensretter sein. Für diese Art von Feldern können Sie diese technischen Spam-Protokolle erstellen, die niemand jemals durchlesen würde. Häufig ist nur die allerletzte Zeile des Protokolls relevant, die aufgezeichnet wurde, bevor der Benutzer aufgrund eines Treiberfehlers einem Absturz ausgesetzt war. Sie können z. B. einen externen Prozess oder Hook schreiben, der auf Abstürze überwacht und dann die letzte Zeile des Protokolls anzeigt, die Benutzer kopieren können und einfügen, zB zusätzlich zu einem Crash Dump.

Da dies häufig detaillierte Informationen erfordert und viele der anfälligsten Bereiche im Code für diese Hardware-, Plattform- und Treiberprobleme leistungskritisch sind, gibt es dieses unangenehme Problem, bei dem die Protokollierung mit einer solchen Häufigkeit erfolgen kann, dass sie tatsächlich langsamer wird Runter die Software.

Ein nützlicher Trick in diesem Fall ist, sich auf die Annahme zu verlassen, dass etwas, das einmal ausgeführt wird, beim zweiten, dritten Mal usw. erfolgreich ausgeführt wird. Dies ist nicht die fundierteste Annahme, aber es ist oft "gut genug" (und unendlich besser als nichts). . Auf diese Weise können Sie ein wenig externen Status verwenden, um zu verfolgen, wann etwas bereits protokolliert wurde, und nachfolgende Versuche zu überspringen, in denen der Code in einer Schleife wiederholt aufgerufen wird.

Wie auch immer, ich hoffe das hilft. Ich bin in der Vergangenheit auf diese Art von Versuchung gestoßen und habe eine gewisse Paranoia in Bezug auf die GPU-Codierung (GPGPU und Shader) als Ergebnis einiger Erfahrungen zwischen mir und meinem Team (manchmal nur, wenn andere Teammitglieder sich wirklich damit befassen) Verspätung und Nachveröffentlichung machten mir zu schaffen, wie ein ATI-Fehler bei einem bestimmten Radeon-Modell, der beim Rendern von Antialias-Linien zum Absturz führte. Dies wurde später gemeldet und als bekanntes Problem markiert, da nur eine Problemumgehungslösung zur Verfügung stand.

Das Protokollieren rettete uns die Nerven, sodass wir oft das Problem auf dieser 10.001. obskuren Prototypmaschine mit einer integrierten GPU sehen konnten, von der wir noch nie gehört hatten. Mit der letzten Codezeile konnten wir sofort feststellen, wo genau der Fehler aufgetreten war oder 3 Codezeilen als Verdächtiger, zB Wenn es sich um einen aufwändigen Shader handelt, sind wir eine Art SOL, da wir in einem GPU-Shader keine Protokollierung durchführen können, aber wir können die Protokollierung zumindest verwenden, um zu sehen, bei welchem Shader das Problem sofort aufgetreten ist die Untersuchung zu starten.

marstato
quelle
2
Logging-Code auswendig zu lernen ist clever. Momentan werden keine Protokolle erstellt - hauptsächlich aus Gründen der Leistung. Daher ist das Debuggen mit einem Core-Dump verbunden. Das Einbetten von Diagnosetests mit dem Installationsprogramm ist ebenfalls eine gute Idee. Vielen Dank für die ausführliche Antwort.
Jon Chesterfield