Ein modernes C++-orientiertes Testframework für C++-Code

Ich habe gelesen

C++-Unit-Testing-Framework

die als zu breit geschlossen ist; und was die Antworten betrifft, werden zwar mehrere Test-Frameworks aufgelistet, aber sie nicht wirklich verglichen oder ihre Funktionen diskutiert.

Jetzt bin ich daran interessiert, ein Framework für Komponententests für ein bestehendes Projekt von mir hinzuzufügen. Es enthält tatsächlich bereits eine Binärdatei, die eine bestimmte Art von Unit-Tests durchführt, oder vielleicht sollte ich etwas zwischen Unit- und Subsystem-Tests tun - aber es ist kein Unit-Testing-Framework an sich und nicht dazu gedacht, den gesamten Code zu testen. Deshalb möchte ich einen angemessenen Rahmen. Es kann mir auch erlauben (oder auch nicht), einen Teil des benutzerdefinierten Codes zu löschen, den ich gerade habe.

Eine wichtige Anforderung, die ich habe, ist, dass das Framework Modern-C++-orientiert ist . Das heißt, dass die Syntax für die Verwendung C++ 11-artig sein wird (könnte C++ 14 oder C++ 17 sein, aber die letztere Option könnte mir aufgrund von CUDA-Kompatibilitätsproblemen einige Probleme bereiten), anstatt nur zu unterstützen das Testen von C++11-Code im Nachhinein. Wenn ich also zum Beispiel lese, dass Google Test nur einen C++98-Compiler benötigt, mache ich mir Sorgen.

Weitere Schlüsselfunktionen (teilweise angepasst aus diesem Artikel ):

  • Minimaler Arbeitsaufwand zum Hinzufügen neuer Tests.
  • Einfach zu modifizieren und zu portieren - aber nicht aus den hier genannten Gründen ! Das heißt, es kann und sollte von fortgeschrittenen C++-Sprach- und Standardbibliotheksfunktionen abhängen, solange sie Standard sind; und ich habe nichts gegen Abhängigkeiten von etwas wie beispielsweise CMake oder einer Skriptsprache usw., solange sie den Unterschied zwischen Betriebssystemen und Betriebssystemverteilungen toleriert.
  • Unterstützt Setup/Teardown-Schritte (Fixtures).
  • Flexibel und robust in Bezug auf Ausnahmen, Abstürze und Behauptungen.
  • Schöne, hübsch gedruckte/mit ASCII-Grafiken verbesserte Konsolenausgabe. Ich interessiere mich nicht für bestimmte solche Features, zB Farben vs. Monochrom oder ob Fortschritte und Erfolge/Misserfolge animiert sind, aber es sollte angenehm lesbar sein.
  • Die Integration mit IDEs ist ein großes Plus

und natürlich:

  • Kostenlose und Open-Source-Lizenz
  • Gratis
  • Unterstützung für verschiedene Ausgabeformate zur Verwendung durch verschiedene Post-Mortem-Tools

Ich hätte wirklich gerne einen Vergleich der Stärken und Schwächen der von mir aufgelisteten Funktionen sowie einen Vergleich zu einem einzelnen Framework.

Was ist falsch an github.com/google/googletest ?
@Mawg: Alt, verwendet keine C++11/14-Funktionen.
Danke für die Erklärung. Das wird anderen helfen, aber dir nicht helfen (+1)

Antworten (5)

Wenn Sie Boost als Abhängigkeit haben, dann ist Boost.Test eine einfache Wahl. Konsistent, mit allen Funktionen, so minimalistisch oder so reichhaltig, wie Sie es brauchen.

Können Sie erklären, wie es sich an modernem C++ orientiert? Ich hatte den Eindruck, dass es ein bisschen alt ist.
@einpoklum - das richtige Wort ist "reif", nicht "alt". Warum zeigen Sie nicht, in welchem ​​Aspekt es veraltet ist, und wir diskutieren darüber?
Ich meinte "alt" wie in "implementiert in C++ vor 2011".
Ich habe C++1xyz-Code getestet, seit er C++0x hieß (Ende 2010), hatte nie das Gefühl, dass Boost.Test mich blockiert, Sie möchten einige projektspezifische Testrig-Bibliotheken darum herum bauen, aber das war es auch schon – das tut es Sie werden nicht gezwungen, die Syntax zu verschlechtern (oder boost::mpl und boost::fusion unnötig zu verwenden :-) )

