[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Switching to QtTestLib for unit tests
From:       David Faure <faure () kde ! org>
Date:       2005-09-03 9:52:01
Message-ID: 200509031152.02264.faure () kde ! org
[Download RAW message or body]

It's bad timing as usual. After talking to Trolltech about QtTestLib-3 last year
and waiting for a very very long time for them GPL'ing it, and nothing happened,
we went forward with kunittest.

But now Trolltech has GPL'ed QtTestLib-4, which is really much nicer than the
previous version of QtTestLib.
See http://www.trolltech.com/products/solutions/catalog/4/Tools/qttestlib/

I wasn't initially in favour of switching to qttestlib, but then I saw Harald's presentation
of it (see below for a list of advantages), and I also ran into problems with kunittest:
the whole idea of dlopened modules falls apart in kdelibs. The test module links
to libkdecore.so, and when dlopening it from kunittestmodrunner it would use
the system libkdecore.so instead of the one in ../.libs. Libtool can use local libs
when launching a program, but there's no solution for dlopening modules.
My reason for pushing dlopened modules was to simplify the code to write for
each test program, but another solution for that is simply a macro containing the whole
main() of the test program, like qttestlib does.

Here's a list of other things that qttestlib provides over kunittest:

* More flexible data-type support (one can't do CHECK(QStringList,QStringList) with kunittest
because that type isn't printable with <<, for instance; qttestlib uses template specialization
so it works fine there)
* Data-driven testing (see the online tutorial)
* GUI automation (send fake key events and mouse events to widgets)
* Signal introspection (count how many times a signal was emitted, and check with which values)
* XML output (for GUIs)
* Verbose output (shows variable values also in working tests) / signal slot dumper
* Comments attached with expected failures
* Additional message can be passed to VERIFY macro check, e.g. DB error message.
* Support for checking that a qDebug/qWarning message was shown
* Simpler framework (no test runner, and no GUI)

But of course the idea would be that the kdesdk/kunittest GUI could be ported
to qttestlib. I don't plan on working on that myself though, my main use for unit-testing
is "make check" type of thing, mostly in kdelibs.

And for the non-technical advantages:
* maintainance and bugfixing done by Trolltech (Harald will keep our copy in sync)
* using the same unittest framework as Qt makes KDE development closer to Qt
development. Someone writing KDE applications can switch to writing a Qt applications
now and then, and vice-versa, without having to learn two unit test systems.

I thought the GPL license of qttestlib could be a problem, but in fact qtteslib
is just like Qt: GPL for opensource development, and available to commercial
Qt customers via Qt Solutions. No problem.

If you wonder what switching would mean: see attached diff for ktempfiletest,
including the full diff for importing qttestlib to kdelibs.
To get an automake-ready qttestlib, unpack http://kdab.net/~dfaure/qttestlib.diff.bz2
in the toplevel of kdelibs.

OK with everyone?

-- 
David Faure, faure@kde.org, sponsored by Trolltech to work on KDE,
Konqueror (http://www.konqueror.org), and KOffice (http://www.koffice.org).

["example.diff" (text/x-diff)]

Index: kdecore/tests/Makefile.am
===================================================================
--- kdecore/tests/Makefile.am	(revision 456383)
+++ kdecore/tests/Makefile.am	(working copy)
@@ -17,7 +17,7 @@
 #    the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
 #    Boston, MA 02110-1301, USA.
 
-INCLUDES = -I$(top_srcdir)/kdecore $(all_includes)
+INCLUDES = -I$(top_srcdir)/kdecore -I$(top_srcdir)/qttestlib $(all_includes)
 
 AM_LDFLAGS = $(QT_LDFLAGS) $(X_LDFLAGS) $(KDE_RPATH)
 
@@ -28,9 +28,10 @@ check_PROGRAMS = kconfigtestgui klocalet
 	cplusplustest kiconloadertest kmdcodectest knotifytest \
 	ksortablevaluelisttest krfcdatetest testqtargs kprociotest \
 	kcharsetstest kcalendartest kmacroexpandertest kshelltest \
-	kxerrorhandlertest startserviceby kstdacceltest kglobaltest ktimezonestest
+	kxerrorhandlertest startserviceby kstdacceltest kglobaltest ktimezonestest \
+	ktempfiletest
 
-TESTS = kurltest kstdacceltest
+TESTS = kurltest kstdacceltest ktempfiletest
 
 noinst_HEADERS = klocaletest.h kprocesstest.h KIDLTest.h \
 		kipctest.h kprociotest.h
@@ -77,17 +78,16 @@ kstdacceltest_SOURCES = kstdacceltest.cp
 kglobaltest_SOURCES = kglobaltest.cpp
 ktimezonestest_SOURCES = ktimezonestest.cpp
 
+ktempfiletest_SOURCES = ktempfiletest.cpp
+ktempfiletest_LDADD = $(LIB_KDECORE) $(top_builddir)/qttestlib/libqttestlib.la
+
 LIBADD = $(LIB_KDECORE) $(LIB_KUNITTEST)
 check_LTLIBRARIES = kunittest_kconfig.la \
-		    kunittest_ktempfile.la \
 		    kunittest_kurlmimetest.la
 
 kunittest_kconfig_la_SOURCES = kconfigtest.cpp
 kunittest_kconfig_la_LDFLAGS = -module $(KDE_CHECK_PLUGIN)
 
-kunittest_ktempfile_la_SOURCES = ktempfiletest.cpp
-kunittest_ktempfile_la_LDFLAGS = -module $(KDE_CHECK_PLUGIN)
-
 kunittest_kurlmimetest_la_SOURCES = kurlmimetest.cpp
 kunittest_kurlmimetest_la_LDFLAGS = -module $(KDE_CHECK_PLUGIN)
 
Index: kdecore/tests/ktempfiletest.cpp
===================================================================
--- kdecore/tests/ktempfiletest.cpp	(revision 456397)
+++ kdecore/tests/ktempfiletest.cpp	(working copy)
@@ -16,7 +16,10 @@
     Boston, MA 02110-1301, USA.
 */
 
+#include "QtTest/qttest_kde.h"
+
 #include "ktempfiletest.h"
+#include "ktempfiletest.moc"
 #include "ktempfile.h"
 #include "kcmdlineargs.h"
 #include "kaboutdata.h"
@@ -30,9 +33,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <kunittest/module.h>
-KUNITTEST_MODULE( kunittest_ktempfile, "KTempFileTest" );
-KUNITTEST_MODULE_REGISTER_TESTER( KTempFileTest );
+QTTEST_KDEMAIN( KTempFileTest, false )
 
 void KTempFileTest::testBasic()
 {
@@ -41,7 +42,7 @@ void KTempFileTest::testBasic()
    f4.setAutoDelete( true );
    qDebug("Filename = %s", qPrintable(f4.name()));
    bool exists = QFile::exists( f4.name() );
-   CHECK( exists, true );
+   VERIFY( exists );
 }
 
 void KTempFileTest::testFixedExtension()
@@ -50,7 +51,7 @@ void KTempFileTest::testFixedExtension()
    KTempFile f2(QString::null, ".ps");
    f2.setAutoDelete( true );
    qDebug("Filename = %s", qPrintable(f2.name()));
-   CHECK( f2.name().right(3), QString::fromLatin1(".ps") );
+   COMPARE( f2.name().right(3), QString::fromLatin1(".ps") );
 }
 
 void KTempFileTest::testHomeDir()
@@ -60,10 +61,9 @@ void KTempFileTest::testHomeDir()
    KTempFile f3(home+QLatin1String("/testXXX"), ".myEXT", 0666);
    f3.setAutoDelete( true );
    qDebug("Filename = %s", qPrintable(f3.name()));
-   CHECK( f3.name().left( home.length() ), home );
-   CHECK( f3.name().right(6), QString::fromLatin1( ".myEXT" ) );
+   COMPARE( f3.name().left( home.length() ), home );
+   COMPARE( f3.name().right(6), QString::fromLatin1( ".myEXT" ) );
 }
 
 //QString name = locateLocal("socket", "test");
 //printf("Socket Filename = %s\n", name.ascii());
-
Index: kdecore/tests/ktempfiletest.h
===================================================================
--- kdecore/tests/ktempfiletest.h	(revision 456398)
+++ kdecore/tests/ktempfiletest.h	(working copy)
@@ -1,9 +1,9 @@
 #ifndef ktempfiletest_h
 #define ktempfiletest_h
 
-#include <kunittest/tester.h>
+#include <qobject.h>
 
-class KTempFileTest : public KUnitTest::SlotTester
+class KTempFileTest : public QObject
 {
     Q_OBJECT
 public slots:


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic