Idiomatisch TDD?



  • Hi,

    eigentlich versuche ich immer auf unnötige virtual functions zu verzichten, um nicht den vtable erzeugen zu müssen. Ich frage mich jetzt im Bereich von test-driven development jedoch, wie man es am besten bewerkstelligt, dass man eine gute Basis für Mocks und Stubs hat.

    Beispielsweise nutzt dieses Framework hier Interfaces für Klassen, die man mocken/stubben/faken möchte: https://github.com/eranpeer/FakeIt

    Das erscheint mir jedoch sehr java-style... überall ein Interface drüberkloppen, "nur" damit man es testen kann.

    Wie löst ihr das bei euren Projekten? Gibt es einen guten Guide, ein gutes Tutorial oder ein gutes Buch, wie man in C++ mit Mocks/Stubs gut und idiomatisch umgeht? Oder ist ein Interface überall drüberkloppen einfach der Weg, den man gehen sollte, sobald man Tests einführt - was man ja wohl auch generell sollte?

    An Erfahrungen wäre ich interessiert!



  • Da ich mich nicht professionell mit dem Programmieren beschäftige, möchte ich hier keinen Unsinn verbreiten, aber sind "Interfaces" nicht ein wichtiger Bestandteil von SOLID (nämlich das "D")?

    http://clean-code-developer.de/

    Wir das in der Praxis umgesetzt? Würde mich interessieren von Profis darüber zu hören und es hat ja auch irgendwie mit der Ausgangsfrage zu tun.



  • Nutzt hier niemand TDD mit C++? Bzw. einfach intensive Tests?

    temi: Spezier bitte mal genauer, wo dieses SOLID stehen soll und wo das D steht. Interfaces kann man in C++ oft durch andere Konzepte wie Funktionszeiger, Templates etc. ersetzen. Während man in Java gerne alles mit Interfaces zumüllt, ist das in C++ eben nur eine der vielen Möglichkeiten und oft eben nicht idiomatisch (d.h. stilistisch optimal).



  • Nen Template zu bauen um den Switch auf die Implementierung hinzubekommen, nur fürs testen, macht den Code aber auch komplexer (IMHO besser als unnötige Polymorphie).
    Die andere Idee wäre das dem Buildgenerator zu überlassen.
    Also das der Anhand von Makros, Variablen die Implementation switcht (im configure die Cpp bestimmt, eventuell den code manipuliert (includes modifiziert)).
    Ob das so viel besser ist, keine Ahnung.

    In der Praxis ists eh immer knapp mit der Zeit, und perfekte Lösungen darf ich nie machen ....



  • Wenn das Mock-FW dir zu OO-lastig ist, dann musst du halt was anderes suchen. Oder du benutzt einfach bedingte Kompilierung.



  • Eisflamme schrieb:

    Nutzt hier niemand TDD mit C++? Bzw. einfach intensive Tests?

    temi: Spezier bitte mal genauer, wo dieses SOLID stehen soll und wo das D steht. Interfaces kann man in C++ oft durch andere Konzepte wie Funktionszeiger, Templates etc. ersetzen. Während man in Java gerne alles mit Interfaces zumüllt, ist das in C++ eben nur eine der vielen Möglichkeiten und oft eben nicht idiomatisch (d.h. stilistisch optimal).

    http://clean-code-developer.de/weitere-infos/solid/

    https://de.wikipedia.org/wiki/Prinzipien_objektorientierten_Designs

    Wie du schon geschrieben hast, gibt es viele Möglichkeiten.



  • Eisflamme schrieb:

    Nutzt hier niemand TDD mit C++? Bzw. einfach intensive Tests?

    Wir haben viele automatisierte Tests. (TDD kann man es aber nicht nennen.)

    Das was ich davon bisher gesehen habe verwendet beim "D" Teil virtual Interfaces. Wobei das quasi alles Interfaces sind wo die virtual Calls nicht sehr weh tun. Weil der Code der in Summe vor + nach dem virtual Call läuft viel viel länger braucht als der Call selbst.
    Bei Code der merklich langsamer wird wenn man ein virtual Interface einzieht würde ich dann doch eher ein Template verwenden.



  • Ich frage mich jetzt im Bereich von test-driven development jedoch, wie man es am besten bewerkstelligt, dass man eine gute Basis für Mocks und Stubs hat.

    Was genau willst du eigentlich mocken ?
    Ich kenn den Begriff auch eher nur aus der Java Welt, und da gings zumindest in meinem Umfeld immer um Datenbanken, oder generell Services, also zeugs was an sich schon ziemlich abstrakt war.

    Ne Datenbank Schnittstelle bzw, nen Service auf WCF oder REST oder irgendwas so zu abstrahieren/modulariesieren, das dabei nen "pure virtual interface" bei rumkommt, halt ich ja an sich für gar keine so schlechte Idee.

    Kritischer wirds bei (produktiv) performanten, hardware nähren Zeugs, aber mockt man sowas eigentlich ?
    Also mockt man was, was man "normal" im C++ Context nicht abstrahieren/modularisieren würde ?



  • temi_:
    Ja, aber die Frage ist, ob es idiomatisch eine best practice gibt. Solche Seiten sind oft nicht auf C++ ausgerichtet genau so wie die ganzen Design-Pattern-Bücher ja auch nur auf Java ausgerichtet sind.

    hustbaer:
    Also bei performancekritischen Tests gemischt und somit uneinheitlich?

    Interfaces hat man ohnehin bei allem, was ein UI unterstützt oder von der Architektur her schon in Interfaces steckt wegen Factorys oder sonst was. Dann blieben bei mir z.B. vermutlich nur sehr performancekritische Basis-Rechen-Funktionen übrig, die ich mit Templates testen müsste - wenn ich da überhaupt Mocks bräuchte.

    RHBaum:
    Registry, z.B. User Settings, die man im GUI-Menü ändern kann. Da spricht eigentlich nur wenig gegen virtual calls. Wäre schon spannend zu wissen, was du tun würdest, wenn du eine perfekte Lösung machen dürftest. 🙂 Was nutzt du in der Praxis denn jetzt von all deinen Vorschlägen?

    Artchi:
    Kannst du eins empfehlen? Habe schon ein bisschen gesucht und nichts besonderes gefunden. GoogleTest wollte ich mir noch anschauen, ist aber etwas komplexer.



  • Eisflamme schrieb:

    hustbaer:
    Also bei performancekritischen Tests gemischt und somit uneinheitlich?

    Also entweder gemischt oder halt (bei performance-kritische Sachen) gar nicht.
    Aber performance-kritische Sachen (z.T. extrem) langsamer machen, nur damit man testen kann, würde ich nicht machen.

    Was noch ginge wäre ein eigener Test-Build. Also ne Build-Config wo diverse Test-Assertions mit reincompiliert sind. Muss man dann halt so hinbekommen dass diese Test-Assertions dann auch vom jeweils verwendeten Test-Framework "gesehen" werden.

    Aber automatisierte Tests, speziell Unit-Tests, sind sowieso so eine Sache. Grundsätzlich toll, aber ich hab' noch nicht viele (nicht-triviale) Tests gesehen die nicht von der konkreten Implementierung der zu testenden Sache abhängig wären. Was dann auch gleich gar nicht mehr so toll ist.


Anmelden zum Antworten