Unit-Test für C ++ - Code - Tools und Methodik [geschlossen]


134

Ich arbeite an einem großen C ++ - System, das sich seit einigen Jahren in der Entwicklung befindet. Im Rahmen der Bemühungen, die Qualität des vorhandenen Codes zu verbessern, haben wir ein großes langfristiges Refactoring-Projekt durchgeführt.

Kennen Sie ein gutes Tool, mit dem ich Unit-Tests in C ++ schreiben kann? Vielleicht etwas ähnliches wie Junit oder Nunit?

Kann jemand einen guten Rat zur Methodik des Schreibens von Komponententests für Module geben, die ohne Berücksichtigung von Komponententests geschrieben wurden?


1
Schauen Sie sich diese Frage an: stackoverflow.com/questions/3150/…
Aardvark

Antworten:


83

Das Anwenden von Komponententests auf Legacy-Code war genau der Grund, warum das effektive Arbeiten mit Legacy-Code geschrieben wurde. Michael Feathers ist der Autor - wie in anderen Antworten erwähnt, war er an der Erstellung von CppUnit und CppUnitLite beteiligt .

Alt-Text


4
Ein Miniaturbild hinzugefügt - abgestimmt. Das Buch hilft mehr als jedes andere Werkzeug.
Gishu

2
Ich denke, CPPUnit könnte es einfacher machen, Tests zu schreiben. Wir verwenden CPPUnit, aber ich bin nicht zufrieden. Ich muss für jeden Test zwei Dateien aktualisieren, und meiner Meinung nach sollte ein Test so einfach zu schreiben sein wie: 'TEST ("Testname") {ASSERT (1 == 1);}' Das Buch dagegen ist ein Muss für alle, nicht nur für diejenigen, die mit Legacy-Code arbeiten, sondern auch für diejenigen, die ihn erstellen;)
Daramarak

9
Seit wann ist C ++ Legacy?!
Nils

9
Es ist nicht so, dass C ++ Legacy ist - wenn ich mich richtig erinnere, definiert dieses Buch ein Legacy-Projekt als eines, für das es keine oder nur sehr wenige Unit-Tests gibt. Solche Projekte sind in der Regel / schwer / schwer zu schreiben, da testgetriebene Entwicklungen die Codebasis nie so beeinflusst haben, dass es trivial ist, sie zu schreiben.
Arafangion

7
@Nils: Wie einer der Amazon-Rezensenten des Buches erwähnt, ist "Legacy-Code Code ohne Komponententests", worum es bei dieser Frage genau geht.
David Johnstone

40

Google hat kürzlich eine eigene Bibliothek zum Testen von C ++ - Apps namens Google Test veröffentlicht.

Projekt auf Google Code


1
ist es möglich, dies mit VC ++ zu verwenden
yesraaj

Scheint ziemlich in Ordnung zu sein, besonders die Art und Weise, wie sie jeder Behauptung eine Beschreibung hinzufügen müssen. Auf der anderen Seite bevorzuge ich persönlich eine Unit-Test-Klasse anstelle von Makros, die wirklich nicht wie Klassen aussehen.
Wernight

3
Ein weiterer schöner Punkt sind die Verspottungsmöglichkeiten: code.google.com/p/googlemock
Philipp

Ich finde das VIEL schöner als CPPUNIT, das Tonnen von Makros und magischen Dateien benötigt, damit Tests funktionieren
Paulm

30

Schauen Sie sich einen hervorragenden Vergleich zwischen mehreren verfügbaren Suiten an. Der Autor dieses Artikels entwickelte später UnitTest ++ .

Was mir besonders gefällt (abgesehen von der Tatsache, dass Ausnahmen usw. gut behandelt werden), ist, dass die Definition der Testfälle und Testvorrichtungen nur in sehr begrenztem Umfang verwaltet wird.


2
Ist das nicht unser grundlegender Irrtum? Er hat gute Einblicke in verfügbare Projekte - aber anstatt sie zu verbessern, startet er seine eigenen.
Peterchen

@ Peterchen: ja; Aber dann ist UnitTest ++ so klein und leicht, dass es sich lohnt, ein separates Projekt zu sein - es ist sehr einfach, es in Betrieb zu nehmen.
TimStaley

