2010-08-23 29 views
11

¿Cómo ejecuto una única prueba con UnitTest ++?¿Cómo ejecuto una única prueba con UnitTest ++?

Estoy ejecutando UnitTest ++ fuera de la caja como está. Mi función main se parece a:

int main() 
{ 
    printf("diamond test v0.1 %s\n\n",TIMESTAMP); 
    diamond::startup(); 
    UnitTest::RunAllTests(); 
    diamond::shutdown(); 
    printf("press any key to continue..."); 
    getc(stdin); 
} 

Para la depuración me gustaría escribir algo como UnitTest::RunSingleTests("MyNewUnitTest"); en lugar de UnitTest::RunAllTests();. ¿UnitTest ++ proporciona esa función y, de ser así, cuál es la sintaxis?

+1

Es necesario que nos dirá más acerca de su entorno, lo que ha intentado y ha fallado, etc. –

+0

Así que ya sabe cómo ejecutar dos pruebas ¿entonces? –

+0

Estoy ejecutando UnitTest ++ fuera de la caja como está.Mi función principal se ve así: int main() { \t \t printf ("prueba de diamante v0.1% s \ n \ n", __ TIMESTAMP__); \t diamond :: startup(); \t \t UnitTest :: RunAllTests(); \t \t diamond :: shutdown(); \t \t printf ("presione cualquier tecla para continuar ..."); \t getc (stdin); \t \t } para la depuración Me gustaría escribir algo así como \t unittest :: RunSingleTests ("MyNewUnitTest"); en lugar de \t UnitTest :: RunAllTests(); . Quería saber si existe tal tipo de función y, en caso afirmativo, cómo se ve la sintaxis. – Arno

Respuesta

12

intente esto como su main() para unittest (de hecho puse esto en un archivo y lo agregué a la biblioteca unittest, de modo que cuando se vincula a la biblioteca el ejecutable usa automáticamente main(). Muy conveniente.)

int main(int argc, char** argv) 
{ 
    if(argc > 1) 
    { 
     //if first arg is "suite", we search for suite names instead of test names 
    const bool bSuite = strcmp("suite", argv[ 1 ]) == 0; 

     //walk list of all tests, add those with a name that 
     //matches one of the arguments to a new TestList 
    const TestList& allTests(Test::GetTestList()); 
    TestList selectedTests; 
    Test* p = allTests.GetHead(); 
    while(p) 
    { 
     for(int i = 1 ; i < argc ; ++i) 
     if(strcmp(bSuite ? p->m_details.suiteName 
          : p->m_details.testName, argv[ i ]) == 0) 
      selectedTests.Add(p); 
     p = p->next; 
    } 

     //run selected test(s) only 
    TestReporterStdout reporter; 
    TestRunner runner(reporter); 
    return runner.RunTestsIf(selectedTests, 0, True(), 0); 
    } 
    else 
    { 
    return RunAllTests(); 
    } 
} 

invocar con argumentos para ejecutar una sola prueba:

> myexe MyTestName 

o única suite

> myexe suite MySuite 
+0

Esto es lo que estaba buscando. Muchas gracias. Voy a intentarlo de inmediato. – Arno

+0

¡Funciona perfecto! Muchas gracias ! – Arno

6

Esto es casi correcto. La "Prueba" en realidad está pensada como un nodo en una lista vinculada, por lo que cuando la agrega a una nueva lista, debe corregir el puntero para evitar incluir más pruebas de las previstas.

por lo que necesita para reemplazar

p = p->next; 

con

Test* q = p; 
    p = p->next; 
    q->next = NULL; 

Geoffrey

+0

Gracias Geoffrey !!! Este apéndice es de hecho una necesidad. La solución stijn no funciona sin esto. – Tarrasch

+0

¿Esta solución no desvincula efectivamente la lista de pruebas de UniTest ++? ¿UnitTest ++ utiliza algún otro medio para limpiar? – AngelGabriel

2

RunTestsIf sólo puede ejecutar un suite si usted le dice el nombre.

class MyTrue 
{ 
    public: 
     MyTrue(const std::string & suiteName, const std::string & testName) 
       : suite(suiteName), test(testName) {} 

