Różnice między wybraną wersją a wersją aktualną.
Both sides previous revision Previous revision | Next revision Both sides next revision | ||
boosttest [2008/04/16 02:32] twroniak |
boosttest [2008/04/16 03:11] twroniak |
||
---|---|---|---|
Linia 193: | Linia 193: | ||
====Unit test framework ==== | ====Unit test framework ==== | ||
+ | |||
+ | <code cpp> | ||
+ | /******************************************************************************* | ||
+ | * Tomasz Wroniak G1ISI | ||
+ | * Boost.Test | ||
+ | * | ||
+ | * Biblioteka Boost.Test oferuje programiscie prosty i przystepny sposob na | ||
+ | * testowanie jego programow. Umozliwia tworzenie przypadkow testowych (test | ||
+ | * cases) i grupowanie ich w zetawy testowe (test suites) | ||
+ | * | ||
+ | *http://www.boost.org/libs/test for the library home page. | ||
+ | ******************************************************************************/ | ||
+ | |||
+ | //naglowek zawierajacy Unit Test Framework | ||
+ | #include <boost/test/unit_test.hpp> | ||
+ | //naglowek zawierajacy BOOST_CHECK_CLOSE | ||
+ | #include <boost/test/floating_point_comparison.hpp> | ||
+ | #include <boost/shared_ptr.hpp> | ||
+ | using namespace boost::unit_test; | ||
+ | |||
+ | /******************************************************************************* | ||
+ | // funkcja main nie jest dostarczana przez programiste, robi to za niego unit | ||
+ | // test framework. Programista musi zdefiniowac funkcje o naglowku | ||
+ | // boost::unit_test::test_suite* init_unit_test_suite ( int argc, char* argv[] ) | ||
+ | // (argc i argv sa parametrami wywolania, nie mozna ich pominac przy deklaracj, | ||
+ | // mozna je zignorowac piszac init_unit_test_suite ( int, char* [] ) ). | ||
+ | // Zadaniem tej funkcji jest inicjalizacja drzewa testowego, wartoscia zwracana | ||
+ | // powinien byc master test suite, czyli zbior wszystkich przypadkow tesotwych. | ||
+ | // w przypadku zwrocenia wartosci NULL testy nie beda wykonane, a program | ||
+ | // zakonczy sie zwroceniem boost::exit_test_failure | ||
+ | *******************************************************************************/ | ||
+ | |||
+ | /****************************************************************************** | ||
+ | * wartosci zwracane przez Unit Test Framework po zakonczeniu testow: | ||
+ | * boost::exit_success - wszystkie testy zakonczone pomyslnie | ||
+ | * boost::exit_test_failure - wykryto niekytyczne bledy (nonfatal errors) lub | ||
+ | * nie powiodla sie inicjalizacja unit test suite | ||
+ | * boost::exit_exception_failure - pojawily sie bledy krytyczne lub niezlapane | ||
+ | * wyjatki | ||
+ | ******************************************************************************/ | ||
+ | |||
+ | // przypadki testowe mozna rejestrowac na kilka roznych sposobow,najprostszym z | ||
+ | // nich jest na pewno automatycznie rejestrowana funkcja niezwiazana z zadna klasa | ||
+ | // rejestrujemy ja za pomoca jednego z magicznych makr boost.test | ||
+ | // w nawiasie podawana jest nazwa przypadku testowego | ||
+ | BOOST_AUTO_TEST_CASE( auto_test_case ) | ||
+ | { | ||
+ | /* makro to automatycznie tworzy obiekt function_test_case oraz umieszcza go w | ||
+ | globalnym zestawie testowym. Testowana funkcja jest wlasnie niniejsza funkcja:) | ||
+ | */ | ||
+ | |||
+ | // w ramach kazdego przypadku testowego mozemy sprawdzic dowolna ilosc warunkow | ||
+ | int i = 666; | ||
+ | |||
+ | |||
+ | // zostanie wygenerowany komunikat 'error in "auto_test_case": check i == 667 failed [666 != 667]' | ||
+ | BOOST_CHECK_EQUAL( i, 667 ); | ||
+ | |||
+ | // tym razem wynik testu bedzie poprawny, nie zotanie wygenerowany zaden komunikat | ||
+ | BOOST_CHECK( i == 666 ); | ||
+ | } | ||
+ | |||
+ | // automatycznie rejestrowane przypadki testowe mozna grupowac w zetawy testowe | ||
+ | BOOST_AUTO_TEST_SUITE( auto_test_suite ) | ||
+ | |||
+ | // ten przypadek testowy bedzie nalezal do auto_test_suite, a nie do globalnego zestawu | ||
+ | BOOST_AUTO_TEST_CASE( nonglobal_test ) | ||
+ | { | ||
+ | BOOST_CHECK_MESSAGE( 2+2 == 5, "ten komunikat bedzie wypisany zamiast zwyklego komunikatu o bledzie"); | ||
+ | |||
+ | double x = 1.000000, y = 1.000001; | ||
+ | double epsilon = 1e-6; | ||
+ | |||
+ | //sprawdzenie, czy dwie liczby roznia sie od siebie o nie wiecej niz zadana wartosc | ||
+ | BOOST_CHECK_CLOSE( x, y, epsilon ); | ||
+ | |||
+ | } | ||
+ | |||
+ | // automatyczne zestawy testowe mozna zagniezdzac | ||
+ | BOOST_AUTO_TEST_SUITE( internal_test_suite ) | ||
+ | |||
+ | BOOST_AUTO_TEST_CASE( internal_suite_test_case ) | ||
+ | { | ||
+ | |||
+ | BOOST_ERROR( "internal_suite_test_case_error" ); | ||
+ | |||
+ | } | ||
+ | |||
+ | BOOST_AUTO_TEST_SUITE_END() //zakonczenie internal_test_suite | ||
+ | |||
+ | BOOST_AUTO_TEST_SUITE_END() //zakonczenie auto_test_suite | ||
+ | |||
+ | // mozemy definiowac niezwiazane funkcje testujace, ktore nastepnie beda dodane zamienione | ||
+ | // na przypadki testowe w funkcji init_unit_test_suite | ||
+ | void free_test_function() | ||
+ | { | ||
+ | // wypisuje 'unknown location(0): fatal error in "free_test_function": memory access violation | ||
+ | // nazwapliku.cpp(numerLinii): last checkpoint' | ||
+ | int* p = (int*)0x01; | ||
+ | BOOST_CHECKPOINT( "Za chwile wystapi naruszenie ochrony pamieci" ); | ||
+ | //BOOST_CHECK( *p == 0 ); //wywolanie tej linijki spowoduje wystapienie fatalerror | ||
+ | // co z kolei spowoduje zakonczenie testow i wyjscie z programu | ||
+ | |||
+ | BOOST_CHECK( 2 == 1 ); | ||
+ | } | ||
+ | |||
+ | class KlasaTestujaca | ||
+ | { | ||
+ | int i; | ||
+ | public: | ||
+ | explicit KlasaTestujaca(int i_): i(i_) {} | ||
+ | |||
+ | void class_test_case() | ||
+ | { | ||
+ | BOOST_CHECK(2 == 1); | ||
+ | } | ||
+ | }; | ||
+ | //____________________________________________________________________________// | ||
+ | |||
+ | |||
+ | test_suite* | ||
+ | init_unit_test_suite( int, char* [] ) { | ||
+ | |||
+ | framework::master_test_suite().p_name.value = "Przykladowe test_suite"; | ||
+ | |||
+ | //jesli nie korzystamy z globalnego zestawu testow, mozemy definiowac wlasne | ||
+ | //za pomoca makra o nastepujacej skladni | ||
+ | //test_suite* test= BOOST_TEST_SUITE( "nazwa zestawu testow" ); | ||
+ | //wywolujac metode add(tak jak ponizej) mozemy dodawac przypadki testowe | ||
+ | //oraz nowe zestawy testow, ukladajac je w drzewiasta strukture | ||
+ | |||
+ | |||
+ | framework::master_test_suite().add( BOOST_TEST_CASE( &free_test_function ), 3 ); | ||
+ | boost::shared_ptr<KlasaTestujaca> instance( new KlasaTestujaca(0) ); | ||
+ | framework::master_test_suite().add( BOOST_CLASS_TEST_CASE( &KlasaTestujaca::class_test_case, instance ) ); | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </code> |