Unit Test

Non ho trovato niente di meglio come ambiente di testing per il C++ di CppUnit. Non che ne sia entusiasta, a dire il vero. Capisco che la reflection di Java sia un aiuto notevole per JUnit e che manchi qualcosa di simile per C++. C'é, é vero, la RTTI, ma si appoggia sulla vtable e quindi non é disponibile per tutte le classi C++, ed é inoltre molto rudimentale se paragonata alle funzionalità offerte dalla reflection di Java.

Però mi pare proprio che le varie soluzioni offerte per lo unit test in C++ siamo più farraginose di quello che potrebbero essere.

Ecco un esempio di testing per la classe Fibonacci, che ho mostrato nel post precedente:

#include <CppUnit/UI/Text/TestRunner.h>
#include <CppUnit/Extensions/HelperMacros.h>
#include "Fibonacci.h"

using namespace std;

class TestFibonacci : public CppUnit::TestFixture {
public:
void fib0() {
Fibonacci fib;
CPPUNIT_ASSERT(fib.get(0) == 0);
}

void fib1() {
Fibonacci fib;
CPPUNIT_ASSERT(fib.get(1) == 1);
}

void fib2() {
Fibonacci fib;
CPPUNIT_ASSERT(fib.get(2) == 1);
}

void fib20() {
Fibonacci fib;
CPPUNIT_ASSERT(fib.get(20) == 6765);
}

void fibX3() {
Fibonacci fib;
CPPUNIT_ASSERT(fib.get(2) == 1);
CPPUNIT_ASSERT(fib.get(20) == 6765);
CPPUNIT_ASSERT(fib.get(3) == 2);
}

CPPUNIT_TEST_SUITE(TestFibonacci);
CPPUNIT_TEST(fib0);
CPPUNIT_TEST(fib1);
CPPUNIT_TEST(fib2);
CPPUNIT_TEST(fib20);
CPPUNIT_TEST(fibX3);
CPPUNIT_TEST_SUITE_END();
};

CPPUNIT_TEST_SUITE_REGISTRATION(TestFibonacci);

void testFibonacci() {
CppUnit::TextUi::TestRunner runner;
CppUnit::TestFactoryRegistry ®istry =
CppUnit::TestFactoryRegistry::getRegistry();
runner.addTest(registry.makeTest());

runner.run("", false);
}

La classe TestFibonacci é una CppUnit::TestFixture che definisce le funzioni che verificano le funzionalità del codice relativo. La macro CPPUNIT_ASSERT si occupa di verificare che il valore risultante passatole sia true.

In coda alla classe una serie di macro creano la suite che raccoglie le funzioni che vogliamo includere nel testing. CPPUNIT_TEST_SUITE inizia il blocco, ricevendo in input il nome della classe, segue una CPPUNIT_TEST per ogni funzione da includere nella suite, e alla fine una CPPUNIT_TEST_SUITE_END completa la definizione della suite.

Dopo la creazione della classe, la macro CPPUNIT_TEST_SUITE_REGISTRATION si fa carico di registrare la suite in un registry apposito.

La funzione di test crea un runner (nel mio caso quello testuale) a cui viene aggiunto il test generato dal registry.

Resta da eseguire il testing usando il metodo run(), e guardare i risultati.

Nessun commento:

Posta un commento