KUnitTest
tester.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef TESTER_H
00030 #define TESTER_H
00031
00320 #include <iostream>
00321 using namespace std;
00322
00323 #include <QtCore/QObject>
00324 #include <QtCore/QStringList>
00325 #include <QtCore/QHash>
00326 #include <QtCore/QTextStream>
00327
00328 #include "kunittest_export.h"
00329
00335 #define CHECK( x, y ) check( __FILE__, __LINE__, #x, x, y, false )
00336
00342 #define VERIFY( cond ) check( __FILE__, __LINE__, #cond, cond, true, false )
00343
00352 #define XFAIL( x, y ) check( __FILE__, __LINE__, #x, x, y, true )
00353
00359 #define SKIP( x ) skip( __FILE__, __LINE__, QLatin1String(#x))
00360
00368 #define CHECK_EXCEPTION(exceptionCatch, expression) \
00369 try \
00370 { \
00371 expression; \
00372 } \
00373 catch(exceptionCatch) \
00374 { \
00375 setExceptionRaised(true); \
00376 } \
00377 if(exceptionRaised()) \
00378 { \
00379 success(QString(__FILE__) + "[" + QString::number(__LINE__) + "]: passed " + #expression); \
00380 } \
00381 else \
00382 { \
00383 failure(QString(__FILE__) + "[" + QString::number(__LINE__) + QString("]: failed to throw " \
00384 "an exception on: ") + #expression); \
00385 } \
00386 setExceptionRaised(false);
00387
00392 #define XFAIL_EXCEPTION(exceptionCatch, expression) \
00393 try \
00394 { \
00395 expression; \
00396 } \
00397 catch(exceptionCatch) \
00398 { \
00399 setExceptionRaised(true); \
00400 } \
00401 if(exceptionRaised()) \
00402 { \
00403 unexpectedSuccess(QString(__FILE__) + "[" + QString::number(__LINE__) + "]: unexpectedly threw an exception and passed: " + #expression); \
00404 }\
00405 else \
00406 { \
00407 expectedFailure(QString(__FILE__) + "[" + QString::number(__LINE__) + QString("]: failed to throw an exception on: ") + #expression); \
00408 } \
00409 setExceptionRaised(false);
00410
00416 #define SKIP_EXCEPTION(exceptionCatch, expression) \
00417 skip( __FILE__, __LINE__, QString("Exception catch: ")\
00418 .arg(QString(#exceptionCatch)).arg(QString(" Test expression: ")).arg(QString(#expression)))
00419
00420 namespace KUnitTest
00421 {
00426 class KUNITTEST_EXPORT TestResults
00427 {
00428 friend class Tester;
00429
00430 public:
00431 TestResults() : m_tests( 0 ) {}
00432
00433 virtual ~TestResults() {}
00434
00437 virtual void clear()
00438 {
00439 m_errorList.clear();
00440 m_xfailList.clear();
00441 m_xpassList.clear();
00442 m_skipList.clear();
00443 m_successList.clear();
00444 m_debug = QLatin1String("");
00445 m_tests = 0;
00446 }
00447
00451 virtual void addDebugInfo(const QString &debug)
00452 {
00453 m_debug += debug;
00454 }
00455
00458 QString debugInfo() const { return m_debug; }
00459
00461 int testsFinished() const { return m_tests; }
00462
00464 int errors() const { return m_errorList.count(); }
00465
00467 int xfails() const { return m_xfailList.count(); }
00468
00470 int xpasses() const { return m_xpassList.count(); }
00471
00473 int skipped() const { return m_skipList.count(); }
00474
00476 int passed() const { return m_successList.count(); }
00477
00479 QStringList errorList() const { return m_errorList; }
00480
00482 QStringList xfailList() const { return m_xfailList; }
00483
00485 QStringList xpassList() const { return m_xpassList; }
00486
00488 QStringList skipList() const { return m_skipList; }
00489
00491 QStringList successList() const { return m_successList; }
00492
00493 private:
00494 QStringList m_errorList;
00495 QStringList m_xfailList;
00496 QStringList m_xpassList;
00497 QStringList m_skipList;
00498 QStringList m_successList;
00499 QString m_debug;
00500 int m_tests;
00501 };
00502
00503 typedef QHash<QByteArray, TestResults *> TestResultsList;
00504
00506
00507
00516 class KUNITTEST_EXPORT Tester : public QObject
00517 {
00518 public:
00519 Tester(const char *name = 0L)
00520 : QObject(0L), m_results(new TestResults()), m_exceptionState(false)
00521 {
00522 setObjectName( QLatin1String(name) );
00523 }
00524
00525 virtual ~Tester() { delete m_results; }
00526
00527 public:
00530 virtual void allTests() = 0;
00531
00532 public:
00535 virtual TestResults *results() const { return m_results; }
00536
00537 protected:
00543 void skip( const char *file, int line, QString msg )
00544 {
00545 QString skipEntry;
00546 QTextStream ts( &skipEntry, QIODevice::WriteOnly );
00547 ts << file << "["<< line <<"]: " << msg;
00548 skipTest( skipEntry );
00549 }
00550
00559 template<typename T>
00560 void check( const char *file, int line, const char *str,
00561 const T &result, const T &expectedResult,
00562 bool expectedFail )
00563 {
00564 cout << "check: " << file << "["<< line <<"]" << endl;
00565
00566 if ( result != expectedResult )
00567 {
00568 QString error;
00569 QTextStream ts( &error, QIODevice::WriteOnly );
00570 ts << file << "["<< line <<"]: failed on \"" << str
00571 <<"\" result = '" << result << "' expected = '" << expectedResult << "'";
00572
00573 if ( expectedFail )
00574 expectedFailure( error );
00575 else
00576 failure( error );
00577
00578 }
00579 else
00580 {
00581
00582
00583 if (expectedFail)
00584 {
00585 QString err;
00586 QTextStream ts( &err, QIODevice::WriteOnly );
00587 ts << file << "["<< line <<"]: "
00588 <<" unexpectedly passed on \""
00589 << str <<"\"";
00590 unexpectedSuccess( err );
00591 }
00592 else
00593 {
00594 QString succ;
00595 QTextStream ts( &succ, QIODevice::WriteOnly );
00596 ts << file << "["<< line <<"]: "
00597 <<" passed \""
00598 << str <<"\"";
00599 success( succ );
00600 }
00601 }
00602
00603 ++m_results->m_tests;
00604 }
00605
00613 void success(const QString &message) { m_results->m_successList.append(message); }
00614
00622 void failure(const QString &message) { m_results->m_errorList.append(message); }
00623
00631 void expectedFailure(const QString &message) { m_results->m_xfailList.append(message); }
00632
00640 void unexpectedSuccess(const QString &message) { m_results->m_xpassList.append(message); }
00641
00649 void skipTest(const QString &message) { m_results->m_skipList.append(message); }
00650
00658 void setExceptionRaised(bool state) { m_exceptionState = state; }
00659
00665 bool exceptionRaised() const
00666 {
00667 return m_exceptionState;
00668 }
00669
00670 protected:
00671 TestResults *m_results;
00672
00673 private:
00674
00675 bool m_exceptionState;
00676 };
00677
00682 class KUNITTEST_EXPORT SlotTester : public Tester
00683 {
00684 Q_OBJECT
00685
00686 public:
00687 SlotTester();
00688 virtual ~SlotTester();
00689
00690 void allTests();
00691
00692 virtual TestResults *results() const { return Tester::results(); }
00693
00695 TestResults *results(const char *slotName);
00696
00698 const TestResultsList &resultsList() const { return m_resultsList; }
00699
00700 Q_SIGNALS:
00701 void invoke();
00702
00703 private:
00704 void invokeMember(const QString &str);
00705
00706 TestResultsList m_resultsList;
00707 TestResults *m_total;
00708 };
00709 }
00710
00711 class QRect;
00712 KUNITTEST_EXPORT QTextStream& operator<<( QTextStream& str, const QRect& r );
00713
00714 class QPoint;
00715 KUNITTEST_EXPORT QTextStream& operator<<( QTextStream& str, const QPoint& r );
00716
00717 class QSize;
00718 KUNITTEST_EXPORT QTextStream& operator<<( QTextStream& str, const QSize& r );
00719
00720 #endif