Página principal | Lista de namespace | Jerarquía de la clase | Lista de componentes | Directories | Lista de archivos | Miembros del Namespace  | Miembros de las clases | Archivos de los miembros | Páginas relacionadas

ADH_test.h

Ir a la documentación de este archivo.
00001 // ADH_test.h (C) 2008  [email protected]
00002 
00003 /** \file  ADH_test.h
00004     \brief Módulo para prueba unitaria de programas.
00005 
00006     \author Adolfo Di Mare <[email protected]>
00007     \date   2008
00008 */
00009 
00010 /** \mainpage
00011 
00012 \section sec-01 Módulo para prueba unitaria de programas
00013 
00014 El archivo de encabezado \c ADH_test.h apoya la escritura de módulos de prueba de
00015 unitaria programas. El modelo que se usa para esta implementación es
00016 similar al expuesto en este artículo "The Simplest Automated Unit
00017 Test Framework That Could Possibly Work" de Chuck Allison, que se
00018 puede obtener aquí:
00019 - http://www.stickyminds.com/getfile.asp?ot=XML&id=3129&fn=XDD3129filelistfilename1.pdf
00020 - http://www.google.com/search?num=100&as_q=Simplest+Unit+Test+Allison
00021 - http://search.yahoo.com/search?n=100&p=Simplest+Unit+Test+Allison
00022 
00023 - Para simplificar al mínimo la tarea de programar los casos de prueba,
00024   la implementación completa de \c ADH_test está contenida en el archivo
00025   de encabezado \c ADH_test.h, por lo que para hacer pruebas basta poner
00026   esta directiva:
00027   - <strong>\#include "ADH_test.h"</strong>
00028 - Este marco de pruebas es similar a JUnit, pues se presume que en
00029   el futuro los estudiantes usarán Java como su lenguaje principal
00030   para desarrollo de programas (pues usan C++ sólo para adiestrarse
00031   profundamente en técnicas de programación).
00032   \see http://search.yahoo.com/search?n=100&p=JUnit+Java
00033 - Como el lenguaje C++ no tiene un mecanismo similar al de "reflexión"
00034   de Java, en cada prueba fallida se registra la condición de prueba
00035   exacta, obtenida a través de una invocación de la macro \c ADH_test_TEST()
00036   que registra el nombre del archivo \c __FILE__ y el renglón \c __LINE__
00037   de la prueba.
00038   \see http://search.yahoo.com/search?n=100&p=reflection+Java
00039 - Para simplificar este marco de pruebas no se usa la clase \c TestResult
00040   que sirve para acumular resultados de las pruebas. En su lugar, se puede
00041   obtener una hilera enorme \c std::string que contiene el registro de
00042   todas las pruebas que no tuvieron éxito invocando el método
00043   \c TestCase::toString() o \c TestCase::toXML().
00044 - Para simplificar esta plataforma de pruebas no se hace diferencia entre
00045   un caso de prueba de prueba existoso y uno que no tiene éxito porque no
00046   se ha levantado la excepción adecuada. Esto contrasta con JUnit, que
00047   llama "falla" a un caso de prueba que ha levantado la excepción equivocada.
00048   Por eso \c TestCase::failureCount() siempre retorna cero \c 0.
00049     \code
00050     // Falla vs Error en JUnit
00051     public void test_Falla () {
00052         try {
00053             new ArrayList(10).get( 11 );
00054             fail("Falla si no tira IndexOutOfBoundsException" ); // falla
00055         }
00056         catch (IndexOutOfBoundsException success) { } // Ok
00057     }
00058     public void test_Error() {
00059         assertTrue( 1 == 2 ); // error
00060     }
00061     \endcode
00062 - En \c ADH_test.h no se hace diferencia entre "fallas" y "errores".
00063   - En \c JUnit una "falla" se produce cuando no se levanta la excepción
00064     adecuada.
00065   - En \c JUnit un  "error" se produce cuando una aserción resulta falsa.
00066   - \see http://osdir.com/ml/java.junit.user/2002-06/msg00114.html
00067   - \see http://www.cs.waikato.ac.nz/~bernhard/314/junit3.8.1/doc/faq/faq.htm#tests_9
00068   - \see http://search.yahoo.com/search?n=100&p=junit+difference+failure+error
00069 - En JUnit la clase \c TestCase es una subclase de \c Assert; aquí no existe
00070   la clase \c Assert pero para mantener una leve compatibiliidad sí se provée
00071   una funcionalidad similar con macros cuyo nombres comienzan con "assert".
00072   \see http://search.yahoo.com/search?n=100&p=JUnit+Java+Assert+method
00073 
00074 \dontinclude test_ADH_test.cpp
00075 \skipline    test::Allison()
00076 \until       }}
00077 \see         test_ADH_test::test_Allison()
00078 */
00079 
00080 #ifndef ADH_test_h
00081 #define ADH_test_h ///< Evita la inclusión múltiple
00082 
00083 #include <list>      // std::list
00084 #include <string>    // class std::string
00085 #include <sstream>   // class basic_ostringstream<T,Ch>
00086 #include <cstdio>    // memcpy()+strlen()
00087 #include <typeinfo>  // class std::type_info ==> char* typeid().name();
00088 #include <algorithm> // find()
00089 
00090 // using namespace std;
00091 /// Definido por la biblioteca C++ estándar.
00092 namespace std {} // Está acá para que Doxygen lo documente
00093 
00094 /// Escuela de Ciencias de la Computación e Informática.
00095 /// \see http:www.ecci.ucr.ac.cr
00096 namespace ECCI { }
00097 
00098 /// Clase privada que contiene los datos de cada prueba no exitosa.
00099 class TestCaseError {
00100     const char * m_fname; ///< Nombre del archivo en donde se produjo el error.
00101     int m_lineno; ///< Número de línea del archivo en donde se produjo el error.
00102     const char * m_label; ///< Mensaje descriptivo del error.
00103     bool m_destroy_label; ///< Indica si el destructor debe retornar la memoria de \c m_label.
00104 private:
00105     TestCaseError() :
00106         m_fname(""), m_lineno(0), m_label(""), m_destroy_label(false)
00107     { } ///< Constructor por defecto.
00108     TestCaseError(const char * fname, int line, const char * label, bool destroy )
00109         : m_fname(fname), m_lineno(line), m_label(label), m_destroy_label(destroy)
00110     { } ///< Constructor.
00111 public:
00112     ~TestCaseError() { if (m_destroy_label) { delete [] m_label; } } ///< Destructor.
00113     TestCaseError( const TestCaseError& o ) {
00114         m_fname = o.m_fname; m_lineno = o.m_lineno; m_label = o.m_label;
00115         m_destroy_label = o.m_destroy_label;
00116         const_cast<TestCaseError*>(&o)->m_destroy_label = false; // evita doble destrucción de m_label
00117     //  const_cast<bool>(o.m_destroy_label) = false; // no compila
00118     } ///< Constructor de copia.
00119     void operator = ( TestCaseError& o ) {
00120         m_fname = o.m_fname; m_lineno = o.m_lineno; m_label = o.m_label;
00121         m_destroy_label = o.m_destroy_label;
00122         o.m_destroy_label = false; // evita doble destrucción de m_label
00123     } ///< Copiador usado al insertar en el contenedor.
00124     friend class TestCase; ///< Caso de prueba.
00125     template <class TestCase> friend void do_toXML( const TestCase * tc , std::basic_ostringstream<char> & ost );
00126     template <class TestCase> friend void do_toString( const TestCase * tc , std::basic_ostringstream<char> & ost );
00127 }; // TestCaseError
00128 
00129 /// Cada caso de prueba es una instancia derivada de esta clase abstracta.
00130 /// - Siempre es obligatorio implementar \c TestCase::run().
00131 class TestCase {
00132 protected:
00133     int m_pass; ///< Cantidad de pruebas exitosas
00134     int m_error; ///< Cantidad de pruebas que han producido error
00135     const char * m_name; ///< Nombre del caso de prueba
00136     bool m_test_suite_destroy; ///< Indica si la prueba está en memoria dinámica.
00137     /// Contenedor para registrar las pruebas que han producido error.
00138     std::list<TestCaseError> m_errorList;
00139 public:
00140     TestCase(const char * name=0);
00141     virtual ~TestCase() { } ///< Destructor
00142     /// <strong>[virtual]</strong> ==> Ejecuta la prueba y retorna \c "false" si produce error.
00143     /// <strong>[***]</strong> Siempre es necesario redefinir el método \c run().
00144     /// \see runBare().
00145     virtual bool run() = 0;
00146     void runBare();
00147     bool Run()     { return run(); } ///< Sinónimo de \c run()
00148     bool runTest() { return run(); } ///< Sinónimo de \c run()
00149     virtual void setUp();
00150     virtual void tearDown();
00151     int  countTestCases() const { return 1; } ///< Cantidad de casos de prueba que serán ejecutados.
00152     /// Cantidad total de pruebas realizadas.
00153     /// - Sinónimo de <code>successCount()+errorCount()+failureCount()</code>.
00154     /// \see reset().
00155     int  runCount() const { return successCount()+errorCount(); }
00156     /// Cantidad de pruebas que han producido error. \see reset().
00157     virtual int errorCount() const { return m_error; }
00158     /// Siempre retorna \c 0 (cero): "Cantidad de fallas".
00159     /// - ADH_test no hace diferencia entre "errores" y "fallas"
00160     /// \see http://osdir.com/ml/java.junit.user/2002-06/msg00114.html
00161     int  failureCount() const { return 0; }
00162     virtual int successCount() const { return m_pass; } ///< Cantidad de pruebas exitosas. \see reset().
00163     /// Retorna \c "true" si todas las pruebas han sido exitosas.
00164     /// - Sinónimo de <code>(successCount() == runCount())</code>
00165     bool wasSuccessful() const { return successCount() == runCount(); }
00166     virtual void reset();
00167 public:
00168     /// Obtiene el nombre de la prueba. \see setName().
00169     std::string getName() const;
00170     void setName( const char * name=0 );
00171     virtual const std::string toString() const;
00172     virtual const std::string summary() const;
00173     virtual const std::string toXML() const;
00174     /// Retorna la hilera encabezado \c summary() seguido de errores \c toString().
00175     const std::string report() const { return summary() + '\n' + toString(); }
00176     const std::string errorString() const { return toString(); } ///< Sinónimo de \c toString()
00177     template <class T> static std::string toString( const T & val );
00178 protected:
00179     void recordSuccess() { ++m_pass; } ///< Registra como exitoso el resultado de una prueba
00180     void recordError( const char* label, const char* fname, int lineno, bool must_copy=false);
00181     void recordError( const std::string& label, const char* fname, int lineno );
00182     void testThis( bool cond, const std::string& label, const char* fname, long lineno);
00183     void testThis( bool cond, const char*        label, const char* fname, long lineno, bool must_copy=false);
00184     template <class TestCase> friend void do_toXML( const TestCase * tc , std::basic_ostringstream<char> & ost );
00185     template <class TestCase> friend void do_toString( const TestCase * tc , std::basic_ostringstream<char> & ost );
00186     template <class TestCase> friend class TestSuite; ///< Colección de pruebas.
00187     int  nPass()  const { return m_pass; }  ///< Sinónimo de \c successCount() [OBSOLETO] \deprecated
00188     int  nError() const { return m_error; } ///< Sinónimo de \c errorCount() [OBSOLETO] \deprecated
00189 private:
00190     virtual bool iAmTestSuite() const { return false; } ///< Retorna \c false para \c TestCase.
00191     TestCase(const TestCase&);            ///< \c "private" evita la copia de casos de prueba
00192     TestCase& operator=(const TestCase&); ///< \c "private" evita la copia de casos de prueba
00193     friend class test_ADH_test; ///< Clase de prueba para \c ADH_test.h
00194 }; // TestCase
00195 
00196 /// NO IMPLEMENTADO ==> Colección de pruebas.
00197 template <class TC> class TestSuite : public TestCase { };
00198 
00199 /** Constructor.
00200     - Si no se indica el nombre en \c "name", el nombre se obtiene con <code>typeid(*this).name()</code>.
00201 
00202     \dontinclude test_ADH_test.cpp
00203     \skipline    test::constructor()
00204     \until       }}
00205     \see         test_ADH_test::test_constructor()
00206 */
00207 inline TestCase::TestCase(const char * name) :
00208     m_pass(0), m_error(0), m_name(name), m_test_suite_destroy(false), m_errorList() { }
00209 
00210 /** Elimina todas las pruebas realizadas.
00211     - Anula los contadores de pruebas porque deja la clase en el estado
00212       inicial que tuvo al ser construida.
00213     - Borra el registro de pruebas no exitosas.
00214     - No borra el nombre de la prueba.
00215 
00216     \dontinclude test_ADH_test.cpp
00217     \skipline    test::reset()
00218     \until       }}
00219     \see         test_ADH_test::test_reset()
00220 */
00221 inline void TestCase::reset() {
00222     m_pass =  m_error = 0;
00223     m_errorList.clear();
00224 }
00225 
00226 inline std::string TestCase::getName() const {
00227     return ( m_name != 0 ? m_name : typeid(*this).name() );
00228 }
00229 
00230 /** Le cambia el nombre a la prueba.
00231     \dontinclude test_ADH_test.cpp
00232     \skipline    test::setName()
00233     \until       }}
00234     \see         test_ADH_test::test_setName()
00235 */
00236 inline void TestCase::setName( const char * name ) {
00237     m_name = name;
00238 }
00239 
00240 /** Ejecuta la prueba <code>setUp(); run(); tearDown();</code>.
00241     - A diferencia de \c run(), este método si establece el ambiente
00242       de prueba invocando \c setUp() y \c tearDown() antes y después
00243       de hacer la prueba.
00244 
00245     \dontinclude test_ADH_test.cpp
00246     \skipline    test::run()
00247     \until       }}
00248     \see         test_ADH_test::test_run()
00249 */
00250 inline void TestCase::runBare( ) { setUp(); run(); tearDown(); }
00251 
00252 /// Establece el ambiente para la ejecución de la prueba
00253 /// \see TestCase::setUp()
00254 typedef TestCase TestFixture;
00255 
00256 /** Establece el ambiente en que se realizará cada prueba.
00257     - Como \c TestCase::run() es un método abstracto,
00258       para facilitar la programación lo usual es que el
00259       programador no incluya invocaciones a
00260       \c TestCase::setUp() y \c TestCase::tearDown()
00261       pues es más simple dejar que lo haga
00262       \c TestSuite<TestCase>::runBare().
00263     - A diferencia de \c TestCase::runBare(), el método
00264       \c TestCase::run() no establece el ambiente de prueba
00265       porque no invoca ni a  \c TestCase::setUp() antes de
00266       la prueba ni a \c TestCase::tearDown() después .
00267     - \c TestSuite<TestCase>::runBare() invoca los métodos
00268       \c TestCase::setUp() y \c TestCase::tearDown()
00269       cuando ejecuta cada prueba.
00270     - Por eso, si el programador cliente quiere que cada
00271       prueba se ejecute luego de establecer el ambiente de
00272       la prueba, lo más práctico es que agregue sus
00273       pruebas a una colección de pruebas \c TestSuite para
00274       ejecutarlas con \c TestSuite<TestCase>::runBare().
00275 */
00276 inline void TestCase::setUp() { }
00277 
00278 /// Destruye el ambiente de prueba
00279 inline void TestCase::tearDown() {}
00280 
00281 /** Efectúa la prueba y registra el resultado.
00282     - Si la prueba es exitosa sólo incrementa la cantidad de éxitos \c successCount().
00283     - Si la prueba no tiene éxito reporta en \c toString()   el hecho.
00284     - La prueba es \c "cond".
00285     - Los valores \c "fname" y \c "lineno" indican el archivo y el renglón
00286       en donde se ejecuta la prueba.
00287     - Usualmente los valores de \c "fname" y \c "lineno" se obtienen con
00288       las macros globales \c "__FILE__" y \c "__LINE__".
00289     - El valor \c "must_copy" indica que es necesario hacer una copia de la
00290       hilera \c "label", copia que será destruida cuando el registro de
00291       pruebas no exitosas sea borrado.
00292     - En la mayor parte de los casos, la hilera \c "label" es una constante
00293       generada por el preprocesador al usar la macro \c \#cond y por eso su
00294       memoria no debe ser retornada.
00295 
00296     Este método es invocado usando la macro \c ADH_test_TEST().
00297     \dontinclude test_ADH_test.cpp
00298     \skipline    test::testThis()
00299     \until       }}
00300     \see         test_ADH_test::test_testThis()
00301 */
00302 inline void TestCase::testThis( bool cond, const char * label, const char* fname, long lineno, bool must_copy ) {
00303     if (cond) {
00304         recordSuccess();
00305     }
00306     else {
00307         recordError( label, fname, lineno, must_copy );
00308     }
00309 }
00310 
00311 inline void TestCase::testThis( bool cond, const std::string& label, const char* fname, long lineno ) {
00312     testThis( cond, label.c_str(), fname, lineno, true /* must_copy == true */ );
00313 } ///< Sinónimo de \c testThis();
00314 
00315 /** Registra que la prueba no tuvo éxito.
00316     - Los valores \c "fname" y \c "lineno" indican el archivo y el renglón
00317       en donde se ejecuta la prueba.
00318     - Usualmente los valores de \c "fname" y \c "lineno" se obtienen con
00319       las macros globales \c "__FILE__" y \c "__LINE__".
00320     - El valor \c "must_copy" indica que es necesario hacer una copia de la
00321       hilera \c "label", copia que será destruida cuando el registro de
00322       pruebas no exitosas sea borrado.
00323     - En la mayor parte de los casos, la hilera \c "label" es una constante
00324       generada por el preprocesador al usar la macro \c \#cond y por eso su
00325       memoria no debe ser retornada.
00326 
00327     Este método es invocado usando la macro \c ADH_test_ERROR().
00328 */
00329 inline void TestCase::recordError( const char* label, const char* fname, int lineno, bool must_copy ) {
00330     if ( must_copy ) {
00331         size_t len = strlen(label)+1;
00332         char* str = new char[ len ]; // hace la copia del mensaje de error
00333         memcpy( str, label, len );
00334         label = str;
00335     }
00336     m_errorList.push_back( TestCaseError ( fname, lineno, label, must_copy ) );
00337     m_error++;
00338 }
00339 
00340 /// Registra que la prueba no tuvo éxito.
00341 /// - En \c ADH_test.h no se hace diferencia entre "fallas" y "errores".
00342 inline void TestCase::recordError( const std::string& label, const char* fname, int lineno ) {
00343     recordError( label.c_str(), fname, lineno, true /* must_copy == true */ );
00344 /*  Nota: como aquí se obtiene memoria dinámica para "str" hay que marcar
00345     el campo "TestCase::m_destroy_label" con el valor "true" de manera
00346     que el destructor de "TestCaseError" retorne esa memoria.
00347 */
00348 }
00349 
00350 /** Hilera "enooorme" que contiene copia del registro de pruebas no exitosas, separados por \c "\n".
00351     \code
00352     =\_error: 1 == 0
00353     =/ (125) X:\DIR\SubDir\test_ADH_test.cpp
00354     =\_error: 4 == 0
00355     =/ (128) X:\DIR\SubDir\test_ADH_test.cpp
00356     \endcode
00357 */
00358 inline const std::string TestCase::toString() const {
00359 //  typedef basic_ostringstream<char> ostringstream;
00360     std::basic_ostringstream<char> ost; // ostringstream ost;
00361     do_toString( this , ost );
00362     return ost.str();
00363 }
00364 
00365 /// Le agrega a \c ost la hilera de todas las pruebas no exitosas de \c *tc.
00366 template <class TestCase>
00367 void do_toString( const TestCase * tc , std::basic_ostringstream<char> & ost ) {
00368     std::list<TestCaseError>::const_iterator it = tc->m_errorList.begin();
00369     for ( ; it != tc->m_errorList.end(); ++it) {
00370         ost << "=\\_error: " << it->m_label << " \n=/ ("
00371             << it->m_lineno << ") " << it->m_fname << "\n";
00372     }
00373     return;
00374 /*  NOTA
00375     La implementación de "TestCase::toString()" está hecha invocando esta
00376     función emplantillada para que sea el compilador el responsable de
00377     remover versiones duplicadas de esta misma rutina, las que se producen
00378     cuando este archivo de encabezado ("ADH_test.h") es incluido en varios
00379     archivos "*.cpp". Todo esto hay que hacerlo para que "ADH_test.h" quepa,
00380     completo, en un único archivo de encabezado.
00381 */
00382 }
00383 
00384 /** Hilera XML que contiene una copia de las pruebas no exitosas.
00385     \code
00386     <error file="X:\DIR\SubDir\test_ADH_test.cpp" line="125" message="1 == 0"/>
00387     <error file="X:\DIR\SubDir\test_ADH_test.cpp" line="128" message="4 == 0"/>
00388     \endcode
00389 */
00390 inline const std::string TestCase::toXML() const {
00391 //  typedef basic_ostringstream<char> ostringstream;
00392     std::basic_ostringstream<char> ost; // ostringstream ost;
00393     do_toXML( this , ost );
00394     return ost.str();
00395 }
00396 
00397 /// Le agrega a \c ost la hilera de todas las pruebas no exitosas de \c *tc en formato XML.
00398 template <class TestCase>
00399 void do_toXML( const TestCase * tc , std::basic_ostringstream<char> & ost ) {
00400     std::list<TestCaseError>::const_iterator it = tc->m_errorList.begin();
00401     for ( ; it != tc->m_errorList.end(); ++it ) {
00402         ost << "<error file=\"" << it->m_fname
00403             << "\" line=\"" << it->m_lineno
00404             << "\" message=\"" << it->m_label  << "\"/>" << std::endl;
00405     }
00406     return;
00407 /*  Nota:
00408     La implementación de "TestCase::toXML()" está hecha invocando a la
00409     función emplantillada "do_toXML()" para que el compilador se encargue
00410     de evitar la declaración múltiple que ocurre cuando "ADH_test.h" es
00411     incluido en varios archivos "*.cpp" diferentes en el mismo proyecto.
00412 */
00413 }
00414 
00415 /// [ADH_test] Macros propios de \c ADH_test.h
00416 #define TEST_ADH_test()
00417 #undef  TEST_ADH_test
00418 
00419 /** [ADH_test] Efectúa la prueba \c "cond y registra el resultado.
00420     - Es más elegante usar assertTrue() que hace lo mismo.
00421     - Si la prueba \c "cond" tiene éxito invoca el método
00422       \c TestCase::recordSuccess().
00423     - Si la prueba \c "cond" no tiene éxito invoca el método
00424       \c TestCase::recordError().
00425     - Esta es una una macro que invoca el método
00426       \c TestCase::testThis().
00427 
00428     \dontinclude test_ADH_test.cpp
00429     \skipline    test::ADH_test_macro()
00430     \until       }}
00431     \see         test_ADH_test::test_ADH_test_macro()
00432 */
00433 #define ADH_test_TEST(cond) testThis( cond, #cond, __FILE__, __LINE__ )
00434 
00435 /// [ADH_test] Macro similar a \c ADH_test_TEST() que usa el mensaje \c "msg".
00436 /// - El mensaje \c "msg" debe ser una hilera literal o un objeto que pueda
00437 ///   convertirse en <code>(const char *)</code>.
00438 #define ADH_test_TEST_Msg(msg, cond) testThis( cond, msg, __FILE__, __LINE__ )
00439 
00440 /** [ADH_test] Registra como "error" el resultado de una prueba.
00441     - El programador cliente es quien determinó que la prueba
00442       no tuvo éxito y por eso quiere registrar ese hecho.
00443     - Está implementado comun una macro que invoca
00444       el método \c TestCase::recordError().
00445 
00446     \see ADH_test_TEST()
00447     \code
00448     if (22==33) {
00449         ADH_test_ERROR("! (22==33)"); // Registra el error
00450     }
00451     \endcode
00452 */
00453 #define ADH_test_ERROR(msg) recordError( msg, __FILE__, __LINE__ )
00454 
00455 /** [ADH_test] Registra como "exitoso" el resultado de una prueba.
00456     - El programador cliente es quien determinó que la prueba
00457       fue exitosa y por eso quiere registrar ese hecho.
00458     - Generalmente se usa después de atrapar una excepción que
00459       se supone debió ser lanzada como resultado de la prueba.
00460     - Está implementado comun una macro que invoca
00461       el método \c TestCase::recordSuccess().
00462     \see ADH_test_TEST()
00463 */
00464 #define ADH_test_SUCCESS() recordSuccess()
00465 
00466 /// [ADH_test] Efectúa la prueba para determinar si <code>(expected == actual)</code>.
00467 /// - Si la prueba tiene éxito invoca el método
00468 ///   \c TestCase::recordSuccess().
00469 /// - Si la prueba no tiene éxito invoca el método
00470 ///   \c TestCase::recordError().
00471 /// - Esta es una una macro que invoca el método
00472 ///   \c TestCase::testThis().
00473 ///  \see ADH_test_TEST()
00474 #define ADH_test_EQUAL(expected, actual) \
00475         testThis( (expected) == (actual), #expected " == " #actual, __FILE__, __LINE__ )
00476 
00477 /// [ADH_test] Efectúa la prueba para determinar si <code>expected == actual</code>.
00478 /// - Si la prueba tiene éxito invoca el método
00479 ///   \c TestCase::recordSuccess().
00480 /// - Si la prueba no tiene éxito invoca el método
00481 ///   \c TestCase::recordError().
00482 /// - Esta es una una macro que invoca el método
00483 ///   \c TestCase::testThis().
00484 /// - Registra el mensaje \c "MSG" si la prueba no tiene éxito.
00485 /// \see ADH_test_TEST()
00486 #define ADH_test_EQUAL_Msg(MSG, expected, actual) \
00487         testThis( (expected) == (actual), MSG, __FILE__, __LINE__ )
00488 
00489 /// Retorna un hilera que contiene el nombre, cantidad de éxitos y cantidad de errores de la prueba.
00490 inline const std::string TestCase::summary() const {
00491     std::string res = "TestCase [" + getName() + ']';
00492     res += " (OK: "    + TestCase::toString( successCount() ) + ')';
00493     res += " (ERROR: " + TestCase::toString( errorCount() )   + ')';
00494     return res;
00495 }
00496 
00497 // ¿¿¿ TestSuite ???
00498 
00499 //inline bool check_ok<int>( const int & )      { return true; }
00500 //template<class unsigned> inline bool check_ok( const unsigned & ) { return true; }
00501 //template<class int> inline bool check_ok( const long & )     { return true; }
00502 //template<class int> inline bool check_ok( const flota   & )  { return true; }
00503 //template<class int> inline bool check_ok( const double & )   { return true; }
00504 
00505 template <class T> bool check_ok( const T& ); ///< Declaración genérica para \c check_ok()
00506 inline bool check_ok( const signed char &   ) { return true; } ///< \c check_ok<>()==true por defecto (por si el programador no lo ha implementado)
00507 inline bool check_ok( const unsigned char & ) { return true; } ///< \c check_ok<>()==true por defecto (por si el programador no lo ha implementado)
00508 inline bool check_ok( const signed int &    ) { return true; } ///< \c check_ok<>()==true por defecto (por si el programador no lo ha implementado)
00509 inline bool check_ok( const unsigned int&   ) { return true; } ///< \c check_ok<>()==true por defecto (por si el programador no lo ha implementado)
00510 inline bool check_ok( const signed long &   ) { return true; } ///< \c check_ok<>()==true por defecto (por si el programador no lo ha implementado)
00511 inline bool check_ok( const unsigned long & ) { return true; } ///< \c check_ok<>()==true por defecto (por si el programador no lo ha implementado)
00512 inline bool check_ok( const float &         ) { return true; } ///< \c check_ok<>()==true por defecto (por si el programador no lo ha implementado)
00513 inline bool check_ok( const double &        ) { return true; } ///< \c check_ok<>()==true por defecto (por si el programador no lo ha implementado)
00514 inline bool check_ok( const long double &   ) { return true; } ///< \c check_ok<>()==true por defecto (por si el programador no lo ha implementado)
00515 
00516 /// Retorna una hilera que contiene el valor de \c val.
00517 /// - \c toString() with standard C++
00518 template <class T>
00519 std::string TestCase::toString( const T & val ) {
00520 //  typedef basic_ostringstream<char> ostringstream;
00521     std::basic_ostringstream<char> temp; // ostringstream temp;
00522     temp << val;
00523     return temp.str( );
00524 }
00525 
00526 /// [CppUnit] Macros propios de \c CppUnit http://cppunit.sourceforge.net/doc/lastest
00527 #define CPPUNIT_ADH_test()
00528 #undef  CPPUNIT_ADH_test
00529 
00530 /// [CppUnit] Assertions that a condition is true.
00531 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga0
00532 #define CPPUNIT_ASSERT(condition) ADH_test_TEST(condition)
00533 
00534 /// [CppUnit] Assertion with a user specified message.
00535 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga1
00536 #define CPPUNIT_ASSERT_MESSAGE(message, condition) CPPUNIT_ASSERT(condition)
00537 
00538 /// [CppUnit] Fails with the specified message.
00539 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga2
00540 #define CPPUNIT_FAIL(message) ADH_test_ERROR(message)
00541 
00542 /// [CppUnit] Asserts that two values are equals.
00543 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga3
00544 #define CPPUNIT_ASSERT_EQUAL(expected, actual) ADH_test_EQUAL(expected, actual)
00545 
00546 /// [CppUnit] Asserts that two values are equals, provides additional messafe on failure.
00547 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga4
00548 #define CPPUNIT_ASSERT_EQUAL_MESSAGE(message, expected, actual) \
00549         ADH_test_EQUAL_Msg(message, expected, actual)
00550 
00551 /// [CppUnit] Macro for primitive value comparisons.
00552 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga5
00553 #define CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, actual, delta) \
00554         assertEquals_Delta(expected, actual, delta)
00555 
00556 /// [CppUnit] Asserts that the given expression throws an exception of the specified type.
00557 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga6
00558 #define CPPUNIT_ASSERT_THROW(expression, ExceptionType) \
00559         do {                                            \
00560             bool cpputExceptionThrown_ = false;         \
00561             try {                                       \
00562                 expression;                             \
00563             } catch ( const ExceptionType & ) {         \
00564                 cpputExceptionThrown_ = true;           \
00565             }                                           \
00566                                                         \
00567             if ( cpputExceptionThrown_ ) {              \
00568                 break;                                  \
00569             }                                           \
00570             ADH_test_ERROR(                                \
00571                 "Expected exception: " #ExceptionType ) \
00572         } while ( false )
00573 
00574 /// [CppUnit] Asserts that the given expression does not throw any exceptions.
00575 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga7
00576 #define CPPUNIT_ASSERT_NO_THROW(expression)                  \
00577         do {                                                 \
00578             try {                                            \
00579                 expression;                                  \
00580             } catch ( ... ) {                                \
00581                 ADH_test_ERROR("Unexpected exception caught");  \
00582             }                                                \
00583         } while ( false )
00584 
00585 /// [CppUnit] Asserts that an assertion fail.
00586 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga8
00587 #define CPPUNIT_ASSERT_ASSERTION_FAIL(assertion)               \
00588         CPPUNIT_ASSERT_THROW( assertion, CPPUNIT_NS::Exception )
00589 
00590 /// [CppUnit] Asserts that an assertion pass.
00591 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga9
00592 #define CPPUNIT_ASSERT_ASSERTION_PASS(assertion) \
00593         CPPUNIT_ASSERT_NO_THROW( assertion )
00594 
00595 // /// Concatena la hilera \c THIS con la hilera \c THAT
00596 // #define ADH_test_CAT( THIS, THAT ) (std::string(THIS) + std::string(THAT).c_str())
00597 
00598 #define JUnit_ADH_test()
00599 #undef  JUnit_ADH_test
00600 
00601 /// [JUnit] Macros propios de \c JUnit http://junit.sourceforge.net/javadoc/junit/framework/Assert.html
00602 ///  Asserts that two objects are equal.
00603 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertEquals(java.lang.Object,%20java.lang.Object)
00604 #define assertEquals(          EXPECTED, ACTUAL ) ADH_test_EQUAL(EXPECTED, ACTUAL)
00605 ///  Asserts that two objects are equal (with message).
00606 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertEquals(java.lang.String,%20java.lang.Object,%20java.lang.Object)
00607 #define assertEquals_Msg( MSG, EXPECTED, ACTUAL ) ADH_test_EQUAL_Msg(MSG, EXPECTED, ACTUAL)
00608 
00609 /// [JUnit] Asserts that a condition is true.
00610 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertTrue(boolean)
00611 #define assertTrue(           CONDITION ) testThis( CONDITION, #CONDITION, __FILE__, __LINE__ )
00612 /// [JUnit] Asserts that a condition is true (with message).
00613 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertTrue(java.lang.String,%20boolean)
00614 #define assertTrue_Msg( MSG,  CONDITION ) testThis( CONDITION,  MSG,       __FILE__, __LINE__ )
00615 
00616 /// [JUnit] Asserts that a condition is false.
00617 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertFalse(boolean)
00618 #define assertFalse(          CONDITION ) testThis( !(CONDITION), "!(" #CONDITION ")", __FILE__, __LINE__ )
00619 /// [JUnit] Asserts that a condition is false (with message).
00620 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertFalse(java.lang.String,%20boolean)
00621 #define assertFalse_Msg( MSG, CONDITION ) testThis( !(CONDITION),       MSG,           __FILE__, __LINE__ )
00622 
00623 #include <math.h> // fabs()
00624 /// [JUnit] Asserts that two doubles are equal concerning a delta.
00625 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertEquals(double,%20double,%20double)
00626 #define assertEquals_Delta(EXPECTED, ACTUAL, DELTA ) \
00627         testThis( fabs( double(EXPECTED) -  double(ACTUAL) ) < double(DELTA), \
00628         "|"  #EXPECTED "-" #ACTUAL "| < " #DELTA,  __FILE__, __LINE__ )
00629 
00630 /// [JUnit] Asserts that two doubles are equal concerning a delta (with message).
00631 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertEquals(java.lang.String,%20double,%20double,%20double)
00632 #define assertEquals_Delta_Msg( MSG, EXPECTED, ACTUAL, DELTA ) \
00633         testThis( fabs( double(EXPECTED) -  double(ACTUAL) ) < double(DELTA), \
00634         MSG, __FILE__, __LINE__ )
00635 
00636 /// [JUnit] Asserts that an object is null.
00637 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertNull(java.lang.Object)
00638 #define assertNull(OBJECT)    testThis( 0==&(OBJECT), "assertNull("    #OBJECT ")", __FILE__, __LINE__ )
00639 /// [JUnit] Asserts that an object isn't null.
00640 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertNotNull(java.lang.Object)
00641 #define assertNotNull(OBJECT) testThis( 0!=&(OBJECT), "assertNotNull(" #OBJECT ")", __FILE__, __LINE__ )
00642 
00643 /// [JUnit] Asserts that two objects refer to the same object.
00644 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertSame(java.lang.Object,%20java.lang.Object)
00645 #define assertSame(THIS, THAT) testThis(    &(THIS)==&(THAT), "assertSame("    #THIS ", " #THAT ")", __FILE__, __LINE__ )
00646 ///  Asserts that two objects do not refer to the same object.
00647 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertNotSame(java.lang.Object,%20java.lang.Object)
00648 #define assertNotSame(THIS, THAT) testThis( &(THIS)!=&(THAT), "assertNotSame(" #THIS ", " #THAT ")", __FILE__, __LINE__ )
00649 
00650 /// [JUnit] Fails a test with no message.
00651 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#fail()
00652 #define fail(     )     ADH_test_ERROR("ERROR")
00653 /// [JUnit] Fails a test with the given message.
00654 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#fail(java.lang.String)
00655 #define fail_Msg( MSG ) ADH_test_ERROR(MSG)
00656 
00657 #endif // ADH_test_h
00658 
00659 // EOF: ADH_test.h

Generado el Thu Nov 15 15:47:43 2007 para Clase ADH_Graph: por  doxygen 1.4.1
Hosted by www.Geocities.ws

1