Eifer

Ein C++14-und-up-Framework!

Beispiel:

suite<> basic("a basic suite", [](auto &_) {
  _.test("a test", []() {
    expect(true, equal_to(true));
  });

  for(int i = 0; i < 4; i++) {
    _.test("test number " + std::to_string(i), [i]() {
      expect(i % 2, less(2));
    });
  }

  subsuite<>(_, "a subsuite", [](auto &_) {
    _.test("a sub-test", []() {
      expect(true, equal_to(true));
    });
  });
});

Hinweis: Ich habe es nicht selbst ausprobiert.

damit nicht

  • Erklärte Designziele: Modern und C++11-nativ, einzelne Datei, nur Header, geringe Größe
  • Rahmencode: https://github.com/martinmoene/lest
  • Fehlt: Testreihen, parametrisierte Tests, Testvorlagen, Testdatengeneratoren, eingebaute Hamcrest-Matcher.

Beispiel:

const lest::test specification[] =
{
    CASE( "Empty string has length zero (succeed)" )
    {
        EXPECT( 0 == string(  ).length() );
        EXPECT( 0 == string("").length() );    
   },
}

Hinweis: Ich habe es nicht selbst ausprobiert.

Bandit

"Ein benutzerfreundlicher Unit-Test für C++11"

Anscheinend "biegt sich dieses Framework nach hinten", um den Quellcode Ihres Tests wie eine Beschreibung eines Tests in natürlicher Sprache lesen zu lassen. Hier ist zum Beispiel ein Test einer Gitarre, der sicherstellt, dass sie im Distortion-Modus verzerrt klingt:

describe("in distorted mode", [&]() {
    before_each([&]() { fuzzbox->flip(); });

    it("sounds distorted", [&]() {
        AssertThat(guitar->sound(), Equals(sounds::distorted));
    });
});

Hinweis: Ich habe es selbst noch nicht ausprobiert.

a) Bitte empfehlen Sie nichts, was Sie nicht selbst ausprobiert haben. b) Bitte schlagen Sie nicht mehrere Tools in einer Antwort vor.
@ThomasWeller: a) Worauf stützen Sie diesen Vorschlag? b) Wollen Sie stattdessen vorschlagen, mehrere Antworten zu verwenden?
@ThomasWeller: a) Noch keine Referenzen dafür ... und ich bin anderer Meinung. Hier auf der Seite kann man Tools auch ohne Bewertungen ausprobieren. b) Also markieren, nicht ablehnen ... trotzdem meine Antwort teilen.
Ich kann nicht markieren: Es ist kein Spam, keine Unhöflichkeit, es ist eine (Mehrfach-)Antwort, und es ist nicht die Aufgabe des Moderators, Antworten in Stücke zu teilen.
Interessant ist auch, dass Sie selbst den ursprünglichen Bedarf an einem solchen Tool hatten und die Lösung jetzt nicht ausprobiert haben. Warum nicht?
@ThomasWeller: Meine Codierungsbemühungen haben sich auf andere Bereiche konzentriert; und Tests können weiterhin auch ohne ein geeignetes Framework geschrieben werden.

DocTest

Präsentiert auf der CppCon 2017 von Victor Kirilov

Dieses aktiv entwickelte Framework ist eigentlich nicht auf modernes C++ ausgerichtet, aber es zielt darauf ab, es mit seiner nächsten Hauptversion (2.0; es ist derzeit 1.2) zu sein.

  • Motto: "Das schnellste funktionsreiche C++98/C++11 Single-Header-Testframework für Unit-Tests und TDD"
  • Rahmencode: https://github.com/onqtam/doctest
  • Ehrgeizige Roadmap , einschließlich IDE-Integrationen
  • Angeblich sehr schnell - mit [Benchmarks] gegen das Catch-Framework (aber ich habe keine Ahnung, ob Catch schneller ist als Gtest, CppUnit usw.)

Hinweis: Ich habe dies nicht selbst ausprobiert.