QTestLib - ein Beispielprojekt testen, aber wie?

Alles rund um die Programmierung mit Qt
Antworten
ms47
Beiträge: 35
Registriert: 22. Januar 2009 10:02

QTestLib - ein Beispielprojekt testen, aber wie?

Beitrag von ms47 »

Hallo,

ich habe ein simples Beispielprojekt, welches nichts anderes macht, als Tastatureingaben einzulesen und direkt auszugeben.
Meine Frage ist, wie ich dann an diesem Beispiel Unit Tests durchführe, die die gegebenen Klassen testen, ohne dass ich selber alle Eingaben vornehmen muss. Normalerweise würde zum testen der Klasse Controller ja die Klasse KeyboardReader ersetzt, sodass die Werte die zurück gegeben werden, nicht von der Tastatur eingelsen werden müssen. Aslo wie gehe ich da jetzt am besten vor?
Leider habe ich noch keine Erfahrungen mit Unit Tests und die Beispiele von Qt kann ich hierauf nicht umsetzen.

Ich hoffe man kann mich verstehen...

Das Beispiel ist zwar in der Praxis unsinnig, aber einfach :-D

Main erzeugt und startet die Controller und dort läuft eine Schleife, die aus der Klasse KeyboardReader die Tastatureingaben einliest und ausgibt, es. Wird a gedrückt, wird das Prog hart beendet.

Hier die Klassen:

main.cpp

Code: Alles auswählen

#include <QtCore/QCoreApplication>
#include "controller.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Controller c;
    c.startController();

    return a.exec();
}
keyboardreader.cpp

Code: Alles auswählen

#include "keyboardreader.h"

KeyboardReader::KeyboardReader()
{
}

QString KeyboardReader::readFromKeyboard()
{
    string sVal;
    cin >> sVal;
    return QString(sVal.c_str());
}
controller.cpp

Code: Alles auswählen

#include "controller.h"

Controller::Controller()
{
}

void Controller::startController()
{
    while(1)
    {
        QString val = kr.readFromKeyboard();
        if(val.compare("a")==0)
        {
            break;
        }
        qDebug() << val;
    }
    exit(1);
}
Vielen Dank im Voraus.

Gruß
Markus
clohr
Beiträge: 7
Registriert: 7. November 2008 15:12

Beitrag von clohr »

hast du dir das schon mal durchgelesen: http://doc.trolltech.com/4.5/qtestlib-tutorial1.html

normalerweise sind Unit_Tests Programme, die vom Hauptprogramm unabhängig ausführbar sind, und gewisse Tests abarbeiten.

Ich hatte meine Unit-Tests aber immer mit QTest::qExec(...) in der main aufgerufen, dann kann man sich das mit QTEST_MAIN sparen. Ist aber eher unorthodox.
ms47
Beiträge: 35
Registriert: 22. Januar 2009 10:02

Beitrag von ms47 »

clohr hat geschrieben:hast du dir das schon mal durchgelesen: http://doc.trolltech.com/4.5/qtestlib-tutorial1.html

normalerweise sind Unit_Tests Programme, die vom Hauptprogramm unabhängig ausführbar sind, und gewisse Tests abarbeiten.

Ich hatte meine Unit-Tests aber immer mit QTest::qExec(...) in der main aufgerufen, dann kann man sich das mit QTEST_MAIN sparen. Ist aber eher unorthodox.
Hi,

danke für deine Antwort. Die Tutorials habe ich mir durchgelesen. Allerdings werden dort immer nur Klassen getestet ohne Rücksicht auf deren Abhängigkeiten.

Klasse A ruft Klasse B auf, die bestimmte Werte irgendwoher einliest. Klasse A kann aber nur richtig getestet werden, wenn man die Klasse B irgendwie so ersetzt, dass sie definierte Werte zurückgibt.

Wird auch mit dem begriff Mock benannt, wenn ich das richtig verstehe. Was ich aber dabei nicht verstehe, wie ich der Klasse A sagen soll, dass sie eine KlasseBMock nehmen soll.

Ich hatte gehofft, in Verbindung mit Qt, dass jemand hier schon damit Erfahrungen gemacht hat. Wenn es doch jemanden gibt, so möge er sich bitte melden ;-)

Gruß
Markus
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Irgendwie sehe ich das Problem nicht. Kannst du nicht etwas konkreter werden? Am besten ein Projekt anhängen, mit ausreichend Kommentaren die erklären was du machen willst?
Wenn es nur das cin ist: Nein, das kannst du mit QTest nicht simulieren. Du könntest dein Programm mit Stream-Operator in der Konsole aufrufen.
Dazu ein kleines Beispiel, es liegt an dir das in deinen Test zu integrieren:
main.cpp

