Meiner Meinung nach sollten Unit-Tests in einer vom Produktionscode getrennten Baugruppe platziert werden. Hier sind nur einige Nachteile der Platzierung von Komponententests in derselben Baugruppe oder denselben Baugruppen wie der Produktionscode:
- Unit-Tests werden mit Produktionscode geliefert. Das einzige, was mit dem Produktcode geliefert wird, ist der Produktionscode.
- Baugruppen werden durch Unit-Tests unnötig aufgebläht.
- Unit-Tests können Build-Prozesse wie automatisierte oder kontinuierliche Builds beeinflussen.
Ich kenne keine Profis. Ein zusätzliches Projekt (oder 10) zu haben, ist kein Nachteil.
Bearbeiten: Weitere Informationen zu Build und Versand
Ich würde außerdem empfehlen, dass bei jedem automatisierten Bauprozess Produktions- und Komponententests an verschiedenen Orten durchgeführt werden. Im Idealfall wird der Unit-Test-Erstellungsprozess nur ausgeführt, wenn der Produktionscode erstellt wird, und die Produktdateien werden in das Unit-Test-Verzeichnis kopiert. Wenn Sie dies auf diese Weise tun, werden die tatsächlichen Bits für den Versand usw. getrennt. Außerdem ist es ziemlich trivial, an dieser Stelle für alle Tests in einem bestimmten Verzeichnis automatisierte Komponententests durchzuführen.
Zusammenfassend ist hier die allgemeine Idee für ein tägliches Erstellen und Testen und Versenden von Bits und anderen Dateien:
- Der Produktions-Build wird ausgeführt und die Produktionsdateien werden in einem bestimmten "Produktions" -Verzeichnis abgelegt.
- Erstellen Sie nur Produktionsprojekte.
- Kopieren Sie kompilierte Bits und andere Dateien in ein "Produktions" -Verzeichnis.
- Das Kopieren von Bits und anderen Dateien in ein Release Candidate-Verzeichnis, auch bekannt als Christmas Release Directory, wäre "Release20081225".
- Wenn der Produktionsbuild erfolgreich ist, wird der Unit-Test-Build ausgeführt.
- Kopieren Sie den Produktionscode in das Verzeichnis "tests".
- Erstellen Sie Komponententests im Verzeichnis "tests".
- Führen Sie Unit-Tests durch.
- Senden Sie Build-Benachrichtigungen und Unit-Testergebnisse an Entwickler.
- Wenn ein Release-Kandidat (wie Release20081225) akzeptiert wird, versenden Sie diese Bits.
#if
. Dieses benutzerdefinierte Symbol kann mithilfe von Compiler-Befehlszeilenparametern in Ihren CI-Software-Skripten umgeschaltet werden. Siehe msdn.microsoft.com/en-us/library/4y6tbswk.aspx .Separates Projekt, aber in der gleichen Lösung. (Ich habe an Produkten mit separaten Lösungen für Test- und Produktionscode gearbeitet - es ist schrecklich. Sie wechseln immer zwischen den beiden.)
Die Gründe für getrennte Projekte sind wie von anderen angegeben. Beachten Sie, dass bei Verwendung datengesteuerter Tests möglicherweise eine erhebliche Aufblähung auftritt, wenn Sie die Tests in die Produktionsbaugruppe aufnehmen.
Wenn Sie Zugriff auf die internen Elemente des Produktionscodes benötigen, verwenden Sie InternalsVisibleTo .
quelle
[assembly:InternalsVisibleTo("UnitTestProjectName")]
Ihrer Projektdatei hinzufügenAssemblyInfo.cs
.Ich verstehe den häufigen Einwand gegen die Bereitstellung von Tests mit Produktionscode nicht. Ich leitete ein Team mit einer kleinen Mikrokappe (wuchs von 14 auf 130 Personen). Wir hatten ungefähr ein halbes Dutzend Java-Apps und fanden es EXTREM wertvoll, Tests vor Ort bereitzustellen, um sie auf einem auszuführen bestimmtenMaschine, die ungewöhnliches Verhalten zeigte. Zufällige Probleme treten vor Ort auf, und es war von unschätzbarem Wert, einige tausend Komponententests ohne Kosten auf das Rätsel zu werfen, und es wurden häufig Probleme innerhalb von Minuten diagnostiziert ... einschließlich Installationsproblemen, flockigen RAM-Problemen, maschinenspezifischen Problemen, flockigen Netzwerkproblemen, usw. usw. Ich denke, es ist unglaublich wertvoll, Tests vor Ort durchzuführen. Außerdem tauchen zu zufälligen Zeiten zufällige Probleme auf, und es ist schön, dass die Unit-Tests dort bereits darauf warten, sofort ausgeführt zu werden. Festplattenspeicher ist billig. Genau wie wir versuchen, Daten und Funktionen zusammenzuhalten (OO-Design), denke ich, dass es von grundlegender Bedeutung ist, Code und Tests zusammenzuhalten (Funktion + Tests, die die Funktionen validieren).
Ich möchte meine Tests in dasselbe Projekt in C # /. NET / Visual Studio 2008 einfügen, aber ich habe dies noch nicht genug untersucht, um es zu erreichen.
Ein großer Vorteil von Foo.cs im selben Projekt wie FooTest.cs ist, dass Entwickler ständig daran erinnert werden, wenn einer Klasse ein Geschwistertest fehlt! Dies fördert bessere testgetriebene Codierungspraktiken ... Löcher sind offensichtlicher.
quelle
Fügen Sie Unit-Tests in dasselbe Projekt wie den Code ein, um eine bessere Kapselung zu erzielen.
Sie können interne Methoden problemlos testen. Dies bedeutet, dass Sie keine Methoden veröffentlichen, die intern sein sollten.
Es ist auch sehr schön, wenn die Unit-Tests in der Nähe des Codes liegen, den Sie schreiben. Wenn Sie eine Methode schreiben, können Sie die entsprechenden Komponententests leicht finden, da sie sich im selben Projekt befinden. Wenn Sie eine Assembly erstellen, die unitTests enthält, erhalten Sie bei Fehlern im unitTest einen Kompilierungsfehler. Sie müssen also Ihre Unittest auf dem neuesten Stand halten, nur um sie zu erstellen. Wenn Sie in einem separaten Projekt unittest haben, können einige Entwickler vergessen, das unittest-Projekt zu erstellen, und die fehlerhaften Tests für eine Weile verpassen.
Sie können die Komponententests mithilfe von Kompilierungs-Tags (IF #Debug) aus dem Produktionscode entfernen.
Automatische Integrationstests (erstellt in NUnit) sollten sich in einem separaten Projekt befinden, da sie keinem einzelnen Projekt angehören.
quelle
Release
Build ausführen können und nur wenige "Heisenbugs" durchfallen können.InternalsVisibleTo
können Sie interne Methoden aus einem separaten Testprojekt testenDebug
,Approval
undRelease
; und kompilieren Sie die Genehmigung mit allen Release-Optimierungen. Außerdem sind Unit-Tests in der Regel nicht in der Lage, Heisenbugs überhaupt zu erkennen (meiner Erfahrung nach). Sie benötigen in der Regel spezielle Integrationsregressionstests für diese - und Sie können diese möglicherweise nebeneinander platzieren.Nachdem ich einige Zeit in TypeScript-Projekten verbracht hatte, in denen Tests häufig neben dem zu testenden Code in einer Datei abgelegt werden, zog ich diesen Ansatz vor, anstatt sie getrennt zu halten:
Als ich kürzlich ein neues .NET Core-Projekt startete, wollte ich sehen, ob es möglich ist, diese Struktur in einem C # -Projekt nachzuahmen, ohne die Tests oder Testassemblys mit der endgültigen Version zu versenden.
Das Einfügen der folgenden Zeilen in die Projektdatei scheint bisher gut zu funktionieren:
Das obige stellt sicher, dass in der
Release
Konfiguration alle Dateien benannt sind*.Tests.cs
von der Kompilierung ausgeschlossen werden und dass die erforderlichen Verweise auf Unit-Test-Pakete entfernt werden.Wenn Sie weiterhin in der Lage sein möchten, die Klassen in ihrer Release-Konfiguration zu testen, können Sie einfach eine neue Konfiguration erstellen, die von
Release
so etwas wie abgeleitet abgeleitet istReleaseContainingTests
.Update: Nachdem ich diese Technik eine Weile verwendet habe, habe ich auch festgestellt, dass es hilfreich ist, Ihre Symbole in VS Code anzupassen, damit die Tests (und andere Dinge) im Explorer-Bereich etwas besser zur Geltung kommen:
Verwenden Sie dazu die Erweiterung Material Icon Theme und fügen Sie Ihren VS Code-Einstellungen JSON Folgendes hinzu:
quelle
Meine Unit-Tests finden immer in einem separaten Projekt statt. Tatsächlich gibt es für jedes Projekt, das ich in meiner Lösung habe, ein separates Testprojekt, das damit einhergeht. Testcode ist kein Anwendungscode und sollte nicht damit vermischt werden. Ein Vorteil, wenn Sie sie in separaten Projekten aufbewahren - zumindest mit TestDriven.Net -, besteht darin, dass ich mit der rechten Maustaste auf ein Testprojekt klicken und alle Tests in diesem Projekt ausführen kann, wobei ich mit einem Klick eine gesamte Bibliothek mit Anwendungscode teste.
quelle
Wenn das NUnit- Framework verwendet wird, gibt es einen zusätzlichen Grund, die Tests in dasselbe Projekt zu integrieren. Betrachten Sie das folgende Beispiel des Produktionscodes, der mit Komponententests gemischt ist:
Die Unit-Tests dienen hier als Dokumentation und Spezifikation für den zu testenden Code. Ich weiß nicht, wie ich diesen Effekt der Selbstdokumentation erreichen kann, wenn sich die Tests in einem separaten Projekt befinden. Der Benutzer der Funktion müsste nach den Tests suchen, um diese Testfälle zu sehen, was unwahrscheinlich ist.
Update : Ich weiß, dass eine solche Verwendung von
TestCase
Attributen nicht von den Entwicklern von NUnit beabsichtigt wurde, aber warum nicht?quelle
Ich schwanke zwischen demselben Projekt und verschiedenen Projekten.
Wenn Sie eine Bibliothek freigeben, ist es ein Problem, den Testcode mit dem Produktionscode freizugeben. Andernfalls ist dies normalerweise nicht der Fall (obwohl es vor dem Versuch eine starke psychologische Barriere gibt).
Wenn ich Tests in dasselbe Projekt einbaue, fällt es mir leichter, zwischen Tests und dem von ihnen getesteten Code zu wechseln und sie leichter umzugestalten / zu verschieben.
quelle
Ich habe sie in separate Projekte gestellt. Der Name der Assembly entspricht in der Regel dem der Namespaces. Wenn es also ein Projekt mit dem Namen Company.Product.Feature.sln gibt, hat es eine Ausgabe (Baugruppenname) von Company.Product.Feature.dll. Das Testprojekt ist Company.Product.Feature.Tests.sln und ergibt Company.Product.Feature.Tests.dll.
Sie sollten sie am besten in einer einzigen Lösung aufbewahren und die Ausgabe über den Konfigurationsmanager steuern. Wir haben eine benannte Konfiguration für jeden der Hauptzweige (Entwicklung, Integration, Produktion) anstelle der Verwendung des Standard-Debugs und der Standardversion. Sobald Sie Ihre Konfigurationen eingerichtet haben, können Sie sie ein- oder ausschließen, indem Sie im Konfigurationsmanager auf das Kontrollkästchen "Erstellen" klicken. (Um den Configuration Manager zu erhalten, klicken Sie mit der rechten Maustaste auf die Lösung und gehen Sie zu Configuration Manager.) Beachten Sie, dass das CM in Visual Studio manchmal fehlerhaft ist. Einige Male musste ich in die Projekt- und / oder Lösungsdateien gehen, um die von ihr erstellten Ziele zu bereinigen.
Wenn Sie Team Build verwenden (und ich bin sicher, dass andere .NET-Build-Tools identisch sind), können Sie den Build außerdem einer benannten Konfiguration zuordnen. Wenn Sie beispielsweise Ihre Komponententests nicht für Ihren Build "Produktion" erstellen, kann das Build-Projekt diese Einstellung ebenfalls kennen und nicht erstellen, da sie als solche markiert wurden.
Außerdem haben wir XCopy-Drops von der Build-Maschine ausgeführt. Das Skript würde einfach das Kopieren von Inhalten mit dem Namen * .Tests.Dll unterlassen. Es war einfach, hat aber funktioniert.
quelle
Ich würde sagen, halte sie getrennt.
Zusätzlich zu den anderen genannten Gründen verzerrt das gemeinsame Vorhandensein von Code und Tests die Testabdeckungszahlen. Wenn Sie über die Abdeckung von Komponententests berichten - Die gemeldete Abdeckung ist höher, da die Tests beim Ausführen von Komponententests abgedeckt werden. Wenn Sie über die Abdeckung von Integrationstests berichten, ist die gemeldete Abdeckung geringer, da bei Integrationstests keine Komponententests ausgeführt werden.
quelle
Ich bin wirklich inspiriert vom Unit-Testing-Framework der Flood NN-Bibliothek von Robert Lopez. Es verwendet ein anderes Projekt für jede einzelne getestete Klasse und verfügt über eine Lösung, die alle diese Projekte enthält, sowie ein Hauptprojekt, das alle Tests kompiliert und ausführt.
Das Schöne ist auch das Layout des Projekts. Die Quelldateien befinden sich in einem Ordner, aber der Ordner für das VS-Projekt befindet sich unten. Auf diese Weise können Sie verschiedene Unterordner für verschiedene Compiler erstellen. Alle VS-Projekte werden mit dem Code ausgeliefert, sodass jeder sehr einfach einige oder alle Komponententests ausführen kann.
quelle
Ich weiß, dass dies eine sehr alte Frage ist, aber ich möchte meine Erfahrung dort hinzufügen. Ich habe kürzlich die Gewohnheit, Unit-Tests durchzuführen, von separaten Projekten auf dasselbe geändert.
Warum?
Erstens neige ich sehr dazu, die Struktur des Hauptprojektordners mit dem Testprojekt gleich zu halten. Wenn ich also eine Datei unter
Providers > DataProvider > SqlDataProvider.cs
habe, erstelle ich in meinen Unit-Test-Projekten die gleiche Struktur wieProviders > DataProvider > SqlDataProvider.Tests.cs
Aber nachdem das Projekt immer größer wird und Sie Dateien von einem Ordner in einen anderen oder von einem Projekt in einen anderen verschieben, wird es sehr mühsam, diese mit Unit-Test-Projekten zu synchronisieren.
Zweitens ist es nicht immer sehr einfach, von der zu testenden Klasse zur Unit-Test-Klasse zu navigieren. Dies ist für JavaScript und Python noch schwieriger.
Vor kurzem habe ich angefangen zu üben, dass ich mit jeder einzelnen Datei, die ich erstellt habe (zum Beispiel
SqlDataProvider.cs
), eine andere Datei mit dem Suffix Test erstellt, wie zSqlDataProvider.Tests.cs
Am Anfang scheint es, als würde es Dateien und Bibliotheksreferenzen aufblähen, aber auf lange Sicht werden Sie das Moving-File-Syndrom auf den ersten Blick beseitigen und außerdem sicherstellen, dass jede einzelne Datei, die getestet werden soll, eine Paardatei hat mit
.Tests
Suffix. Sie können einfach in die Testdatei springen (weil sie nebeneinander liegt), anstatt durch ein separates Projekt zu schauen.Sie können sogar Geschäftsregeln schreiben, um das Projekt zu durchsuchen, eine Klasse zu identifizieren, die keine .Tests-Datei enthält, und diese dem Eigentümer zu melden. Außerdem können Sie Ihrem Testläufer leicht mitteilen, welche
.Tests
Zielklassen er haben soll.Insbesondere für Js und Python müssen Sie Ihre Referenzen nicht aus einem anderen Pfad importieren. Sie können einfach denselben Pfad der zu testenden Zieldatei verwenden.
Ich verwende diese Praxis für eine Weile und denke, dass es ein sehr vernünftiger Kompromiss zwischen Projektgröße und Wartbarkeit und Lernkurve für Neulinge im Projekt ist.
quelle
Wie andere geantwortet haben - setzen Sie Tests in separate Projekte
Eine Sache, die nicht erwähnt wurde, ist die Tatsache, dass Sie nur
nunit3-console.exe
gegen.dll
Dateien laufen können.Wenn Sie Ihre Tests über TeamCity ausführen möchten, ist dies ein Problem.
Angenommen, Sie haben ein Konsolenanwendungsprojekt. Beim Kompilieren wird eine ausführbare Datei
.exe
an denbin
Ordner zurückgegeben.Von dort aus können
nunit3-console.exe
Sie keine in dieser Konsolenanwendung definierten Tests ausführen.Mit anderen Worten, eine Konsolenanwendung gibt eine
exe
Datei zurück und eine Klassenbibliothek gibtdll
Dateien zurück.Ich habe heute nur ein bisschen davon bekommen und es ist scheiße :(
quelle
Ich habe vor kurzem in Docker bereitgestellt. Ich sehe keinen Wert darin, ein separates Projekt zu haben, wenn die Docker-Datei das Verzeichnis / src problemlos kopieren und das Verzeichnis / test verlassen kann. Aber ich bin neu bei dotnet und vermisse möglicherweise etwas.
quelle
Separate Projekte, obwohl ich mit mir selbst diskutiere, ob sie den gleichen SVN teilen sollten. Im Moment gebe ich ihnen separate SVN-Repositories, eines mit dem Namen
"MyProject" - für das Projekt selbst
und einer rief an
"MyProjectTests" - für die mit MyProject verknüpften Tests.
Dies ist ziemlich sauber und hat den Vorteil, dass Commits für das Projekt und Commits für die Tests ziemlich getrennt sind. Dies bedeutet auch, dass Sie den SVN des Projekts bei Bedarf übergeben können, ohne Ihre Tests freigeben zu müssen. Dies bedeutet auch, dass Sie Zweigstellen- / Amtsleitungs- / Tag-Verzeichnisse für Ihre Tests und für Ihr Projekt haben können.
Aber ich bin zunehmend geneigt, für jedes Projekt Folgendes in einem einzigen SVN-Repository zu haben.
Es würde mich interessieren, was andere über diese Lösung denken.
quelle