5 Stimmen

.NET Unit Testing - Best Practices zum Verstecken von Testnähten im Release-Code

Ich bin auf der Suche nach einigen Ratschlägen für Unit-Testing in einer Weise, die nicht verlassen "Test-Haken" in Ort in der Produktion Code.

Nehmen wir an, ich habe eine statische Klasse (VB.NET-Modul) namens MethodLogger, die eine Methode "void WriteEntry(string Message)" hat, die die aufrufende Methode und eine Nachricht in eine Protokolldatei auf der Festplatte schreiben soll. Das eigentliche Ziel von WriteEntry() kann auf eine Fake-Implementierung von IMethodLogger umgeleitet werden, um Unit-Tests durchzuführen, und für todos in anderen Fällen sollte es die eigentliche Implementierung von IMethodLogger aufrufen.

Hier ist ein grober Schnitt von dem, was ich bis jetzt ausgeheckt habe, und ich mag den Ansatz - aber in einigen schnellen Tests wirft er einige Fragen und Zweifel auf:

[InternalAttributesVisibleTo("MethodLogger.Tests")]
internal static class MethodLogger
{
    public void WriteEntry(string message)
    {
        LogWriter.WriteEntry(message);
    }

    private IMethodLogger LogWriter
    {
        get;
        set;
    }

#if DEBUG
    internal void SetLogWriter(IMethodLogger logger)
    {
        LogWriter = logger;
    }
#endif
}

Hier sind meine konkreten Fragen:

  • Diese eng Paare die Unit-Tests gegen die DEBUG-Build ausgeführt; wenn ich Unit-Tests ausführen, obwohl es scheint, dass es nicht speziell die Baugruppe unter Test in DEBUG neu erstellen--ist es möglich, dies zu tun?

    • Würde ich die Unit-Tests jemals gegen einen nicht-debuggen Build laufen lassen wollen? Von der Spitze von meinem Kopf sehe ich weniger Wert - aber würde es sein?
  • Wäre es für mich möglich, ein benutzerdefiniertes Pre-Compiler-Flag wie "TEST" anstelle von "DEBUG" zu verwenden? Wie würde ich Visual Studio anweisen, das Ziel immer neu zu erstellen? mit diese Flagge zum Testen, um sicherzustellen, dass meine Haken/Nähte verfügbar sind?

1voto

Randolpho Punkte 54011

Es handelt sich um eine interne Methode. Lassen Sie sie einfach so wie sie ist, ohne bedingte Kompilierung, und nur aufrufen aus Ihren Unit-Tests.

Es spricht nichts dagegen, den Haken drin zu lassen - vielleicht sollten Sie sogar überlegen, ob Sie die Methode öffentlich und erlaubt jedem Code, den Logging-Hook zu ändern.

Wenn ich mir Ihren Code noch einmal ansehe, dann haben Sie nicht einmal brauchen die SetLogWriter-Methode; verwenden Sie einfach einen privaten Accessor für Ihre statische Klasse, und Sie können sie in Ihren Unit-Tests selbst einstellen.

Ich kann verstehen, dass es in Ordnung ist, den Haken zu belassen, ihn zu entfernen ist nur eine Vorliebe, aber ich bin nicht damit einverstanden, ihn öffentlich zu machen - es fühlt sich zu sehr an, als würde man die Berechtigungen erhöhen, nur weil es ein wenig Ärger erspart. - Yoooder

Nun, ich habe mich eher zu den allgemeinen Grundsätzen der Codeorganisation geäußert. Es ist im Allgemeinen eine gute Idee, solche Haken für Ihren Code zu erstellen. In Ihrem Fall würden Sie nicht "die Berechtigungen erhöhen, um ein Problem zu beseitigen", sondern "ein robustes und flexibles Logging-Framework entwickeln".

1voto

Matt Briggs Punkte 39925

Dies scheint mir ein erstklassiger Kandidat für einen IoC-Container zu sein. Ich würde meinen Logger nicht statisch machen, und verschiedene Konfigurationen für Test, Entwicklung und Produktion einrichten.

1voto

cfeduke Punkte 22720

Ihr Build-Prozess muss einen Produktions-Build enthalten, gegen den Unit-Tests ausgeführt werden. Wenn dies nicht der Fall ist, können Sie nicht garantieren, dass sich nicht jemand bei den Pragmas vertan hat (z. B. Release vs. Debug).

Im Falle der Protokollierung verwende ich immer Log4Net . Während der Entwicklung und beim Testen werden die Protokollmeldungen auf die ausführlichste Stufe eingestellt. In der Produktion belasse ich sie in der Regel auf der Fehler- oder Info-Stufe, stelle sie aber für die Fehlersuche bei Bedarf auf ausführlicher ein.

IMO der beste Weg, um auszuführen, was Sie versuchen, mit SetLogWriter zu erreichen ist eigentlich eine Umkehrung der Kontrolle Container verwenden, wie StructureMap um zur Laufzeit auf der Grundlage verschiedener Konfigurationen Konkretes zuzuweisen. Während des Unit-Tests können Sie eine Bibliothek wie Moq um Konkretes herzustellen, das sich in einer erwarteten Weise verhält (eine SQL-Abfrage, die immer genau das gleiche Ergebnis liefert), obwohl Sie in Ihrem speziellen Fall genau das Gegenteil tun (gewünschte Protokollierung während der Unit-Tests vs. keine Protokollierung zur Produktionslaufzeit).

0voto

Adam Hughes Punkte 3604

W benutzerdefiniertes Pre-Compiler-Flag wie "TEST" anstelle von "DEBUG" zu verwenden? Wie würde ich Visual Studio anweisen, das Ziel immer das Ziel mit diesem Flag zum Testen neu zu erstellen um sicherzustellen, dass meine Hooks/Seams verfügbar sind? verfügbar sind?

Ja. Sie möchten ein Symbol für die bedingte Kompilierung hinzufügen. Sie können dies in den Projekteigenschaften auf der Registerkarte Build tun. Sie können eine andere Build-Konfiguration im Konfigurationsmanager erstellen und nur Ihr TEST-Symbol zur neuen Konfiguration hinzufügen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X