Narzędzia użytkownika

Narzędzia witryny


boosttest

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Previous revision
Next revision
Previous revision
boosttest [2008/04/16 02:00]
twroniak
boosttest [2008/04/16 23:00] (aktualna)
twroniak
Linia 1: Linia 1:
 +The acceptance test makes the customer satisfied that the\\
 +software provides the business value that makes them willing\\
 +to pay for it. The unit test makes the programmer satisfied\\
 +that the software does what the programmer thinks it does.\\
 +
 ===== Opis biblioteki ===== ===== 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 ====
 +
 +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> <code cpp>
Linia 34: Linia 40:
   
  int foo(3);  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 );  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( foo ) == 9 );
  BOOST_CHECK( square_err( foo ) == 9 );  BOOST_CHECK( square_err( foo ) == 9 );
Linia 65: Linia 77:
  
 ==== Program execution monitor ==== ==== 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> <code cpp>
Linia 79: Linia 93:
 } }
  
-int cube( int arg ) 
-{ 
- return arg*arg*arg;​ 
-} 
- 
-int cube_err( int arg ) 
-{ 
- return square_err( arg )*arg; 
-} 
  
 int cpp_main( int, char* [] ) //​zmieniona nazwa !!!!!! int cpp_main( int, char* [] ) //​zmieniona nazwa !!!!!!
Linia 108: Linia 113:
 } }
 </​code>​ </​code>​
 +
 +Program execution monitor posiada możliwość konfiguracji przez następujące zmienne środowiskowe:​
 +  * BOOST_TEST_CATCH_SYSTEM_ERRORS - pozwala wyłączyć przechwytywanie błędów systemowych,​ domyślnie ustawiona na "​yes"​
 +  * BOOST_PRG_MON_CONFIRM - domyślnie ustawiona na "​yes"​ powoduje wyświetlanie wiadomość potwierdzającą w przypadku pomyślnego zakończenia testów.
  
 ==== Execution monitor ==== ==== Execution monitor ====
 +
 +Execution monitor, czyli monitor wykonywania programu, jest jednym z niskopoziomowych elementów biblioteki Boost.Test, oraz stanowi bazę do implementacji pozostałych narzędzi przez nią oferowanych. Używany jako osobne narzędzie zapewnia monitorowane środowisko wykonywania programu oraz ujednoliconą obsługę błędów. Poniżej zaprezentowano jedną z ciekawszych jego cech, czyli rejestrowanie funkcji obsługujących własne wyjątki programisty.
  
 <code cpp> <code cpp>
Linia 189: Linia 200:
  
 ====Unit test framework ==== ====Unit test framework ====
 +
 +Unit test framework jest narzędziem oferującym programiście prosty i przystępny sposób na testowanie jego programów. Jest moim zdaniem najprzydatniejszym elementem biblioteki. Umożliwia tworzenie przypadków testowych testujących zarówno niezwiązane funkcje, jak i metody klas. Przypadki testowe (test cases) można grupować w zestawy testowe (test suites) tak, aby np. testy metod jednej klasy były zgrupowane w jednym zestawie.\\
 +\\
 +
 +Funkcja main nie jest dostarczana przez programistę,​ robi to za niego unit test framework. Programista musi zdefiniować funkcje o nagłówku boost::​unit_test::​test_suite* init_unit_test_suite ( int argc, char* argv[] )
 + (argc i argv są parametrami wywołania, nie można ich pominąć przy deklaracji, można je zignorować pisząc init_unit_test_suite ( int, char* [] ) ). Zadaniem tej funkcji jest inicjalizacja drzewa testowego, wartością zwracaną powinien być master test suite, czyli zbiór wszystkich przypadków testowych.
 +
 +<code cpp>
 +
 +//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;​
 +
 +/​******************************************************************************
 + * 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>​
 +
 +Jak łatwo zauważyć biblioteka ta w znacznym stopniu polega na prostych makrach opakowujących szablony. Skutkuje to niestety znacznym wydłużeniem kompilacji, która na słabszych komputerach (takich jak np. komputer autora:) ) może trwać na prawdę długo. Elegancję tak frywolnego użycia tak dużej ilości makr pozostawiam do oceny czytelnikowi.
 +
boosttest.1208304055.txt.gz · ostatnio zmienione: 2008/04/16 02:00 przez twroniak