24

Boost verfügt über eine Testbibliothek, die Unterstützung für Unit-Tests enthält. Es könnte sich lohnen, einen Blick darauf zu werfen.


4
Ich kann dieses hervorragende Toolkit empfehlen.
Rob

1
Ja, Boost ist der richtige Weg. Kein Overhead, einfach testen und loslegen! Ich arbeitete verzweifelt an meinem eigenen Rahmen, als mir der Schub kam. Vielen Dank Boost (für alles!)
Daramarak

Sie können einen Artikel lesen, den
Wernight

21

Noel Llopis von Games From Within ist der Autor von Exploring the C ++ Unit Testing Framework Jungle , einer umfassenden (aber jetzt veralteten) Bewertung der verschiedenen C ++ Unit Testing Frameworks sowie eines Buches über Spieleprogrammierung.

Er benutzte CppUnitLite eine ganze Weile, um verschiedene Probleme zu beheben, schloss sich aber schließlich mit einem anderen Autor der Unit-Test-Bibliothek zusammen und produzierte UnitTest ++ . Wir verwenden hier UnitTest ++ und es gefällt mir bisher sehr gut. Es hat (für mich) genau das richtige Kräfteverhältnis bei geringem Platzbedarf.

Ich habe selbst entwickelte Lösungen verwendet, CxxTest (für das Perl erforderlich ist) und boost :: test. Als ich hier bei meinem aktuellen Job Unit-Tests implementierte, kam es ziemlich genau auf UnitTest ++ vs boost :: test an.

Ich mag die meisten Boost-Bibliotheken, die ich verwendet habe, sehr, aber meiner Meinung nach ist boost :: test etwas zu hartnäckig. Besonders hat mir nicht gefallen, dass Sie (AFAIK) das Hauptprogramm des Testkabels mit einem boost :: test-Makro implementieren müssen. Ich weiß, dass es sich nicht um "reines" TDD handelt, aber manchmal benötigen wir eine Möglichkeit, Tests mit einer GUI-Anwendung auszuführen, beispielsweise wenn ein spezielles Testflag in der Befehlszeile übergeben wird und boost :: test diesen Typ nicht unterstützen kann des Szenarios.

UnitTest ++ war das einfachste Test-Framework zum Einrichten und Verwenden, auf das ich in meiner (begrenzten) Erfahrung gestoßen bin.


17

Ich verwende die ausgezeichnete Boost.Test- Bibliothek in Verbindung mit einer viel weniger bekannten, aber ach so großartigen Turtle- Bibliothek: einer auf Boost basierenden Scheinobjektbibliothek.

Stellen Sie sich vor, Sie möchten ein calculatorObjekt testen, das auf einer viewSchnittstelle funktioniert (das ist das Einführungsbeispiel von Turtle), da ein Codebeispiel besser spricht als Worte :

// declares a 'mock_view' class implementing 'view'
MOCK_BASE_CLASS( mock_view, view )
{
    // implements the 'display' method from 'view' (taking 1 argument)
    MOCK_METHOD( display, 1 )                   
};

BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
    mock_view v;
    calculator c( v );

    // expects the 'display' method to be called once with a parameter value equal to 0
    MOCK_EXPECT( v, display ).once().with( 0 ); 

    c.add( 0, 0 );
}

Sehen Sie, wie einfach und ausführlich es ist, Erwartungen an das Scheinobjekt zu deklarieren? Offensichtlich ist der Test fehlgeschlagen, wenn die Erwartungen nicht erfüllt werden.


14

Ich habe gerade mein eigenes Framework, CATCH , veröffentlicht. Es befindet sich noch in der Entwicklung, aber ich glaube, es übertrifft bereits die meisten anderen Frameworks. Unterschiedliche Menschen haben unterschiedliche Kriterien, aber ich habe versucht, den größten Teil des Bodens ohne zu viele Kompromisse abzudecken. Schauen Sie sich meinen verlinkten Blogeintrag an, um einen Vorgeschmack zu erhalten. Meine fünf wichtigsten Funktionen sind:

  • Nur Header
  • Automatische Registrierung von funktions- und methodenbasierten Tests
  • Zerlegt Standard-C ++ - Ausdrücke in LHS und RHS (sodass Sie nicht eine ganze Familie von Assert-Makros benötigen).
  • Unterstützung für verschachtelte Abschnitte innerhalb eines funktionsbasierten Geräts
  • Namenstests in natürlicher Sprache - Funktions- / Methodennamen werden generiert

Es hat auch Objective-C-Bindungen.


4
doctest ist meine Neuimplementierung von Catch mit einem großen Fokus auf die Kompilierungsgeschwindigkeit
lesen




6

Ich bin derzeit auf der Suche nach einem Unit-Test- und Mock-Framework, das in unserem Unternehmen für eine langlebige Codebasis verwendet werden kann. Wie Sie wissen, ist die Liste der Unit-Test-Frameworks für c ++ lang, daher habe ich einige Filter angewendet, um sie auf eine Hand voll zu reduzieren, die genauer betrachtet werden kann. Das erste Filterkriterium war, dass es kostenlos sein muss. Das zweite Kriterium war die Projektaktivität. Ich habe auch nach spöttischen Frameworks gesucht, weil Sie eines benötigen, wenn Sie Unit-Tests schreiben möchten.

Ich habe die folgende Liste (ungefähr) sortiert nach Aktivität erstellt, höchste Aktivität oben:

  • GoogleTest / GoogleMock: Viele Mitwirkende, die von Google selbst verwendet werden. Dies wird wahrscheinlich für einige Zeit hier sein und Updates erhalten. Für meine private Codebasis werde ich auf diese Kombination umsteigen, in der Hoffnung, in den schnellsten Zug zu springen.

  • BoostTest + Turtle: Nicht so oft aktualisiert, aber das Test-Framework ist Teil von Boost, daher sollte es beibehalten werden. Turtle hingegen wird hauptsächlich von einem Mann gepflegt, hat aber keine Aktivität, ist also nicht tot. Ich habe fast alle meine Testerfahrungen mit dieser Kombination gemacht, da wir die Boost-Bibliothek bereits bei meinem vorherigen Job verwendet haben und ich sie derzeit für meinen privaten Code verwende.

  • CppUTest: Bietet Tests und Verspottungen. Dieses Projekt war von 2008 bis 2015 aktiv und hat in letzter Zeit ziemlich viele Aktivitäten. Dieser Fund war eine kleine Überraschung, da viele Projekte mit deutlich weniger Aktivität häufiger bei der Suche im Web auftauchen (wie CppUnit, das 2013 das letzte Update hatte). Ich habe mich nicht eingehender damit befasst, daher kann ich nichts zu den Details sagen. Bearbeiten (16.12.2015): Ich habe dies kürzlich ausprobiert und festgestellt, dass dieses Framework etwas ungeschickt und "C-stylisch" ist, insbesondere bei Verwendung der Mock-Klassen. Es schien auch eine geringere Vielfalt an Behauptungen zu haben als andere Rahmenbedingungen. Ich denke, seine Hauptstärke ist, dass es mit reinen C-Projekten verwendet werden kann.

  • QTest: Die Testbibliothek , die mit dem Qt-Framework geliefert wird . Die Wartung sollte für einige Zeit garantiert sein, aber ich verwende sie eher als unterstützende Bibliothek, da die Testregistrierung IMO ungeschickter ist als in anderen Frameworks. Soweit ich es verstehe, zwingt es Sie, eine Test-Exe pro Testvorrichtung zu haben. Die Testhilfefunktionen können jedoch beim Testen des Qt-Gui-Codes von Nutzen sein. Es hat keine Verspottungen.

  • Fang: Es hat jüngste Aktivitäten, wird aber hauptsächlich von einem Mann entwickelt. Das Schöne an diesem Framework ist der alternative Fixture-Ansatz, mit dem Sie wiederverwendbaren Fixture-Code im Test selbst schreiben können. Außerdem können Sie Testnamen als Zeichenfolgen festlegen. Dies ist hilfreich, wenn Sie dazu neigen, ganze Sätze als Testnamen zu schreiben. Ich wünschte, dieser Stil würde herausgerissen und in googleTest eingefügt ;-)

