KUnitTest
tester.h
Go to the documentation of this file.
00001 /* 00002 * tester.h 00003 * 00004 * Copyright (C) 2004 Zack Rusin <zack@kde.org> 00005 * Copyright (C) 2005 Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net> 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * 1. Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * 2. Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in the 00015 * documentation and/or other materials provided with the distribution. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00018 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00019 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00020 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00022 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00023 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00024 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00026 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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 //typedef TestResultsList::Iterator TestResultsListIteratorType; 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 // then the test passed, but we want to record it if 00582 // we were expecting a failure 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
KDE 4.6 API Reference