przejście do zawartości
zpr c++ quick reference
Narzędzia użytkownika
Zarejestruj się!
Zaloguj
Narzędzia witryny
Narzędzia
Pokaż stronę
Poprzednie wersje
Odnośniki
Ostatnie zmiany
Menadżer multimediów
Indeks
Zaloguj
Zarejestruj się!
Ostatnie zmiany
Menadżer multimediów
Indeks
Ślad:
boosttest
Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić.
===== Opis biblioteki ===== Biblioteka Boost.Test dostarcza programiście zestaw narzędzi do testowania tworzonego przez niego oprogramowania. Mechanizmy dostarczane przez bibliotekę umożliwiają tworzenie programów testujących, definiowanie przypadków testowych i grupowanie ich w zestawy testów oraz uruchamianie testów w monitorowanym środowisku. ==== Minimal testing facility ==== Minimal testing facility, jak sama nazwa wskazuje, stanowi minimum mechanizmów umożliwiających testowanie oprogramowania. Pierwsza wersja Boost.Test zawierała jedynie prezentowaną w tym podrozdziale funkcjonalność. Minimal testing facility dostarcza własną funkcję main(), która uruchamia funkcję test_main(dostarczaną przez użytkownika) w monitorowanym środowisku. Biblioteka dba o to, aby wszystkie parametry uruchomienia programu zostały również przekazane do funkcji test_main(). <code cpp> #include <boost/test/minimal.hpp> #include <iostream> int square_err( int arg ) { return arg*arg-1; //blad gruby:) } int square( int arg ) { return arg*arg; } int cube( int arg ) { return arg*arg*arg; } int cube_err( int arg ) { return square_err( arg )*arg; } int test_main( int /*argc*/, char* /*argv*/[] ) //uwaga - zmieniona nazwa funkcji main { int foo(3); //w monitorowanym srodowisku uzyskujemy dostep do makr testujacych o wiele mowiacych nazwach //makro BOOST_REQUIRE przerywa testowanie w przypadku niespelnienia podanego mu warunku BOOST_REQUIRE( foo == 3 ); //za pomoca tego makra powinny byc wiec testowane warunki, ktorych spelnienie jest krytyczne dla //dalszego dzialania programu //BOOST_CHECK wypisuje informacje o bledzie na standardowe wyjscie po zakonczeniu testow BOOST_CHECK( square( foo ) == 9 ); BOOST_CHECK( square_err( foo ) == 9 ); BOOST_CHECK( cube( foo ) == 27 ); BOOST_CHECK( cube_err( foo ) == 27 ); if( foo != 4 ) BOOST_ERROR( "foo != 4 !!!!!" ); //ponizsze 3 sprawdzenia przy bledzie spowoduja przerwanie dalszego testowania if(cube( foo ) != 4 ) throw "cube(3) != 4"; //recznie wykryty blad, zglaszany poprzez wyjatek //ktory nie ma okazji byc zlapany if(cube( foo ) != 8 ) BOOST_FAIL("cube(3) != 8");//rowniez zglasza wyjatek BOOST_REQUIRE( foo == 4 ); //blad w BOOST_REQUIRE powoduje przerwanie testow std::cout << "Ten kod nigdy nie zostanie osiagniety\n"; return 0; } </code> ==== Program execution monitor ==== Kolejnym udostępnianym przez bibliotekę mechanizmem jest Program execution monitor. Podobnie jak minimal testing facility tworzy on monitorowane środowisko uruchomieniowe, w którym uruchamiany jest program użytkownika. Po zakończeniu testów użytkownikowi przedstawiany jest raport z przeprowadzonych testów, zawierający informacje o testach, które się nie powiodły oraz o wyjątkach, które zostały zgłoszone, ale nie zostały obsłużone. <code cpp> #include <boost/test/prg_exec_monitor.hpp> int square_err( int arg ) { return arg*arg-1; //blad gruby:) } int square( int arg ) { return arg*arg; } int cpp_main( int, char* [] ) //zmieniona nazwa !!!!!! { int foo(3); if( square( foo ) != 9 ) throw "square() error"; if( square_err( foo ) != 9) throw "square_err() error"; //niezlapany wyjatek, spowoduje wypisanie na konsole //komunikatu: exception: C string: square_err() error //aby uzyskac komunikat o bledzie nalezy wyrzucic jeden z nastepujacych typow: //ciag znakow w stylu C (NULL-terminated) //instancje std::string //std::exception lub dowolna klase pochodna return 1; } </code> Program execution monitor posiada możliwość konfiguracji przez następujące zmienne środowiskowe: * BOOST_TEST_CATCH_SYSTEM_ERRORS * BOOST_PRG_MON_CONFIRM ==== Execution monitor ==== <code cpp> #include <boost/test/prg_exec_monitor.hpp> #include <boost/test/execution_monitor.hpp> #include <boost/test/utils/basic_cstring/io.hpp> #include <iostream> struct NotImplementedYetException {}; struct DivisionByZeroException {}; namespace { class TestClass { int arg; public: TestClass( int a ): arg(a){} int operator() () { if( arg > 10 ) throw NotImplementedYetException(); if( arg == 0 ) throw DivisionByZeroException(); return 10/arg; } }; void translate_NotImplementedYetException( NotImplementedYetException const& ex ) { std::cout<< "tej funkcji jeszcze nie zaimplementowano\n"; } void translate_DivisionByZeroException( DivisionByZeroException const& ex ) { std::cout<< "wymuszenie dzielenia przez zero\n"; } } //zakonczenie lokalnej przestrzeni nazw int cpp_main( int /*argc*/, char* /*argv*/[]) { ::boost::execution_monitor monitor; //rejestrowanie funkcji tlumaczacych wyjatki //pozwalaja one na bezpiecznie przechwytywanie wyjatkow przez mechanizmy biblioteki w przypadku //gdy uzytkownik nie dostarczy kodu wylapujacego te wyjatki //zapobiega to normalnemu w takich wypadkach wyjsciu z programu oraz umozliwia //przejrzenie listy zgloszonych w ten sposob wyjatkow po zakonczeniu testow monitor.register_exception_translator<NotImplementedYetException>( &translate_NotImplementedYetException ); monitor.register_exception_translator<DivisionByZeroException>( &translate_DivisionByZeroException ); try { monitor.execute( ::boost::unit_test::callback0<int>( TestClass( 20 ) ) ); /* execution_monitor::execute( unit_test::callback0<int> const& F, bool catch_system_errors, int timeout ) F - funkcja przyjmujaca zero argumentow, rzucany jest wyjatek boost::execution_exception przy niezlapanym wyjatku, wystapieniu bledu systemowego (jesli catch_system_errors jest ustawiony na true) lub po okreslonym timeoucie */ } catch ( boost::execution_exception const& ex ) { std::cout << "Zlapano wyjatek: " << ex.what() << std::endl; } return 0; } </code> ====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>
boosttest.1208308280.txt.gz
· ostatnio zmienione: 2008/04/16 03:11 przez
twroniak
Narzędzia strony
Pokaż stronę
Poprzednie wersje
Odnośniki
Do góry