Code: Alles auswählen

#include <iostream>
using namespace std;

struct Test {
    char get() {
        char c;
        cin >> c;
        return c;
    }
};

int main() {
    Test t;
    char c;
    while(cin && c!='a') {
        c = t.get();
        cout << "Recieved " << c << endl;
    }
}
testdata.txt

Code: Alles auswählen

x y z f s a
Aufruf:

Code: Alles auswählen

./main_1 < testdata.txt
Ausgabe:

Code: Alles auswählen

Recieved x
Recieved y
Recieved z
Recieved f
Recieved s
Recieved a
ms47 hat geschrieben:Wird auch mit dem begriff Mock benannt, wenn ich das richtig verstehe.
Hier ist aber glaub ich das eigentliche Problem...
Du hast das Tutorial nur überflogen. Den Begriff "Mock" gibt es nicht. Der moc ist Qts Meta Object Compiler, der auf von QObject abgeleitete Klassen losgelassen wird, um SIGNAL/SLOT zu ermöglichen. moc erzeugt Code, der üblicherweise in einer Datei "name.moc" gespeichert wird. Und das hat rein gar nix mit QtTestLib zu tun.
clohr
Beiträge: 7
Registriert: 7. November 2008 15:12

Beitrag von clohr »

ms47 hat geschrieben:
Hi,

danke für deine Antwort. Die Tutorials habe ich mir durchgelesen. Allerdings werden dort immer nur Klassen getestet ohne Rücksicht auf deren Abhängigkeiten.

Klasse A ruft Klasse B auf, die bestimmte Werte irgendwoher einliest. Klasse A kann aber nur richtig getestet werden, wenn man die Klasse B irgendwie so ersetzt, dass sie definierte Werte zurückgibt.

Wird auch mit dem begriff Mock benannt, wenn ich das richtig verstehe. Was ich aber dabei nicht verstehe, wie ich der Klasse A sagen soll, dass sie eine KlasseBMock nehmen soll.

Ich hatte gehofft, in Verbindung mit Qt, dass jemand hier schon damit Erfahrungen gemacht hat. Wenn es doch jemanden gibt, so möge er sich bitte melden ;-)

Gruß
Markus
Also die Unit Tests hab ich bei Qt schon verwendet, allerdings wie gesagt, hab ich diese aus der main()-Funktion heraus gestartet mit QTest::exec, was so eigentlich nicht vorgesehen ist.
Grundsätzlich war das Qt-UnitTesting-Framework auch das erste Unit-Testing Framework, was ich jemals eingesetzt hab, deswegen hab ich jetzt auch nicht die große Erfahrung damit.
Wenn du das mit dem Unit-Testing lehrbuchmässig durchziehen willst, dann solltest du dein Programm aufspalten in mehrere Bibliotheken, die sich dann in unterzeichnissen befinden.
Ich meine damit:
Hauptverzeichnis: main.cpp
Unterzeichnis Bibliothek: dort dann eine Bibliothek, die irgendwas erledigt.
In dem Unterverzeichnis Bibliothek ist dann ein Makefile, oder zwei, was einerseites das Unit-Test-Programm kompiliert und ausführt, und andererseits wird die Bibliothek kompiliert, als dynamische oder statische Lib, dass ist dann egal. Und auf diese Lib wird dann mit dem Hauptprogramm aus dem Wurzelverzeichnis gelinkt, und ausführbar gemacht.
Das klingt sehr schön in der Theorie, und das wollte ich auch schon mal mit dem QMake-Zeug versuchen, bin aber leider daran gescheitert.
Dann hatte ich es mal mit CMake versucht, hab es aber nicht ganz geschafft mit den QTestLib Zeug und cmake einen ausführbaren Unit-Test zu bauen.
Also, für den Fall, das du einen schnell funktionierenden UnitTest brauchst, starte den Unit-Test aus der main()-Funktion, dann kannst du das Unit-Test Zeug auch in dem ursprüngl. Projekt-Makefile belassen.
Und wenn du grundlegend mal wissen willst, wie so etwas funktionieren könnte:
Lade dir Psi herunter, und sie dir deren QMakefiles an, die schreiben die Unit-Test auch mit der QTestLib

http://psi-im.org/download/
Antworten