Testgesteuerte Entwicklung bedeutet , dass der Test vor dem Code geschrieben wird und einem bestimmten Zyklus folgt :
- Test schreiben
- Test prüfen (ausführen)
- Produktionscode schreiben
- Test prüfen (ausführen)
- Produktionscode bereinigen
- Test prüfen (ausführen)
Für mich ist dies nur möglich, wenn Sie mit Ihrer Entwicklungslösung sehr schnell zwischen Produktions- und Testcode wechseln und den Test für einen bestimmten Produktionscode-Teil extrem schnell ausführen können.
Obwohl es viele Unit Testing Frameworks für C ++ gibt (ich verwende Bost.Test atm.), Scheint es nicht wirklich eine anständige (für natives C ++ ) Visual Studio (Plugin) -Lösung zu geben, die das TDD erstellt Zyklus erträglich, unabhängig vom verwendeten Rahmen.
"Bearable" bedeutet, dass Sie mit einem Klick einen Test für eine bestimmte CPP-Datei ausführen können, ohne manuell ein separates Testprojekt usw. einrichten zu müssen. "Bearable" bedeutet auch, dass ein einfacher Test startet (Verknüpfung!) Und sehr schnell ausgeführt wird .
Welche Tools (Plugins) und Techniken gibt es also, die den TDD-Zyklus für die native C ++ - Entwicklung mit Visual Studio ermöglichen?
Hinweis: Ich bin mit kostenlosen oder "kommerziellen" Tools einverstanden.
Bitte : Keine Rahmenempfehlungen. (Es sei denn, das Framework verfügt über ein dediziertes Visual Studio-Plugin und Sie möchten das Plugin empfehlen.)
Hinweis zum Bearbeiten : Die bisherigen Antworten enthalten Links zum Integrieren eines Unit Testing-Frameworks in Visual Studio. Die Ressourcen beschreiben mehr oder weniger, wie das UT-Framework kompiliert und Ihre ersten Tests ausgeführt werden. Dies ist nicht , was diese Frage ist. Ich bin der Meinung, dass, um wirklich produktiv zu arbeiten, wenn die Unit-Tests in einem manuell gepflegten (!) Getrennten vcproj von Ihren Produktionsklassen durchgeführt werden, so viel Overhead entsteht, dass TDD "nicht möglich" ist. Soweit mir bekannt ist, fügen Sie einem Java- oder C # -Ding keine zusätzlichen "Projekte" hinzu, um Unit Tests und TDD zu aktivieren, und das aus gutem Grund. Das sollte mit C ++ mit den richtigen Tools möglich sein, aber es scheint (diese Frage ist ungefähr), dass es sehr wenig Tools für TDD / C ++ / VS gibt.
Beim Googeln habe ich ein Tool gefunden, VisualAssert , das in die richtige Richtung zu zielen scheint. Allerdings scheint es nicht weit verbreitet zu sein (im Vergleich zu CppUnit, Boost.Test usw.).
Bearbeiten: Ich möchte dem Kontext für diese Frage einen Kommentar hinzufügen. Ich denke, es ist eine gute Zusammenfassung, um (einen Teil) des Problems zu skizzieren: (Kommentar von Billy ONeal )
Visual Studio verwendet keine "Build-Skripte", die vom Benutzer angemessen bearbeitet werden können. Ein Projekt erzeugt eine Binärdatei. Darüber hinaus hat Java die Eigenschaft, dass Java niemals eine vollständige Binärdatei erstellt - die von Ihnen erstellte Binärdatei ist nur eine ZIP-Datei der Klassendateien. Daher ist es möglich, separat und dann JAR manuell zusammen zu kompilieren (z. B. mit 7z). C ++ und C # verknüpfen beide tatsächlich ihre Binärdateien, sodass Sie im Allgemeinen kein solches Skript schreiben können. Das Beste, was Sie bekommen können, ist, alles separat zu kompilieren und dann zwei Verknüpfungen vorzunehmen (eine für die Produktion, eine für das Testen).
quelle
As far as I am aware, you do not add extra "projects" to a Java or C# thing to enable Unit Tests and TDD,
<- Ich denke nicht, dass das richtig ist. Normalerweise haben Sie auch mehrere Projekte in C #. Sie möchten Ihren Testcode nicht in Ihrer Produktionsbinärdatei versenden.7z
). C ++ und C # verknüpfen beide tatsächlich ihre Binärdateien, sodass Sie im Allgemeinen kein solches Skript schreiben können. Das Beste, was Sie bekommen können, ist, alles separat zu kompilieren und dann zwei Verknüpfungen vorzunehmen (eine für die Produktion, eine für das Testen).Antworten:
Ich habe eine 5-teilige Blogserie über TDD mit C ++ und Visual Studio geschrieben: Teil 1 , Teil 2 , Teil 3 , Teil 4 , Teil 5 .
Ich bin mir nicht sicher, warum Sie sagen, dass Sie in C # keine zusätzlichen Projekte für TDD erstellen, da ich das immer mit NUnit gemacht habe und es typisch für das ist, was andere Leute auch mit NUnit machen. Der Grund ist einfach: Halten Sie den Testcode immer vom Produktionscode getrennt. Für C ++ mit Visual Studio bedeutet dies separate Projekte, genau wie für C # und NUnit. Soweit ich von der Java-Welt weiß, ist dies auch dort üblich.
Offensichtlich hat jeder unterschiedliche Vorstellungen davon, was für TDD "erträglich" ist. Ich übe die Methode, die ich in meinem Blogbeitrag skizziere, seit mehreren Jahren und finde sie sehr erträglich. C ++ ist eine kompilierte Sprache, und das Kompilieren kann langsam sein, wenn das zu testende System stark gekoppelt ist. Es gibt einfach keinen Ausweg, ohne auf ein lockerer gekoppeltes Design umzusteigen.
Meine "One-Click-Aktion" ist "Build Solution". Wenn dadurch zu viel erstellt wird, können Sie während der Arbeit immer irrelevante Projekte entladen. Build Solution erstellt dann nur die minimale Teilmenge der Projekte, die aufgrund Ihrer Änderungen aktualisiert werden müssen.
Zugegeben, aufgrund der Kompilierungszeit von C ++ dauert dies in jedem Zyklus des TDD-Prozesses etwas länger als bei NUnit und C #, aber das Vertrauen, das ich aus meinem gut getesteten C ++ - Code erhalte, ist es wert. Sonst werde ich viel mehr Zeit im Debugger verbringen. Ich würde darauf achten, dass Sie bei der Verwendung von gmock nicht sparsam vorgehen, da dies die Testkompilierungszeit erheblich verlängern kann. Ich bin bisher meistens mit leichten "gefälschten" Objekten davongekommen und brauche selten die volle Funktionalität von Mocks. Die Mocking-Frameworks für C ++ sind stark vorlagenbasiert und dies kann die Kompilierungszeit erheblich verlängern. Sie sollten daher nur dort reserviert werden, wo Sie wirklich ein Mock benötigen und eine Fälschung einfach nicht ausreicht.
Ich habe überlegt, einen Boost.Test-Assistenten für Unit-Test-Projekte zu erstellen, um einen Teil der Kesselplatten-Natur beim Erstellen des Testprojekts für Produktionscode zu automatisieren, aber nachdem Sie es ein paar Mal durchgeführt haben, ist es wirklich nicht so schwer, dies manuell zu tun.
Bei Lösungen mit vielen (150?) Projekten gibt es auch Möglichkeiten, damit umzugehen. Eine naheliegende besteht darin, Gruppen verwandter Projekte zu finden, sie zu bündeln und zu konsumieren / als Einheit zu veröffentlichen. Wenn Sie wirklich alle 150 Projekte neu erstellen / berühren müssen, um kleine Änderungen vorzunehmen, die Sie während eines TDD-Zyklus vornehmen, ist Ihr Code ohnehin so stark gekoppelt, dass Unit-Tests wahrscheinlich keinen großen Unterschied machen.
Wenn ich mir den NetBeans-IDE-Link ansehe, finde ich die Augenweide , etwas zu haben, das die Testausgabe analysiert und eine kleine Testzeile in einem Fenster mit einem grünen oder roten Symbol daneben zeigt, von dem ich dachte, ich würde es vermissen, von NUnit gekommen zu sein. aber nicht wirklich vermisst. Ich fand es nützlicher, dass der Build einfach fehlschlug, und dann konnte ich in das Fehlerfenster doppelklicken, um den Cursor an der Stelle der fehlgeschlagenen Zusicherung zu platzieren.
quelle
Ich verwende kein Visual-C ++, aber ich führe TDD mit C ++ durch, wobei googletest und googlemock mit QtCreator als IDE verwendet werden. Vor Jahren hatte ich ein ähnliches Setup mit Visual-C ++, aber mit einem anderen Unit-Test-Framework.
Was ich als nützlich empfunden habe, ist, das Projekt in einige Unterprojekte aufzuteilen.
Mit diesem Setup kümmert sich meine IDE um das Hinzufügen von Dateien zu verschiedenen Projekten. Wenn Abhängigkeiten korrekt ermittelt werden, kann ich alle meine Komponententests mit einer teilweisen Neuerstellung ausführen. Ich habe es derzeit sogar so eingerichtet, dass alle meine Tests sofort nach dem Erstellen ausgeführt werden. Jenkins, das CI, das ich derzeit verwende, wird ebenfalls ausgeführt und liefert Testergebnisse und Abdeckungsdaten.
Möglicherweise können Sie in Ihrer IDE einen benutzerdefinierten Starter für eine Datei hinzufügen, um die Komponententests für die Datei Foo.cpp auszuführen, wenn Sie zufällig alle Komponententests für Foo unter dem Testgerät TestFoo benannt haben. Wie man dies genau für Visual-C ++ einrichtet Ich bin mir nicht sicher, aber ich denke, dass es möglich ist.
quelle
Ich benutze MSTest zum Testen von nativem C ++ - Code.
Hier ist der großartige Blog-Beitrag über diesen Weg: http://blogs.msdn.com/b/jsocha/archive/2010/11/19/writing-unit-tests-in-visual-studio-for-native-c. aspx
Ja, es wird mindestens zwei Projekte geben - eines für die Anwendung selbst, eines für Tests.
Anstatt ein drittes Projekt mit einer statischen Bibliothek zu erstellen, füge ich einfach die Quelle der Anwendung zum Testprojekt hinzu, sodass die Lösung folgendermaßen aussieht:
quelle
Vielleicht etwas spät am Tag, aber wenn ich Ihre Frage richtig lese, suchen Sie nach Techniken, um den TDD-Zyklus zu verbessern? Es wurde hier nicht erwähnt, aber haben Sie sich Post-Build-Ereignisse in VS angesehen?
Unsere Lösungen sind in der Regel organisiert (mit angezeigten Projektabhängigkeiten) ...
Das Post-Build-Ereignis von MAIN-APP führt UNIT-TEST-APP aus
Das Post-Build-Ereignis von UNIT-TEST-APP wird von selbst ausgeführt (geben Sie einfach '$ (TargetPath)' als Befehl ein, der im Post-Build-Ereignis ausgeführt werden soll).
(Dies bedeutet, dass beim Erstellen von MAIN-APP Unit-Tests zweimal ausgeführt werden können, aber das war in unserem Fall kein wirkliches Problem!)
Wie bereits erwähnt, ist das Einrichten dieser Struktur mit einigem Aufwand verbunden, aber sobald sie vorhanden ist, ist das Hinzufügen von Tests einfach.
Alles was Sie tun müssen, ist die Haupt-App zu erstellen und die Unit-Tests werden automatisch ausgeführt!
quelle
Ich weiß nicht, ob das hilft, aber es gibt einige großartige Videos über TDD von Brett L. Schuchert. Leider zeigt er die Kombination "C ++" und "VS" aber nicht
TDD mit C # und VS: http://vimeo.com/album/210446
TDD mit C ++ und Eclipse: http://vimeo.com/13240481
Vielleicht können Sie es aus diesen beiden herausarbeiten.
BEARBEITEN: In dem C ++ - Video geht es natürlich um die Verwendung des CppUTest-Testrahmens mit Eclipse. Als ich es veröffentlichte, dachte ich, dass es leicht für die Verwendung in VS übernommen werden sollte. Also habe ich ein wenig gegoogelt und Folgendes gefunden:
http://schuchert.wikispaces.com/tdd.cpp.NotesOnCppUTest
Hier finden Sie Informationen zur Verwendung von CppUTest in Visual Studio.
quelle
Googletest
Integration in vc ++
Sie benötigen kein Plugin, der Test ist nur ein weiteres Ziel. Es gibt keine Plugins, um Tests mit C ++ zu generieren. Wenn Sie könnten, würden Sie sinnlose Dinge wie Zuweisungen testen
quelle
vcproj
Datei im laufenden Betrieb automatisch zu generieren, die von mir geschriebene Testdatei und die referenzierte Produktionsdatei abzurufen und zu versuchen, diese auszuführen? (Nur träumen, aber es könnte funktionieren.)Ich kann C ++ - Tools nicht kommentieren, da ich sie seit ungefähr 20 Jahren nicht mehr berührt habe (.NET dev in diesen Tagen) und ich denke, die meisten Tools in diesen Tagen sind für verwalteten Code, aber für Techniken ...
Wie andere bereits erwähnt haben, befindet sich der Testcode immer in einem völlig anderen Projekt / einer anderen Baugruppe als der Produktionscode, und ja, Sie müssen dieses Projekt normalerweise selbst warten, obwohl dies in der VS-IDE sicherlich kein großes Problem ist, da Sie häufig mehrere Projekte haben Teil Ihrer Lösung sowieso.
Produktionscode ist und muss für TDD etwas anders geschrieben werden. Wenn Sie die Tests zuerst schreiben, müssen Sie Ihren Code so gestalten, dass er testbar ist. Dies ist ein ganz anderes Thema an sich, kann jedoch einige Zeit in Anspruch nehmen und zunächst sehr frustrierend erscheinen, insbesondere wenn Ihre IDE / Tools Ihnen kein schnelles Feedback geben. Das Ausführen von Befehlszeilentools zum Ausführen von Tests ist nur zu störend.
Es gibt viele spezifische Techniken, um Code testbar zu machen, aber die meisten von ihnen zerfallen darin, kleine Objekte zu erstellen, die nicht viel bewirken, sodass Sie sie isoliert testen und eine Testversion eines bestimmten Verhaltens in komplexere Inhalte einfügen können Objekte. IOC-Frameworks können hier sehr hilfreich sein.
Ein Buch, das Sie vielleicht nützlich finden, ist: Michael Feathers, Effektiv mit Legacy Code arbeiten. Dies verwendet in seinen Beispielen mehrere Sprachen und kann Ihnen dabei helfen, bestimmte Ansätze zur sicheren Anpassung von Code / Techniken zu identifizieren, die ursprünglich nicht als testbar konzipiert wurden.
Kleine Einschränkung: Ich habe vor Jahren von der Agile Kool-Aid getrunken: D.
quelle
Working Effectively with Legacy Code
auf meinem Schreibtisch :-)Maven wird in C ++ nicht häufig verwendet (es wird hauptsächlich für Java verwendet, ist jedoch sprachunabhängig), aber es ist ein sehr leistungsfähiges Tool, mit dem Sie alles in einem Projekt behalten können (einschließlich Tests, die empfohlen werden) Annäherung mit Maven). Ich schlage es jetzt nur vor, da es nach den bisherigen Antworten so aussieht, als gäbe es möglicherweise keine Alternative mit einem VS-Plugin.
Auf der Suche nach Plugins habe ich gefunden:
http://incubator.apache.org/npanday/
aber es scheint noch nicht sehr ausgereift zu sein. Mit dem Maven-Setup müssen Sie nur
mvn test
die Befehlszeile ausführen, um die Tests auszuführen .Wenn Sie interessiert sind , können Sie es lernen hier und (einer) der C ++ unterstützt Plugins hier (Maven hat eine Plugin - Architektur , so dass alles ein Plugin).
quelle
Framework-Empfehlung: In unserem Büro verwenden wir TestDriven.NET, das in Visual Studio integriert ist. Die unittest-Klassen sind in C ++ / CLI geschrieben, die dann aufrufen können, um den zu testenden nativen Code auszuführen. Ja, die C ++ / CLI-Klassen werden in eine eigene Assembly eingefügt, sodass der Lösung (en) ein "Test" -Projekt hinzugefügt wird.
quelle