C++ Unit Tests (schwer zu testbare Klasse)



  • @Pixma sagte in C++ Unit Tests (schwer zu testbare Klasse):

    nochmals sorry wegen dem gravierenden Fehler der mir eben nicht aufgefallen ist.

    Kein Problem. Bin selbst auf der Leitung gestanden vorher. Die Sache ist halt, daß main.cpp und Foo.cpp zwei verschiedene Compilation Units sind. Will heißen:

    main.cpp wird kompiliert und definiert IS_UNIT_TEST, bindet Foo.h ein.
    Foo.cpp wird kompiliert und bindet Foo.h ein. Bekommt aber von IS_UNIT_TEST nichts mit.

    Hm. Womit wird denn das gebaut? Kannst Du IS_UNIT_TEST nicht schon (quasi "global") beim Compileraufruf setzen?

    Plan B:

    testing.h

    #define IS_UNIT_TEST  // oder auch nicht.
    

    Foo.h

    pragma once
    
    #include "testing.h"
    
    class Foo
    {
    	public:
    		void toTest();
    };
    

    Foo.cpp

    #include "Foo.h"
    
    #include <iostream>
    
    void Foo::toTest()
    {
    #ifndef IS_UNIT_TEST
    	std::cout << "Dies wird ausgegeben bei normaler Ausfuehrung\n";
    #elif
    	std::cout << "Dies wird ausgegeben bei einem unit Test.\n";
    #endif
    }
    

    main.cpp

    #include "Foo.h"
    
    int main()
    {
    	Foo foo;
    	foo.toTest();
    }
    

    ... wobei. Den einen Code zu testen der dann garnicht 1:1 in production geht ist schon irgendwie sinnfrei. XY-Problem??

    @Pixma sagte in C++ Unit Tests (schwer zu testbare Klasse):

    eine Klasse, welche Adressen speichert, worauf dann mathematische Operationen wie Alignment, Subtraktion, Addition, etc. ausgeführt werden.

    Vielleicht magst Du das ein bisschen genauer ausführen.



  • Plan A: Ich baue das Projekt mit Visual Studio 2015. Wobei ich die Projektmappe mit Premake5 erstelle.
    Das hatte ich auch schon vorgestern probiert, in dem ich in der premake5.lua im Abschnitt workspace folgende Zeile eingefügt habe: defines { "IS_UNIT_TEST" }. Dies hat aber auch nicht funktioniert.

    Plan B: Wäre eine Überlegung, wenn es keine schönere Möglichkeit gibt. Aber das würde ich gerne als allerletzte Möglichkeit machen.

    Ich schreibe eine Klasse, welche es mir erlaubt an eine Adresse, welche mit "operator new(size);" erstellt wurde eine Variable zu schreiben. Das funktioniert alles auch soweit. Ich kann zusätzliche header (Strukturen), Tracking Strukturen und Boundaries einfügen und Funktionalitäten funktionieren auch alle auf den ersten Blick. Aktuell teste ich das ganze mit dem Visual Studio RAM Analyzer und einem selbstgeschriebenen Log worin die Ausgaben hineingeschrieben werden. Jedoch muss ich da halt manuell kontrollieren. Mein Ziel jedoch ist es diese Komponenten in Form von mehreren Unit Tests automatisiert zu testen, da die Funktionalitäten bereits recht umfangreich sind und ich ungerne alle per Hand immer im Log testen möchte. Später einmal wenn ich mir sicher bin, dass wirklich alles funktioniert kommen die Basiskomponenten wie zum Beispiel ein Linear Allocator, Stack Allocator und ein Pool Allocator.



  • @Pixma sagte in C++ Unit Tests (schwer zu testbare Klasse):

    Ich schreibe eine Klasse, welche es mir erlaubt an eine Adresse, welche mit "operator new(size);" erstellt wurde eine Variable zu schreiben.

    Ich habe keinen Plan wovon Du da redest (und wozu das gut sein soll).

    @Pixma sagte in C++ Unit Tests (schwer zu testbare Klasse):

    Ich baue das Projekt mit Visual Studio 2015.

    Dann IS_UNIT_TEST in [Project Settings] ~> [C/C++] ~> [Preprocessor] ~> [Preprocessor definitions] eintragen und glücklich sein.



  • Dieser Beitrag wurde gelöscht!


  • hmm,
    wie gesagt, ich entwickel Allocator Klassen (Linear, Stack, ...).

    Das funktioniert in dem Fall leider nicht, da die Klasse in einer anderen Projektmappe ist als meine main function.
    Naja egal, ich teste es dann halt händisch.
    Trotzdem danke 👍



  • Ich nutze auch Unittests. Aber ich mache für die Unittests immer ein eigenes Projekt und teste dort die Module einzeln ab. Ich baue auch keine Compilerweichen ein. Im Zweifel bekommt ein Modul mal noch einen zusätzlichen getter um Informationen oder Stati abzufragen, aber mehr verändere ich nicht.

    Es lässt sich allerdings auch nicht zwangsläufig alles mit Unittests abtesten.



  • Hallo lt0101,

    vielen Dank für deine Antwort. Bei meinen Solution habe ich auch drei Projektmappen.
    Eins für die ganzen Komponenten und dem Memory managern. Diese wird als DLL kompiliert. Ein anderes Projekt noch, welches diese Klassen nutzt, wo auch der Einstiegspunkt sich befindet. Dann hab ich auch noch ein Unit Test Projekt. Hier zu Beschreibung hab ich das gekürzt und umgebaut.

    Hmm ok, dann geht das wohl nicht. Weil im Studium wurde uns beigebracht wie wichtig Unit Tests sind und dass man jede Komponente ausreichend testen soll.



  • Wenn du Makros (#define) von deinem Unit-Test-Projekt aus benutzen willst, dann mußt du selbstverständlich direkt die Sourcen angeben (und kannst nicht die kompilierte Library benutzen).

    Du könntest natürlich auch nur diese Makros in den Header-Dateien nutzen (die du ja zwangsläufig einbinden mußt).

    Aber so wie @It0101 auch geschrieben hat, würde ich auf Makros (explizit für Unit-Tests) verzichten, da du ja sonst nicht den 'Production Code' testest.



  • Die Lösung ist eigentlich (wenn man das überhaupt will ... einen code testen und der andere ist production) ganz einfach und schon genannt. Das Symbol in die Projekteigenschaften eintragen. Wenn einem das bei drei Projects in einer Solution händisch zu viel Arbeit ist, dann gibt es sicher auch andere Wege als sich durch den Properties-Dialog zu klicken. Mein erster Weg wäre zu msbuild.



  • @Pixma sagte in C++ Unit Tests (schwer zu testbare Klasse):

    Weil im Studium wurde uns beigebracht wie wichtig Unit Tests sind und dass man jede Komponente ausreichend testen soll.

    Das ist auch nicht falsch. Aber man sollte im Idealfall beim Design der Komponenten/Module schon berücksichtigen, dass man mit Unittests abtesten will. Einen Unittest über eine wildgewachsene Komponente drüberzustülpen ist selten eine gute Idee. Geht aber auch.

    In dem Moment wo du aber Compilerweichen einbaust, veränderst du den Code. Und durch dumme Umstände ( Morgenkaffee vergessen ) kann es passieren, dass du die eine Sache abtestest und die andere in Production installierst. Und dann nützen dir deine Tests einen Dreck 😉

    Also möglichst unveränderten Quellcode abtesten.



  • habs nun manuell durchlaufen lassen und es funktioniert alles.
    Ich habe jede mögliche Konfiguration der Übergabeparameter kontrolliert und den Log auf die Ergebnisse verglichen.
    Dann verzichte ich in dem Speziallfall auf Unit Tests.

    Vielen Dank für die Hilfe und für den Tipp mit Makros in Bezug auf Unit Tests. 🙂

    Gruß Dennis



  • Ich verstehe das Problem nicht wirklich. Wenn ich das richtig überflogen habe, rufst du deine Funktionalitäten auf und loggst irgendwo die Ergebnisse.
    Dann kannst du doch auch da überprüfen, ob die Ergebnisse die erwarteten sind und fertig ist dein Testfall.


Anmelden zum Antworten