Mock Frameworks

Die Anzahl der Mock-Frameworks ist viel kleiner als die Anzahl der Test-Frameworks, aber hier sind diejenigen, bei denen ich festgestellt habe, dass sie kürzlich aktiv waren.

  • Hippomock : Ab 2008 aktiv, aber nur mit geringer Intensität.

  • FakeIt : Ab 2013 aktiv, aber mehr oder weniger von einem Mann entwickelt.

Fazit

Wenn Ihre Codebasis langfristig verfügbar ist, wählen Sie zwischen BoostTest + Turtle und GoogleTest + GoogleMock . Ich denke, diese beiden werden langfristig gewartet werden. Wenn Sie nur eine kurzlebige Codebasis haben, können Sie Catch ausprobieren, das eine schöne Syntax hat. Dann müssten Sie zusätzlich ein spöttisches Framework auswählen. Wenn Sie mit Visual Studio arbeiten, können Sie Test-Runner-Adapter für BoostTest und GoogleTest herunterladen. Auf diese Weise können Sie die Tests mit der in VS integrierten Test-Runner-GUI ausführen.


3

Siehe auch die Antworten auf die eng verwandte Frage "Auswahl eines C ++ - Unit-Test-Tools / Frameworks" hier


3

Es gibt auch TUT , Template-Unit-Test, ein vorlagenbasiertes Framework. Die Syntax ist umständlich (manche nennen es Vorlagenmissbrauch), aber der Hauptvorteil ist, dass alles in einer einzigen Header-Datei enthalten ist .

Ein Beispiel für einen mit TUT geschriebenen Unit-Test finden Sie hier.


2
Ich habe eine Bibliothek nur für Header eingerichtet, die Makros enthält, die TUTs umschließen, um die Funktion sicherzustellen und den Deklerationscode zu testen, um ihn zu vereinfachen und bei Fehlern Informationen zu Datei- und Zeilennummern bereitzustellen. Hier ist ein Link zu einem Beitrag mit Beispielen für den Unterschied in Ausgabe und Code sowie ein Link zum Projekt auf github: codecrafter.wordpress.com/2012/12/19/tutadapter1
Josh Heitzman

2

Ich habe CPPunit ausprobiert und es ist nicht sehr benutzerfreundlich.

Die einzige Alternative, die ich kenne, ist die Verwendung von C ++. NET, um Ihre C ++ - Klassen zu verpacken und Komponententests mit einem der .NET-Unit-Test-Frameworks (NUnit, MBUnit usw.) zu schreiben.



1

Michael Feathers von ObjectMentor war maßgeblich an der Entwicklung von CppUnit und CppUnitLite beteiligt.

Er empfiehlt jetzt CppUnitLite



1

Schauen Sie sich cfix ( http://www.cfix-testing.org ) an, es ist auf die Entwicklung von Windows C / C ++ spezialisiert und unterstützt sowohl Unit-Tests im Benutzermodus als auch im Kernelmodus.


Danke für das Teilen. Ich habe kürzlich angefangen, cfix zu Testzwecken zu verwenden. Ich suchte nach einer Möglichkeit, den Aufrufstapel sowohl bei bestandenen als auch bei fehlgeschlagenen Testfällen anzuzeigen. Gibt es in cfix einen Weg, dies zu erreichen?
versuchen, am

1

Wenn Sie mit Visual Studio 2008 SP1 arbeiten, würde ich die Verwendung von MSTest zum Schreiben der Komponententests dringend empfehlen. Ich benutze dann Google Mock zum Schreiben der Mocks. Die Integration in die IDE ist ideal und ermöglicht und trägt nicht den Aufwand von CPPunit in Bezug auf die Bearbeitung von drei Stellen für die Hinzufügung eines Tests.


1

Ich denke, VisualAssert leistet hervorragende Arbeit bei der VS-Integration. Sie können die Tests in VS ausführen und debuggen, und Sie müssen keine ausführbare Datei erstellen, um die Tests auszuführen.



Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.