     bool operator()(const UnitTest::Test* const testCase) const 
     { 
      return suite.compare(testCase->m_details.suiteName) == 0 && 
         test.compare(testCase->m_details.testName) == 0; 
     } 
    private: 
     std::string suite; 
     std::string test; 
}; 

int main (...) { 
    bool isSuite = false; 
    std::string suiteName = "suite01"; 
    std::string testName = "test01"; 

    UnitTest::TestReporterStdout reporter; 
    UnitTest::TestRunner runner(reporter); 
    if (isSuite) { 
     runner.RunTestsIf(UnitTest::Test::GetTestList(), 
      NULL, MyTrue(suiteName, testName), 0); 
    } else { 
     runner.RunTestsIf(UnitTest::Test::GetTestList(), 
      NULL, UnitTest::True(), 0); 
    } 
} 
1

Usted puede hacer esto mediante el parámetro de predicateRunTestsIf:

TestReporterStdout reporter; 
TestRunner runner(reporter); 
return runner.RunTestsIf(Test::GetTestList(), "MySuite", 
    [](Test* t) { 
     return strcmp(t->m_details.testName, "MyTest") == 0; 
    }, 0); 

Si usted no tiene suites, o si desea buscar todos ellos, se puede reemplazar con "MySuite"NULL.

1

La respuesta dada por @stijn tiene un error en la manipulación de la lista de prueba y, por lo tanto, generalmente ejecuta pruebas adicionales que no solicitó.

Este ejemplo utiliza un funcionador de predicados y también aprovecha la coincidencia de nombres de conjunto de aplicaciones integrada proporcionada por RunTestsIf. Es correcto y mucho más simple.

#include "UnitTest++.h" 
#include "TestReporterStdout.h" 
#include <string.h> 
using namespace UnitTest; 

/// Predicate that is true for tests with matching name, 
/// or all tests if no names were given. 
class Predicate 
{ 
public: 

Predicate(const char **tests, int nTests) 
    : _tests(tests), 
     _nTests(nTests) 
{ 
} 

bool operator()(Test *test) const 
{ 
    bool match = (_nTests == 0); 
    for (int i = 0; !match && i < _nTests; ++i) { 
     if (!strcmp(test->m_details.testName, _tests[i])) { 
      match = true; 
     } 
    } 
    return match; 
} 

private: 
    const char **_tests; 
    int _nTests; 
}; 

int main(int argc, const char** argv) 
{ 
    const char *suiteName = 0; 
    int arg = 1; 

    // Optional "suite" arg must be followed by a suite name. 
    if (argc >=3 && strcmp("suite", argv[arg]) == 0) { 
     suiteName = argv[++arg]; 
     ++arg; 
    } 

    // Construct predicate that matches any tests given on command line. 
    Predicate pred(argv + arg, argc - arg); 

    // Run tests that match any given suite and tests. 
    TestReporterStdout reporter; 
    TestRunner runner(reporter); 
    return runner.RunTestsIf(Test::GetTestList(), suiteName, pred, 0); 
} 
+0

Estoy de acuerdo: esta es una forma mucho mejor (¿probablemente la forma prevista?) Para seleccionar pruebas. Además, la solución anterior (stjin y Geoffrey) parece desvincular la lista de prueba de una manera que podría no ser segura. – AngelGabriel

0

La solución en la respuesta aceptada no funciona para mí. Cuando la primera prueba de la suite se carga en p, no pasa a la siguiente prueba (no sé exactamente por qué).

estoy usando Xcode y unittest ++ v1.4

#include "UnitTest++.h" 
#include "TestReporterStdout.h" 

#define SUITE_NAME "ActionFeedback" 

using namespace UnitTest; 

int main(int argc, char** argv) 
{ 
#ifdef SUITE_NAME 
    TestReporterStdout reporter; 
    TestRunner runner(reporter); 
    return runner.RunTestsIf(Test::GetTestList() , SUITE_NAME , True(), 0); 
#else 
    return RunAllTests(); 
#endif 

} 
Cuestiones relacionadas