Testowanie kodu gry w języku C++ za pomocą CPPUnit

Wielkość: px
Rozpocząć pokaz od strony:

Download "Testowanie kodu gry w języku C++ za pomocą CPPUnit"

Transkrypt

1 Testowanie kodu gry w języku C++ za pomocą CPPUnit Wojciech Toman

2 TESTOWANIE KODU GRY W JĘZYKU C++ ZA POMOCĄ CPPUNIT Jest duża różnica między kodem źródłowym, poprawnym kodem źródłowym i dobrym kodem źródłowym WSTĘP Błędy były, są i będą nieodłączną częścią programistycznego rzemiosła. Pojawiają się często w najmniej oczekiwanych momentach i w najmniej oczekiwanych miejscach kodu, przyczyniając się tym samym do frustracji zarówno końcowych użytkowników jak i próbujących je zlikwidować programistów i testerów. Idealnej recepty na ich eliminację nie ma i nigdy nie będzie. Istnieją jednak sposoby minimalizacji ryzyka ich wystąpienia, ograniczenia ich do takiego poziomu, że można je zaakceptować. Jedną z popularniejszych metod na przestrzeni ostatnich kilku lat są zautomatyzowane testy, a szczególnie tzw. unit-testy i testy funkcjonalne, które stanowią ważną część metodyk Agile 1. W tym artykule skupię się na tych pierwszych. Definicja 1 Test funkcjonalny (ang. functional test) test sprawdzający poprawność działania komponentów lub modułów aplikacji w rzeczywistej sytuacji oraz ich wzajemną współpracę. Przykładem testu funkcjonalnego może być sprawdzenie poprawności grafu sceny po dodaniu do niego nowego węzła za pomocą menedżera sceny. Unit-testy są testami sprawdzającymi poprawność działania kodu na poziomie najmniejszych jego autonomicznych jednostek, czyli pojedynczych funkcji 2, tu całkowicie wyrwanych z rzeczywistego kontekstu, w jakim zostaną użyte. Polegają one na przekazaniu do funkcji pewnego wejścia i przeanalizowaniu wyjścia. Wejście nie jest oczywiście przypadkowe bardzo często reprezentuje ono typową sytuację z jaką spotkamy się w grze. Jednak równie często (a nawet częściej) testowana jest sytuacja nietypowa, błędna taka jak np. zaalokowanie zbyt dużego bloku pamięci przez menedżera pamięci, czy próba otworzenia niepoprawnie zapisanego pliku poziomu. W takiej sytuacji nasz kod nadal powinien się zachowywać poprawnie: rzucając wyjątek, zgłaszając komunikat o błędzie, przyjmując wartości domyślne i ignorując nietypową sytuację lub w jeszcze inny sposób obsłużyć napotkany błąd. Definicja 2 Unit-testy są testami sprawdzającymi poprawność działania kodu na poziomie najmniejszych jego autonomicznych jednostek, czyli pojedynczych funkcji. Jeśli wyjście jest zgodne z oczekiwanym w danym przypadku wynikiem test zostaje zaliczony. W przeciwnym razie gratulacje! Właśnie znalazłeś błąd w swoim kodzie. Ważne jest to, że pojedynczy test wiele o poprawności kodu nam nie powie. Owszem, przekonamy się, że w danym przypadku kod działa zgodnie z oczekiwaniami. Ale jak zachowa się dla innych danych? Cóż recepta jest prosta. Należy napisać więcej testów. Ich liczba jest zależna od funkcji, którą poddajemy testowaniu. Co 1 Metodyki Agile są oparte na tzw. najlepszych praktykach tworzenia oprogramowania. Do ich upowszechnienia przyczyniło się w dużej mierze powstanie programowania ekstremalnego (XP) autorstwa Kenta Becka. Manifest metodyk Agile można znaleźć pod adresem: 2 Mimo że testy są prowadzone na poziomie funkcji różna jest definicja jednostki w zależności od przyjętego paradygmatu programowania. W programowaniu strukturalnym/proceduralnym jednostką jest funkcja, natomiast w programowaniu zorientowanym obiektowo klasa.

3 więcej czasem wcale nie trzeba pisać dziesiątek przypadków testowych wystarczy opracować kilka jak najlepszych tzn. mocno przemyślanych 3. Po pewnym czasie wyrobimy sobie swego rodzaju intuicję, dzięki czemu będziemy wiedzieli, że liczba określonych przez nas przypadków testowych w zupełności wystarczy do stwierdzenia, że kod jest poprawny. Definicja 3 Przypadek testowy (ang. test case) zbiór warunków i zmiennych pozwalający określić testującemu czy wymaganie poprawności testu zostało całkowicie lub częściowo spełnione. Przykładem przypadku testowego dla funkcji mnożenia macierzy, jest pomnożenie macierzy A przez macierz jednostkową I. Warunkiem zaliczenia testu jest otrzymanie w wyniku wywołania funkcji, macierzy A. Zaletą stosowania unit-testów jest to, że oszczędzają mnóstwo pracy zarówno programistom jak i zespołowi testującemu grę. Ten zaoszczędzony czas można wykorzystać na maksymalne dopracowanie gry pod kątem np. grywalności, efektów specjalnych, czy na podniesienie inteligencji aktorów AI. Ponadto pozwalają na przetestowanie kodu niższego poziomu, który ze względu na swój poziom komplikacji jest bardziej narażony na krytyczne dla poprawnego działania błędy (choćby wspomniane już błędy alokacji pamięci). Tego kodu testerzy w żaden sposób bezpośrednio nie sprawdzą, a zgłaszane przez nich objawy błędu wcale nie muszą doprowadzić nas do jego przyczyny. Prawdopodobnie spędzimy wiele godzin debugując kod, po czym okaże się, że błąd tkwi w zupełnie innym miejscu niż sądziliśmy. Ponadto starsze, tradycyjne metody testowania pod koniec produkcji gry sprawiały, że w przypadku znalezienia błędu na jego poprawienie było relatywnie niewiele czasu (większość zajmowała jego identyfikacja). Z wykorzystaniem unit-testów błąd jest znajdywany natychmiast. Może być też w związku z tym szybko poprawiony. Jakiś czas temu spotkałem się z zarzutem, że użycie unit-testów wymaga bardzo dużych zmian kodzie, aby wszystko co należy przetestować mogło w ogóle być przetestowane. Choć taka obawa jest uzasadniona, na szczęście nie jest to konieczne (choć i taka metoda jest jak najbardziej poprawna, a złamanie enkapsulacji faktycznie może okazać się konieczne). Możemy bowiem stworzyć framework do testów, który większość problemów pozwoli nam obejść. Stworzyć, lub jeszcze lepiej wykorzystać już istniejący. Teraz przechodzimy do bohatera tego artykułu, czyli CppUnit. Biblioteka ta, jedna z popularniejszych, powstała w oparciu o framework do testowania kodu Javy, o odkrywczej nazwie JUnit. CppUnit zaoszczędzi nam wiele pracy i ją ułatwi np. poprzez generowanie przejrzystych raportów z testów, z których szybko dowiemy się które testy nie zostały zaliczone, i w którym ich miejscu otrzymany wynik był niepoprawny. Korzystając z niego w najgorszym przypadku w niektórych klasach będziemy musieli dodać deklarację przyjaźni z klasą testu (o tym w dalszej części). Ma jednak jedną wadę - kompilacja jego niektórych części w darmowym VC++ Express może być problematyczna część projektów z solucji wymaga, bowiem do kompilacji bibliotek MFC i ATL, które są dostępne wyłącznie w wersjach od Professional włącznie. Na szczęście nie dotyczy to najważniejszych komponentów biblioteki, czyli tych odpowiedzialnych za tworzenie testów i ich uruchamianie. W dalszej części artykułu przedstawię proces tworzenia testów dla konkretnych klas gry i jej silnika. Jako zwolennik test-driven development uważam, że unit-testy powinny być tworzone przed napisaniem właściwego 3 Przykładowo zamiast dla funkcji sinus testować poprawność wyniku dla wartości kąta równej 45,567 stopni lepiej sprawdzić czy wartość będzie poprawna dla popularnych kątów lub upewnić się, że zawsze będzie należała do przedziału <-1; 1>.

4 kodu 4, listingi z samego kodu gry zostały pominięte, a wszelkie wątpliwości staram się wyjaśniać na bieżąco, m.in. w komentarzach do poszczególnych testów. W końcowej części artykułu postaram się przedstawić także garść porad dotyczących procesu testowania. Ponadto fakt, że przedstawiam tu konkretny framework, nie powoduje, że przedstawione techniki nie mogą być zastosowane w wypadku korzystania z innych rozwiązań. Większość z nich jest bowiem uniwersalna jedynie kod będzie wyglądał nieco inaczej. JAK ORGANIZOWAĆ TESTY Dobrą praktyką jest oddzielenie testów od kodu gry. Jest to o tyle dobre rozwiązanie, że jeśli tworzymy np. silnik graficzny, to prawdopodobnie nie mamy ochoty, udostępniać nikomu tego nadmiarowego kodu. Jeśli tworzymy grę nie mamy z kolei raczej ochoty na zbyt duże zwiększenie rozmiaru pliku wynikowego. Jednak najważniejsze jest to, że dzięki takiemu podejściu nie zmniejszamy czytelności kodu. Jeśli testujemy pewną klasę lub pewną konkretną funkcjonalność najlepiej wydzielić ze wszystkich przypadków testowych jej dotyczących osobną klasę 5. Idąc jeszcze dalej wszystkie testy można umieścić w osobnym projekcie. Taką klasę będącą zbiorem testów dotyczących pewnej funkcjonalności nazwiemy z języka angielskiego test suit. Definicja 4 Zbiór testów (ang. test suite) zbiór przypadków testowych sprawdzających poprawność konkretnego fragmentu funkcjonalności. W przypadku programowania zorientowanego obiektowo, zbiór testów będzie zwykle dotyczył jednej klasy. Ważne jest, aby testy uruchamiać dla każdej z konfiguracji. Może się bowiem okazać, że test zaliczony w konfiguracji Debug nie zostanie zaliczony w konfiguracji Release. Dlaczego? Z taką sytuacją wiąże się ściśle pojęcie heisenbug. Ogólnie mówiąc: po pierwsze w konfiguracji Debug do kodu jest dołączonych znacznie więcej informacji (które sprawiają, że niepoprawny kod może zachowywać się przez długi czas w porządku), a ponadto niektóre z optymalizacji z Release uwidaczniają nasze błędy. Definicja 5 Heisenbug (za Wikipedia) - błąd systemu, który wymyka się próbom wyizolowania warunków jego występowania, np. nie występuje lub zmienia swoje zachowanie w trakcie próby powtórzenia go w tych samych warunkach. Wspomniałem wcześniej o tym, że być może koniecznym stanie się złamanie enkapsulacji. W świetle tego, co przeczytałeś w tym podrozdziale powinno być już jasne dlaczego. Testy będą się odwoływać do metod testowanych obiektów. Zatem jedynym sposobem dostępu do metod prywatnych i chronionych jest zmiana ich zasięgu na publiczny bądź deklaracja przyjaźni z klasą testu. To drugie rozwiązanie wydaje się być bardziej eleganckie jednak wybór należy do Ciebie. PISZEMY TESTY 4 Takie podejście wywodzi się z tzw. Agile Methods [Toman01]. Powoduje ono, że programista znacznie dogłębniej zastanawia się nad kodem, który napisze, co przyczynia się do wzrostu jego jakości. 5 W CppUnit taka klasa nazywa się TestFixture niestety nie istnieje dobry polski odpowiednik dla tej nazwy.

5 W ramach tego rozdziału zajmiemy się następującymi klasami: klasą macierzy o wymiarach 4x4 o nazwie Matrix4 oraz klasą poziomu gry GameLevel. Dla każdej z nich określimy podstawową funkcjonalność, a następnie na tej podstawie stworzymy kilka przypadków testowych. Najpierw jednak przyjrzymy się, jak pisać testy przy pomocy CppUnit. Celem jest pokazanie praktycznego zastosowania unit-testów. JAK PISAĆ TESTY PRZY POMOCY CPPUNIT Oczywistym jest, że testy przy wykorzystaniu biblioteki CppUnit należy pisać w sposób z nią zgodny. W zasadzie są dwie metody, które różnią się zasadniczo ilością makr stosowanych w kodzie. Pierwsza z nich przedstawiona m.in. w [Madden01] prezentuje się w poniższy sposób: Listing 1 #include <cppunit/testfixture.h> #include <cppunit/testsuite.h> #include <cppunit/test.h> #include <cppunit/testcaller.h> #include <cppunit/testassert.h> class TestsMath: public CppUnit::TestFixture public: CPPUNIT_TEST_SUITE(TestsMaths); CPPUNIT_TEST(sineTest); CPPUNIT_TEST(cosineTest); CPPUNIT_TEST_SUITE_END(); float sinetest() float cosinetest() ; Zatrzymajmy się na chwilę w tym miejscu i przeanalizujmy powyższą definicję klasy TestsMaths. Jej przeznaczeniem jest przetestowanie funkcji matematycznych w naszej bibliotece. Aby klasa ta w ogóle mogła być potraktowana jako zbiór testów musi być dziedziczona z klasy TestFixture z biblioteki CppUnit 6. Makra CPPUNIT_TEST_SUITE i CPPUNIT_TEST_SUITE_END określają początek i koniec zbioru funkcji, opisujących przypadki testowe. Jedna uwaga odnośnie CPPUNIT_TEST_SUITE. Wyrażenie podane w nawiasie musi być nazwą typu dziedziczącego z TestFixture (prawdopodobnie będziesz chciał w tym miejscu umieścić nazwę klasy, którą właśnie definiujesz). 6 Możliwe jest też dziedziczenie z klasy Test będącej pojedynczym przypadkiem testowym. Aby skorzystać z tej metody należy później przeciążyć funkcję runtest() i umieścić w niej przypadek testowy.

6 Oprócz powyższego zapisu istnieje równoważny, w którym po prostu liczba makr została znacznie ograniczona: Listing 2 #include <cppunit/testfixture.h> #include <cppunit/testsuite.h> #include <cppunit/test.h> #include <cppunit/testcaller.h> #include <cppunit/testassert.h> class TestsMath: public CppUnit::TestFixture public: static CppUnit::Test* suite() CppUnit::TestSuite* suiteoftests = new CppUnit::TestSuite( TestsMaths ); CppUnit::TestCaller<TestsMaths>( sinetest, &TestsMaths::sineTest)); CppUnit::TestCaller<TestsMaths>( cosinetest, &TestsMaths::cosineTest)); return suiteoftests; float sinetest() ; float cosinetest() Jak widać największą różnicą w porównaniu do poprzedniego listing, jest rezygnacja z makr i dodanie statycznej metody o nazwie suite() zwracającej wskaźnik do obiektu Test. W jej ciele dodawane są wszystkie testy, poprzez utworzenie obiektu typu TestSuite i wywołanie na nim metody addtest(). Gdy teraz mamy już określone przypadki testowe, zobaczymy jak możemy określić czy dany test został zaliczony, czy też nie. Z pomocą przychodzi kilka użytecznych makr: CPPUNIT_ASSERT(warunek) tego makra będziesz prawdopodobnie używać najczęściej. Działa podobnie jak tradycyjne makro assert znane programistom C++. Jeśli warunek nie został spełniony, test zostaje nie zaliczony. CPPUNIT_ASSERT_MESSAGE(komunikat, warunek) podobnie jak powyższe, tyle że pozwala na określenie własnego komunikatu w przypadku niepowodzenia. CPPUNIT_ASSERT_THROW(wyrażenie, wyjątek) test zostaje zaliczony jeśli dla danego wyrażenia zostanie rzucony konkretny wyjątek. Makro to jest niezwykle przydatne do testowania nietypowych sytuacji. Ponadto biblioteka CppUnit definiuje takie makra jak: CPPUNIT_FAIL, CPPUNIT_ASSERT_EQUAL czy CPPUNIT_ASSERT_DOUBLES_EQUAL. Jednak ich praktyczne zastosowanie jest niewielkie. Zwykle będziesz się

7 prawdopodobnie ograniczać do CPPUNIT_ASSERT i CPPUNIT_ASSERT_THROW, gdyż wszystkie warunki są możliwe do określenia przy ich pomocy. Na koniec warto wspomnieć o dwóch funkcjach klasy TestFixture: setup() i teardown(). Pierwsza dokonuje inicjalizacji obiektów, z których będziemy korzystać w przypadkach testowych, a druga je zwalnia. Aby z nich skorzystać wystarczy je przeciążyć w swojej klasie. W kolejnych podrozdziałach tego artykułu zajmiemy się napisaniem prawdziwych testów. KLASA MATRIX4 Najpierw zastanówmy się, jaką funkcjonalność powinna zapewniać klasa macierzy. Ułatwi nam to jej gruntowne przetestowanie. Powinna pozwalać na: Tworzenie macierzy z tablicy 16 liczb zmiennoprzecinkowych dobrym testem czy macierz jest tworzona poprawnie jest podanie na wejściu 16 różnych liczb i sprawdzeniu, czy pojawiają się one w tych komórkach macierzy, do których mieliśmy je zamiar zapisać. Wystarczy jeden przypadek testowy, gdyż nie ma tu sytuacji nadzwyczajnych. Dodawanie macierzy w zasadzie jak wyżej, wystarczy sprawić, aby w każdej komórce macierzy wynikowej była inna wartość. Mnożenie macierzy o ile w zwykłym przypadku funkcja ta nie stanowi większego problemu, to już przy dodaniu optymalizacji pod SSE lub SSE2 jest możliwość, że błąd się pojawi. Poza mnożeniem dwóch dowolnych macierzy należy sprawdzić jak zachowa się mnożenie macierzy przez jej macierz odwrotną (powinno w wyniku dać macierz jednostkową) oraz przez macierz jednostkową (powinno dać macierz wejściową). Transponowanie macierzy Odwracanie macierzy należy sprawdzić jak zachowa się macierz, której wyznacznik jest równy 0 (macierz odwrotna wówczas nie istnieje). Liczenie wyznacznika Najpierw napiszmy definicję klasy TestMatrix4 dziedziczącej z CppUnit::TestFixture.

8 Listing 3 class TestMatrix4: public CppUnit::TestFixture public: TestMatrix4() ~TestMatrix4() void testcreation(); void testinvert(); void testdeterminant(); void testtranspose(); void testaddition(); void testmultiplication(); ; static CppUnit::Test* suite(); Poniżej natomiast znajduje się implementacja poszczególnych metod tej klasy. Wszystkie kroki staram się wytłumaczyć w komentarzach w kodzie: Listing 4 CppUnit::Test* TestMatrix4::suite() CppUnit::TestSuite* suiteoftests = new CppUnit::TestSuite( TestMatrix4 ); // Kolejno dodajemy wszystkie testy do zbioru testów. // W tym celu tworzymy nowy obiekt szablonowy TestCaller, // którego konstruktor przyjmuje za argumenty nazwę testu // oraz wskaźnik na funkcję będąca przypadkiem testowym CppUnit::TestCaller<TestMatrix4>( testcreation, &TestMatrix4::testCreation)); CppUnit::TestCaller<TestMatrix4>( testinvert, &TestMatrix4::testInvert)); CppUnit::TestCaller<TestMatrix4>( testdeterminant, &TestMatrix4::testDeterminant)); CppUnit::TestCaller<TestMatrix4>( testtranspose, &TestMatrix4::testTranspose)); CppUnit::TestCaller<TestMatrix4>( testaddition, &TestMatrix4::testAddition)); CppUnit::TestCaller<TestMatrix4>( testmultiplication, &TestMatrix4::testMultiplication)); return suiteoftests; void TestMatrix4::testCreation() // Niezwykle prosty przypadek testowy. Tworzymy macierz 4x4 typu // Matrix4, która w konstruktorze przyjmuje 16 liczb typu zmienno- // przecinkowego. Wystarczy zatem sprawdzić, czy wszystkie liczby // zostały wpisane we właściwych miejscach.

9 // W ten sam sposób można sprawdzić np. tworzenie macierzy // jednostkowej (wywołanie metody o nazwie identity() i sprawdzenie // zawartości poszczególnych pól macierzy). Matrix4 mat(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); CPPUNIT_ASSERT(mat._m11 == 1 && mat._m12 == 2 && mat._m13 == 3 && mat._m14 == 4 && mat._m21 == 5 && mat._m22 == 6 && mat._m23 == 7 && mat._m24 == 8 && mat._m31 == 9 && mat._m32 ==10 && mat._m33 ==11 && mat._m34 ==12 && mat._m41 ==13 && mat._m42 ==14 && mat._m43 ==15 && mat._m44 ==16); void TestMatrix4::testAddition() // Kolejny prosty test. Wystarczy dodać dwie macierze w taki sposób, // aby żadna wartość nie występowała w komórkach macierzy wynikowej // więcej niż raz. Matrix4 mat1(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); Matrix4 mat2(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); mat0 = add(mat1, mat2); // Zwróćmy uwagę na to, że tym razem nie podajemy tu konkretnej // macierzy, a wynik jej pomnożenia przez liczbę 2. Oczywiście // użycie takiej formy wymaga najpierw sprawdzenia poprawności // mnożenia macierzy przez liczbę rzeczywistą, jednak w tym artykule // test ten pomijamy. Sam fakt zastosowania tego typu sprawdzenia // wynika z faktu, że macierze wejściowe są sobie równe. CPPUNIT_ASSERT(mat0 == 2 * mat1); // Poniżej sprawdzamy inne sposoby wykonywania dodawania macierzy, // tj. Z wykorzystaniem przeciążonych operatorów. mat0 = mat1; mat0 += mat1; CPPUNIT_ASSERT(mat0 == 2 * mat1); mat0 = mat1 + mat2; CPPUNIT_ASSERT(mat0 == 2 * mat1); void TestMatrix4::testMultiplication() Matrix4 mat1(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); Matrix4 mat2; Matrix4 mat0; // Pomnożenie dowolnej macierzy przez macierz jednostkową powinno // zwrócić macierz wejściową. mat2.identity(); mat0 = mat1; mat0.multiply(mat2); CPPUNIT_ASSERT(mat0 == mat1); // Pomnożenie macierzy jednostkowej przez dowolną macierz powinno // zwrócić tę macierz. mat0 = mat2; mat0.multiply(mat1); CPPUNIT_ASSERT(mat0 == mat1); // Pomnożenie dowolnej macierzy przez jej macierz odwrotną powinno // zwrócić macierz jednostkową (przy założeniu, że macierz odwrotna // istnieje).

10 mat0 = mat1; mat2 = invert(mat1); mat0.multiply(mat2); CPPUNIT_ASSERT(mat0.isIdentity()); void TestMatrix4::testInvert() // Odwracamy macierze, które są odwracalne. Matrix4 mat(1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1); mat.invert(); CPPUNIT_ASSERT(mat == Matrix4(0.25, 0.25, 0.25, 0.25, 0.25, 0.25,-0.25,-0.25, 0.25,-0.25, 0.25,-0.25, 0.25,-0.25,-0.25, 0.25)); mat.set(1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1); mat.invert(); CPPUNIT_ASSERT(mat == Matrix4(1, 0, 0, 0, 1, 1, 1, -1, -1, -1, 0, 1, 0, 1, 0, 0)); // Sprawdzamy co się dzieje gdy macierz ma wyznacznik równy 0. // Przyjmijmy, że w wyniku tej operacji chcemy otrzymać macierz // wejściową. Matrix4 mat2(0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); mat = mat2; mat.invert(); CPPUNIT_ASSERT(mat == mat2); void TestMatrix4::testDeterminant() // Sprawdzamy poprawność liczenia wyznacznika. Matrix4 mat(2, -2, 0, 1, 0, -1, 0, 2, 0, 0, 3, 0, 0, 0, 0, 1); CPPUNIT_ASSERT(mat.determinant() == -6); mat.set(1, -2, 0, 1, 0, 0, 0, 2, -1, 0, 3, 0, 0, -1, 2, 0); CPPUNIT_ASSERT(mat.determinant() == -2); mat.set(0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); CPPUNIT_ASSERT(mat.determinant() == 0); void TestMatrix4::testTranspose() Matrix4 mat(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); mat.transpose(); CPPUNIT_ASSERT(mat == Matrix4(1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16)); To tyle na temat klasy macierzy. Oczywiście napisanie większej liczby testów może być uzasadnione, jednak na potrzeby tego artykułu te w zupełności wystarczą.

11 KLASA GAMELEVEL Klasa GameLevel będzie pozwalała na wczytywanie pliku poziomu zapisanego w formacie XML. W związku z tym większość testów powinna oscylować wokół sprawdzenia poprawności danych w nim zawartych. Sprawdzenia, czy tagi mają dopuszczalne wartości. Należy też przetestować co się stanie, gdy w pliku zabraknie krytycznych danych, takich jak np. dane o wersji pliku bądź pojawią się dane, z których nie korzystamy. Oczywiście można by powiedzieć, że takie testy nie mają sensu, gdyż zwykle do tworzenia poziomów wykorzystuje się i tak edytor, który zapisuje dane w odpowiednim formacie. Pojawia się jednak pewne ale: 1. Na początku produkcji prawdopodobnie edytor będzie w tak mało zaawansowanej wersji, że wiele osób będzie edytować plik ręcznie, w edytorze tekstu byle tylko móc stworzyć prototypy. O pomyłkę wówczas nietrudno, a szukanie buga, którego w rzeczywistości nie ma (wina leży tu po stronie nieuważnego użytkownika) jest na pewno niewdzięcznym i czasochłonnym zadaniem. 2. Edytor sam w sobie może zawierać błędy. Oczywiście jeśli to my za niego odpowiadamy powinniśmy go, w myśl tego artykułu, gruntownie przetestować. Zdarza się jednak, że wykorzystuje się gotowe narzędzia, których kodu przetestować nie możemy. Jeśli zawierają one jakiś błąd możemy się tylko przed nim zabezpieczyć. Zresztą nawet jeśli edytor jest autorstwa członka naszego zespołu to o ile nie jesteśmy w jego kierownictwie nie zmusimy nikogo do pisania unit-testów. Poniżej znajduje się definicja przypadków testowych dla klasy GameLevel. W tym przypadku nie umieszczam już definicji samej klasy, ani definicji metody suite(). Ponadto przedstawiam tylko testy dla funkcji wczytujących poziom. W innym przypadku ten artykuł musiałby być dużo dłuższy. Listing 5 void TestGameLevel::testCreation() // Na początek sprawdzamy, czy poziom jest wczytywany poprawnie, gdy // wczytujemy plik o poprawnym nagłówku: // autor, nazwa, wersja, plik do wczytania. // Oczekujemy, że sprawdzenie poprawności (metoda isvalid()) da // wartość pozytywną (true). LevelHeader header( author, level, 1.1, level.lvl ); GameLevel level; level.load(header); CPPUNIT_ASSERT(level.isValid()); CPPUNIT_ASSERT(level.getAuthor() == author ); CPPUNIT_ASSERT(level.getName() == level ); CPPUNIT_ASSERT(level.getVersion() == 1.1); CPPUNIT_ASSERT(level.getFileName() == level.lvl ); // Teraz sprawdzamy co się stanie, gdy w nagłówku zabraknie danych // opcjonalnych: autor i wersja. Oczekujemy, że zostaną zastosowane // wartości domyślne. LevelHeader header2; header2.name = level ; header2.file = level.lvl ; level.load(header2); CPPUNIT_ASSERT(level.isValid()); CPPUNIT_ASSERT(level.getAuthor() == DEFAULT_AUTHOR); CPPUNIT_ASSERT(level.getVersion() == DEFAULT_VERSION); CPPUNIT_ASSERT(level.getVersion() == 1.1);

12 CPPUNIT_ASSERT(level.getFileName() == level.lvl ); // Gdy nie zostaną podane wartości wymagane, poziom powinien mieć // status: nieprawidłowy funkcja isvalid() zwróci wartość false. LevelHeader header3; header3.author = author ; header3.name = level ; header3.version = 1.1; level.load(header3); CPPUNIT_ASSERT(level.isValid() == false); // Alteratywą dla powyższego rozwiązania będzie sprawdzenie rzucenia // wyjątku, typu Invalid_Header: // CPPUNIT_ASSERT_THROW(level.load(header3), Invalid_Header); URUCHAMIANIE TESTÓW Zatem mamy już napisane kilka testów, ale kompilacja źródeł nie powoduje wcale, że otrzymujemy ich wyniki. Nadal nie wiemy, które z nich zaliczyły, a które nie. Cała nasza praca poszła na marne? Na szczęście nie, ale faktycznie aby je zobaczyć należy najpierw testy uruchomić. Za uruchamianie testów są odpowiedzialne obiekty klasy TestRunner. Przed uruchomieniem testów należy je dodać wywołując metodę TestRunner::addTest(). Metoda ta przyjmuje za argument wskaźnik na obiekt typu Test (przypominam, że metoda suite() zwraca taki wskaźnik). Po dodaniu wszystkich testów wystarczy wywołać metodę TestRunner::run() i wszystko się wyjaśni. Poniżej znajduje się kod dla naszej sytuacji: Listing 6 int main() CppUnit::TextUi::TestRunner runner; runner.addtest(testgamelevel::suite()); runner.addtest(testmatrix4::suite()); runner.run(); RAPORTY Niezwykle przydatną cechą biblioteki CppUnit jest to, że pozwala ona na generowanie czytelnych raportów z przeprowadzonych testów. Wyczytamy z nich ile testów zostało przeprowadzonych, które nie zaliczyły, w którym miejscu testu wystąpił błąd. Najczytelniejszym wg mnie jest arkusz xmla. Za to w jaki sposób zostanie przedstawiony raport z testów odpowiada obiekt klasy Outputter (dla xml a będzie to XmlOutputter), któremu można przekazać do konstruktora strumień, do którego chcemy zapisać dane. Ustawienie danego wyjścia odbywa się poprzez wywołanie metody TextUi::TestRunner::setOutputter(). Kod w naszej sytuacji będzie wyglądał następująco: Listing 7 CppUnit::TextUi::TestRunner runner;

13 std::ofstream ofs( tests.xml ); CppUnit::XmlOutputter* xml = new CppUnit::XmlOutputter(&runner.result(), ofs); xml->setstylesheet( report.xsl ); runner.setoutputter(xml); runner.addtest(testgamelevel::suite()); runner.addtest(testmatrix4::suite()); runner.run(); W kolejnych wierszach tworzymy kolejno strumień, obiekt outputtera i przypisujemy mu wybrany arkusz styli. AUTOMATYZACJA Bardzo ważną kwestią w nowoczesnych metodach testowania kodu jest zagadnienie tzw. automatyzacji. Jakiś czas temu zauważono, że najlepiej byłoby gdyby testy uruchamiane były automatycznie co jakiś czas (np. przed umieszczeniem kodu w repozytorium SVN czy CVS, czy też raz na tydzień), dzięki czemu byłaby gwarancja, że wprowadzane zmiany nie zaburzają poprawności działania kodu. CppUnit udostępnia do tego celu odpowiednie narzędzie. Niestety należy ono do tych, których kompilacja w popularnym VC++ Express jest niemożliwa. Napisanie prostego narzędzia do tego celu choć specjalnie trudne nie jest, na pewno jest czasochłonne. Na szczęście VC++ udostępnia mechanizm Build-Events, który choć trochę może nam pomóc. W Post-Build Event dopisz: $(ConfigurationName)\Test.exe $(ConfigurationName)\tests.xml Te dwa proste wiersze spowodują, że testy zostaną uruchomione ilekroć zbudowany zostanie projekt z testami (a powinien być budowany zawsze), a do tego zostanie otwarty raport z ich działania. Proste i pożyteczne. PORADY Poniżej znajduje się kilka użytecznych rad dotyczących tworzenie unit-testów: Czego nie należy testować? o o Przede wszystkim nie należy testować kodu pochodzącego całkowicie z zewnątrz. Rozumiem przez to oczywiście wszelkie biblioteki, silniki, których nie napisaliśmy sami, a które wykorzystujemy w swojej grze. Przeważnie i tak nie mamy takiej możliwości, bo nie mamy dostępu do kodu źródłowego, ale ważniejsze jest to, że nigdy nie będziemy znali danej biblioteki tak dobrze jak jej twórcy. Zresztą z jakiego powodu mielibyśmy wyręczać w pracy innych programistów? Zwykle nie ma też potrzeby testowania akcesorów, podobnie jak nie ma ich sensu uwzględniać w diagramach UMLa. Niemniej nie jest to regułą i czasem należy postąpić inaczej. Analogiczna sytuacja występuje dla przeciążonych operatorów. Testując, należy mieć po prostu na uwadze, że błąd może się pojawić nawet w pozornie łatwej funkcji. Dobrym przykładem są tu klasy należące do bibliotek matematycznych. Prędzej czy później będziemy chcieli je pewnie zoptymalizować pod kątem SIMD. Wówczas ich kod znacznie się skomplikuje. Dzięki napisaniu testów będziemy mieli gwarancję, że ta zmiana nie zaburzy prawidłowego funkcjonowania kodu. Ponadto wykonywanie działań matematycznych np. na

14 kwaternionach jest samo w sobie na tyle skomplikowane, że nawet w nie-simdowej formie jest narażone na trudne do uchwycenia błędy. o Test nigdy nie powinien wychodzić poza obręb testowanej jednostki (funkcji/klasy). Jeśli w teście dochodzi do jakiejś interakcji z innymi jednostkami można tu już bowiem mówić o teście funkcjonalnym. Innymi słowy w podejściu obiektowym nie powinniśmy wywoływać metod należących do klas nie będących częścią zbioru testów. W podejściu strukturalnym funkcji. Unit-testy wskazują jedynie czy kod jest poprawny. Nie są jednak w żadnym stopniu zdolne udzielić nam odpowiedzi, czy ten kod jest rzeczywiście funkcjonalny czy grywalny - powiedzą nam, czy w wyniku trafienia przeciwnika odebrane zostało mu życie, ale nie powiedzą nam, czy liczba odebranych punktów życia ma jakikolwiek sens praktyczny. Unit-testy nie do tego zostały wymyślone! Wniosek stąd jest prosty nie możemy całkowicie zrezygnować z QA. Testy nie są nam też w stanie powiedzieć nic o wydajności aplikacji, ani wyłapać błędów prowadzących do jej zmniejszenia (mam tu na myśli np. wybór złego algorytmu czy struktury danych). Gdzie leży granica między unit-testami, a testami funkcjonalnymi? Zgodnie z tym co zostało powiedziane testy funkcjonalne sprawdzają poprawność oprogramowania na wyższym poziomie, na poziomie współpracy między jego poszczególnymi częściami. Teoria zatem brzmi niezwykle prosto i typowym przykładem testu funkcjonalnego może być następująca sytuacja. Tworzymy obiekt graficzny za pomocą menedżera siatek, po czym dodajemy go do grafu sceny poprzez menedżer sceny. Następnie sprawdzamy zawartość tego grafu. Jednak nie zawsze ta granica musi być tak oczywista, np. mnożenie macierzy 4x4 przez wektor 4- wymiarowy. Z jednej strony są to dwie oddzielne klasy opakowujące pewne określone operacje. Z drugiej, z logicznego punktu widzenia stanowią jeden rodzaj funkcjonalności (zwłaszcza, że wektor w algebrze liniowej jest niczym innym jak macierzą o jednym z wymiarów wynoszącym 1). Zatem tu w moim przekonaniu lepiej użyć unit-testów. Przy okazji chciałbym podkreślić, że tandem unit-testy + testy funkcjonalne jest znacznie silniejszą bronią w walce z błędami niż tylko jeden rodzaj testów! Teoretycznie często zaleca się, aby jeden przypadek testowy był jedną funkcją. Jednak od razu widać, że jeśli dla jednej tylko funkcji napiszemy kilka przypadków testowych to dla całej klasy takich funkcji może być kilkadziesiąt i więcej, co sprawia, że kod testów staje się mało przejrzysty. Warto zatem wszystkie powiązane ze sobą przypadki testowe (np. pogrupowane pod kątem funkcji, których dotyczą) umieścić razem tj. w jednej funkcji testującej. Często nie jesteśmy w stanie jednoznacznie podać rezultatu jakiego oczekujemy od funkcji, lub dopuszczamy pewien margines błędu. Taka sytuacja może mieć miejsce np. w przypadku obliczeń na liczbach zmiennoprzecinkowych, bądź wykorzystywania stablicowanych wartości dla funkcji trygonometrycznych. Opłaca się wówczas wykorzystać pewne własności funkcji i to je testować. Przykładem może być badanie wyjścia funkcji sinus. Na wejściu możemy podać losowe kąty 7 i 7 Ze stosowaniem losowych testów należy bardzo uważać, bo nie mamy nad nimi pełnej kontroli. Z jednej strony mamy znacznie więcej przypadków testowych niż określilibyśmy ręcznie. Z drugiej może się zdarzyć tak, że będą one należały do określonego przedziału, tym samym pozostawiając nieprzetestowanym inne przedziały. Jednak istnieje możliwość określenia pewnych reguł generowania przypadków testowych. Takie

15 sprawdzić czy zawsze wynik jest większy równy od -1 i mniejszy równy od 1. Dla małych kątów możemy natomiast sprawdzić czy wartość sinusa jest w przybliżeniu równa samej wartości kąta. PODSUMOWANIE Podsumowując należy jeszcze raz podkreślić, że nawet unit-testy (czy jakiekolwiek inne testy) nie uchronią cię całkowicie przed błędami. Nadal będą się one pojawiać, choć z dużym prawdopodobieństwem w znacznie mniejszych ilościach. Unit-testy mogą nam oszczędzić wielu problemów, jest to jak napisał Blake Madden automatyczny debugger, który większość pracy wykonuje za nas. Niestety, mimo ich niewątpliwych zalet mają pewne problemy, aby zagościć na poważnie w przemyśle gier wideo. Dlaczego? Nie wiem sam szukam na to pytanie odpowiedzi i jak na razie jej nie znajduję. Niemniej zachęcam wszystkich do ich testowania. Niech nasze gry mają jak najmniej błędów! I na koniec jeszcze jedno zdanie: BIBLIOGRAFIA Błędny test jest gorszy niż jego brak [CppUnit01] Dokumentacja biblioteki CppUnit, dostępna online na [Madden01] Madden Blake, Using CppUnit to Implement Unit Testing, Games Programming Gems 6, Charles River Media [Toman01] Toman Wojciech, Sport dla programistów, czyli programowanie ekstremalne, dostępny online na podejście prowadzi do jeszcze większej automatyzacji procesu testowania, przy zachowaniu przynajmniej częściowej kontroli nad postacią przypadków testowych.

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1 Podstawy programowania. Wykład Funkcje Krzysztof Banaś Podstawy programowania 1 Programowanie proceduralne Pojęcie procedury (funkcji) programowanie proceduralne realizacja określonego zadania specyfikacja

Bardziej szczegółowo

Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu.

Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu. Zrozumienie funkcji danych statycznych jest podstawą programowania obiektowego. W niniejszym artykule opiszę zasadę tworzenia klas statycznych w C#. Oprócz tego dowiesz się czym są statyczne pola i metody

Bardziej szczegółowo

Czym są właściwości. Poprawne projektowanie klas

Czym są właściwości. Poprawne projektowanie klas Z akcesorów get i set korzysta każdy kto programuje w C#. Stanowią one duże udogodnienie w programowaniu obiektowym. Zapewniają wygodę, bezpieczeństwo i znacząco skracają kod. Akcesory są ściśle związane

Bardziej szczegółowo

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main. Część XVI C++ Funkcje Jeśli nasz program rozrósł się już do kilkudziesięciu linijek, warto pomyśleć o jego podziale na mniejsze części. Poznajmy więc funkcje. Szybko się przekonamy, że funkcja to bardzo

Bardziej szczegółowo

Podczas dziedziczenia obiekt klasy pochodnej może być wskazywany przez wskaźnik typu klasy bazowej.

Podczas dziedziczenia obiekt klasy pochodnej może być wskazywany przez wskaźnik typu klasy bazowej. Polimorfizm jest filarem programowania obiektowego, nie tylko jeżeli chodzi o język C++. Daje on programiście dużą elastyczność podczas pisania programu. Polimorfizm jest ściśle związany z metodami wirtualnymi.

Bardziej szczegółowo

Rozdział 4 KLASY, OBIEKTY, METODY

Rozdział 4 KLASY, OBIEKTY, METODY Rozdział 4 KLASY, OBIEKTY, METODY Java jest językiem w pełni zorientowanym obiektowo. Wszystkie elementy opisujące dane, za wyjątkiem zmiennych prostych są obiektami. Sam program też jest obiektem pewnej

Bardziej szczegółowo

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut.

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut. Konstruktory Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut. Rozpatrzmy przykład przedstawiający klasę Prostokat: class

Bardziej szczegółowo

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost; Klasy w C++ są bardzo ważnym narzędziem w rękach programisty. Klasy są fundamentem programowania obiektowego. Z pomocą klas będziesz mógł tworzyć lepszy kod, a co najważniejsze będzie on bardzo dobrze

Bardziej szczegółowo

Automatyzacja testowania oprogramowania. Automatyzacja testowania oprogramowania 1/36

Automatyzacja testowania oprogramowania. Automatyzacja testowania oprogramowania 1/36 Automatyzacja testowania oprogramowania Automatyzacja testowania oprogramowania 1/36 Automatyzacja testowania oprogramowania 2/36 Potrzeba szybkich rozwiązań Testowanie oprogramowania powinno być: efektywne

Bardziej szczegółowo

1 Podstawy c++ w pigułce.

1 Podstawy c++ w pigułce. 1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,

Bardziej szczegółowo

Szablony funkcji i klas (templates)

Szablony funkcji i klas (templates) Instrukcja laboratoryjna nr 3 Programowanie w języku C 2 (C++ poziom zaawansowany) Szablony funkcji i klas (templates) dr inż. Jacek Wilk-Jakubowski mgr inż. Maciej Lasota dr inż. Tomasz Kaczmarek Wstęp

Bardziej szczegółowo

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie? 1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie? a) konstruktor b) referencje c) destruktor d) typy 2. Które z poniższych wyrażeń są poprawne dla klasy o nazwie

Bardziej szczegółowo

Wykład 8: klasy cz. 4

Wykład 8: klasy cz. 4 Programowanie obiektowe Wykład 8: klasy cz. 4 Dynamiczne tworzenie obiektów klas Składniki statyczne klas Konstruktor i destruktory c.d. 1 dr Artur Bartoszewski - Programowanie obiektowe, sem. 1I- WYKŁAD

Bardziej szczegółowo

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie. Część XXII C++ w Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie. Ćwiczenie 1 1. Utwórz nowy projekt w Dev C++ i zapisz go na

Bardziej szczegółowo

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018 Informatyka I Klasy i obiekty. Podstawy programowania obiektowego dr inż. Andrzej Czerepicki Politechnika Warszawska Wydział Transportu 2018 Plan wykładu Pojęcie klasy Deklaracja klasy Pola i metody klasy

Bardziej szczegółowo

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu. Część XIX C++ w Każda poznana do tej pory zmienna może przechowywać jedną liczbę. Jeśli zaczniemy pisać bardziej rozbudowane programy, okaże się to niewystarczające. Warto więc poznać zmienne, które mogą

Bardziej szczegółowo

TEMAT : KLASY DZIEDZICZENIE

TEMAT : KLASY DZIEDZICZENIE TEMAT : KLASY DZIEDZICZENIE Wprowadzenie do dziedziczenia w języku C++ Język C++ możliwa tworzenie nowej klasy (nazywanej klasą pochodną) w oparciu o pewną wcześniej zdefiniowaną klasę (nazywaną klasą

Bardziej szczegółowo

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji. JAVA Java jest wszechstronnym językiem programowania, zorientowanym obiektowo, dostarczającym możliwość uruchamiania apletów oraz samodzielnych aplikacji. Java nie jest typowym kompilatorem. Źródłowy kod

Bardziej szczegółowo

Wyszukiwanie binarne

Wyszukiwanie binarne Wyszukiwanie binarne Wyszukiwanie binarne to technika pozwalająca na przeszukanie jakiegoś posortowanego zbioru danych w czasie logarytmicznie zależnym od jego wielkości (co to dokładnie znaczy dowiecie

Bardziej szczegółowo

Liczby losowe i pętla while w języku Python

Liczby losowe i pętla while w języku Python Liczby losowe i pętla while w języku Python Mateusz Miotk 17 stycznia 2017 Instytut Informatyki UG 1 Generowanie liczb losowych Na ogół programy są spójne i prowadzą do przewidywanych wyników. Czasem jednak

Bardziej szczegółowo

Podstawy Programowania Obiektowego

Podstawy Programowania Obiektowego Podstawy Programowania Obiektowego Wprowadzenie do programowania obiektowego. Pojęcie struktury i klasy. Spotkanie 03 Dr inż. Dariusz JĘDRZEJCZYK Tematyka wykładu Idea programowania obiektowego Definicja

Bardziej szczegółowo

Laboratorium Informatyka (I) AiR Ćwiczenia z debugowania

Laboratorium Informatyka (I) AiR Ćwiczenia z debugowania Laboratorium Informatyka (I) AiR Ćwiczenia z debugowania Krzysztof Kluza, Janusz Miller 1 Debugowanie Debugowanie, czy też po polsku odpluskiwanie, to proces polegający na kontrolowanym wykonaniu programu

Bardziej szczegółowo

Programowanie strukturalne i obiektowe. Funkcje

Programowanie strukturalne i obiektowe. Funkcje Funkcje Często w programach spotykamy się z sytuacją, kiedy chcemy wykonać określoną czynność kilka razy np. dodać dwie liczby w trzech miejscach w programie. Oczywiście moglibyśmy to zrobić pisząc trzy

Bardziej szczegółowo

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie Część X C++ Typ znakowy służy do reprezentacji pojedynczych znaków ASCII, czyli liter, cyfr, znaków przestankowych i innych specjalnych znaków widocznych na naszej klawiaturze (oraz wielu innych, których

Bardziej szczegółowo

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania Celem ćwiczenia jest zapoznanie studentów z najprostszą dynamiczną strukturą

Bardziej szczegółowo

Wyjątki (exceptions)

Wyjątki (exceptions) Instrukcja laboratoryjna nr 6 Programowanie w języku C 2 (C++ poziom zaawansowany) Wyjątki (exceptions) dr inż. Jacek Wilk-Jakubowski mgr inż. Maciej Lasota dr inż. Tomasz Kaczmarek Wstęp Wyjątki (ang.

Bardziej szczegółowo

7. Pętle for. Przykłady

7. Pętle for. Przykłady . Pętle for Przykłady.1. Bez użycia pętli while ani rekurencji, napisz program, który wypisze na ekran kolejne liczby naturalne od 0 do pewnego danego n. 5 int n; 6 cin >> n; 8 for (int i = 0; i

Bardziej szczegółowo

Programowanie obiektowe

Programowanie obiektowe Programowanie obiektowe Laboratorium 1. Wstęp do programowania w języku Java. Narzędzia 1. Aby móc tworzyć programy w języku Java, potrzebny jest zestaw narzędzi Java Development Kit, który można ściągnąć

Bardziej szczegółowo

REFERAT PRACY DYPLOMOWEJ

REFERAT PRACY DYPLOMOWEJ REFERAT PRACY DYPLOMOWEJ Temat pracy: Projekt i implementacja środowiska do automatyzacji przeprowadzania testów aplikacji internetowych w oparciu o metodykę Behavior Driven Development. Autor: Stepowany

Bardziej szczegółowo

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec PROE wykład 3 klasa string, przeciążanie funkcji, operatory dr inż. Jacek Naruniec Przypomnienie z ostatnich wykładów Konstruktory/destruktory i kolejność ich wywołania w złożonej klasie. Referencja Obiekty

Bardziej szczegółowo

Zadanie nr 2: Arytmetyka liczb zespolonych

Zadanie nr 2: Arytmetyka liczb zespolonych Zadanie nr 2: Arytmetyka liczb zespolonych 1 Cel ćwiczenia Wykształcenie umiejętności definiowania przeciążeń operatorów arytmetycznych dwuargumentowych i jednoargumentowych dla własnych struktur danych

Bardziej szczegółowo

Programowanie i techniki algorytmiczne

Programowanie i techniki algorytmiczne Temat 2. Programowanie i techniki algorytmiczne Realizacja podstawy programowej 1) wyjaśnia pojęcie algorytmu, podaje odpowiednie przykłady algorytmów rozwiązywania różnych 2) formułuje ścisły opis prostej

Bardziej szczegółowo

Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody

Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody Obiektowy PHP Czym jest obiekt? W programowaniu obiektem można nazwać każdy abstrakcyjny byt, który programista utworzy w pamięci komputera. Jeszcze bardziej upraszczając to zagadnienie, można powiedzieć,

Bardziej szczegółowo

Jeśli chcesz łatwo i szybko opanować podstawy C++, sięgnij po tę książkę.

Jeśli chcesz łatwo i szybko opanować podstawy C++, sięgnij po tę książkę. Języki C i C++ to bardzo uniwersalne platformy programistyczne o ogromnych możliwościach. Wykorzystywane są do tworzenia systemów operacyjnych i oprogramowania użytkowego. Dzięki niskiemu poziomowi abstrakcji

Bardziej szczegółowo

Języki i techniki programowania Ćwiczenia 2

Języki i techniki programowania Ćwiczenia 2 Języki i techniki programowania Ćwiczenia 2 Autor: Marcin Orchel Spis treści: Język C++... 5 Przekazywanie parametrów do funkcji... 5 Przekazywanie parametrów w Javie.... 5 Przekazywanie parametrów w c++...

Bardziej szczegółowo

1 Podstawy c++ w pigułce.

1 Podstawy c++ w pigułce. 1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,

Bardziej szczegółowo

Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR

Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR Zadanie polega na napisaniu pierwszego programu w języku C, jego poprawnej kompilacji i wgraniu na mikrokontroler. W tym celu należy zapoznać

Bardziej szczegółowo

Listy powiązane zorientowane obiektowo

Listy powiązane zorientowane obiektowo Listy powiązane zorientowane obiektowo Aby zilustrować potęgę polimorfizmu, przeanalizujmy zorientowaną obiektowo listę powiązaną. Jak zapewne wiesz, lista powiązana jest strukturą danych, zaprojektowaną

Bardziej szczegółowo

0 + 0 = 0, = 1, = 1, = 0.

0 + 0 = 0, = 1, = 1, = 0. 5 Kody liniowe Jak już wiemy, w celu przesłania zakodowanego tekstu dzielimy go na bloki i do każdego z bloków dodajemy tak zwane bity sprawdzające. Bity te są w ścisłej zależności z bitami informacyjnymi,

Bardziej szczegółowo

Kumulowanie się defektów jest możliwe - analiza i potwierdzenie tezy

Kumulowanie się defektów jest możliwe - analiza i potwierdzenie tezy Kumulowanie się defektów jest możliwe - analiza i potwierdzenie tezy Marek Żukowicz 14 marca 2018 Streszczenie Celem napisania artykułu jest próba podania konstruktywnego dowodu, który wyjaśnia, że niewielka

Bardziej szczegółowo

Java pierwszy program w Eclipse «Grzegorz Góralski strona własna

Java pierwszy program w Eclipse «Grzegorz Góralski strona własna Strona 1 z 9 «Przykładowe zadania do cz. III ćwiczeń z genetyki Java pierwsze kroki w programowaniu (01)» Kategoria: java, Tagi: eclipse - java - programowanie. Autor: Grzegorz, napisał dnia: February

Bardziej szczegółowo

Część 4 życie programu

Część 4 życie programu 1. Struktura programu c++ Ogólna struktura programu w C++ składa się z kilku części: część 1 część 2 część 3 część 4 #include int main(int argc, char *argv[]) /* instrukcje funkcji main */ Część

Bardziej szczegółowo

użytkownika 1 Jak wybrać temat pracy 2 Spis treści 3 Część pierwsza problematyka 4 Część druga stosowane metody 5 Część trzecia propozycja rozwiązania

użytkownika 1 Jak wybrać temat pracy 2 Spis treści 3 Część pierwsza problematyka 4 Część druga stosowane metody 5 Część trzecia propozycja rozwiązania 1 Jak wybrać temat pracy 2 Spis treści 3 Część pierwsza problematyka 4 Część druga stosowane metody 5 Część trzecia propozycja rozwiązania 6 Część czwarta dokumentacja techniczna i dokumentacja użytkownika

Bardziej szczegółowo

4. Funkcje. Przykłady

4. Funkcje. Przykłady 4. Funkcje Przykłady 4.1. Napisz funkcję kwadrat, która przyjmuje jeden argument: długość boku kwadratu i zwraca pole jego powierzchni. Używając tej funkcji napisz program, który obliczy pole powierzchni

Bardziej szczegółowo

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static), Tworzenie obiektów Dostęp do obiektów jest realizowany przez referencje. Obiekty w języku Java są tworzone poprzez użycie słowa kluczowego new. String lan = new String( Lancuch ); Obszary pamięci w których

Bardziej szczegółowo

Programowanie w języku C++ Grażyna Koba

Programowanie w języku C++ Grażyna Koba Programowanie w języku C++ Grażyna Koba Kilka definicji: Program komputerowy to ciąg instrukcji języka programowania, realizujący dany algorytm. Język programowania to zbiór określonych instrukcji i zasad

Bardziej szczegółowo

Szablony funkcji i szablony klas

Szablony funkcji i szablony klas Bogdan Kreczmer bogdan.kreczmer@pwr.wroc.pl Zakład Podstaw Cybernetyki i Robotyki Instytut Informatyki, Automatyki i Robotyki Politechnika Wrocławska Kurs: Copyright c 2011 Bogdan Kreczmer Niniejszy dokument

Bardziej szczegółowo

Wskaźnik może wskazywać na jakąś zmienną, strukturę, tablicę a nawet funkcję. Oto podstawowe operatory niezbędne do operowania wskaźnikami:

Wskaźnik może wskazywać na jakąś zmienną, strukturę, tablicę a nawet funkcję. Oto podstawowe operatory niezbędne do operowania wskaźnikami: Wskaźniki są nieodłącznym elementem języka C. W języku C++ także są przydatne i korzystanie z nich ułatwia pracę, jednak w odróżnieniu do C wiele rzeczy da się osiągnąć bez ich użycia. Poprawne operowanie

Bardziej szczegółowo

Zad. 5: Układ równań liniowych liczb zespolonych

Zad. 5: Układ równań liniowych liczb zespolonych Zad. 5: Układ równań liniowych liczb zespolonych 1 Cel ćwiczenia Wykształcenie zdolności abstrahowania operacji arytmetycznych od konkretnych typów. Unaocznienie problemów związanych z programowaniem uogólnionym

Bardziej szczegółowo

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut.

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut. Wyjątki Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut. Wydaje się, że żaden użytkownik oprogramowania nie lubi, kiedy stosowany program nagle zawiesza się,

Bardziej szczegółowo

Spis treści. Rozdział 1. Aplikacje konsoli w stylu ANSI C i podstawowe operacje w Visual C++... 7

Spis treści. Rozdział 1. Aplikacje konsoli w stylu ANSI C i podstawowe operacje w Visual C++... 7 Spis treści Wprowadzenie...n...n... 5 Jak korzystać z tej książki?...t... 6 Rozdział 1. Aplikacje konsoli w stylu ANSI C i podstawowe operacje w Visual C++... 7 Podsumowanie...t...t...15 Rozdział 2. Rozdział

Bardziej szczegółowo

Programowanie obiektowe - 1.

Programowanie obiektowe - 1. Programowanie obiektowe - 1 Mariusz.Masewicz@cs.put.poznan.pl Programowanie obiektowe Programowanie obiektowe (ang. object-oriented programming) to metodologia tworzenia programów komputerowych, która

Bardziej szczegółowo

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi EGZAMIN PIERWSZY (25 CZERWCA 2013) JĘZYK C++ poprawiam ocenę pozytywną z egzaminu 0 (zakreśl poniżej x) 1. Wśród poniższych wskaż poprawną formę definicji

Bardziej szczegółowo

Jak napisać program obliczający pola powierzchni różnych figur płaskich?

Jak napisać program obliczający pola powierzchni różnych figur płaskich? Część IX C++ Jak napisać program obliczający pola powierzchni różnych figur płaskich? Na początku, przed stworzeniem właściwego kodu programu zaprojektujemy naszą aplikację i stworzymy schemat blokowy

Bardziej szczegółowo

Wykład 5: Klasy cz. 3

Wykład 5: Klasy cz. 3 Programowanie obiektowe Wykład 5: cz. 3 1 dr Artur Bartoszewski - Programowanie obiektowe, sem. 1I- WYKŁAD - podstawy Konstruktor i destruktor (część I) 2 Konstruktor i destruktor KONSTRUKTOR Dla przykładu

Bardziej szczegółowo

TESTOWANIE OPROGRAMOWANIA

TESTOWANIE OPROGRAMOWANIA TESTOWANIE OPROGRAMOWANIA Uważaj na ten program ja tylko udowodniłem jego poprawność, nie testowałem go Donald Knuth Plan prezentacji 1. Testowanie wstęp 2. Refaktoryzacja 3. Pojęcia związane z testowaniem

Bardziej szczegółowo

Priorytetyzacja przypadków testowych za pomocą macierzy

Priorytetyzacja przypadków testowych za pomocą macierzy Priorytetyzacja przypadków testowych za pomocą macierzy W niniejszym artykule przedstawiony został problem przyporządkowania priorytetów do przypadków testowych przed rozpoczęciem testów oprogramowania.

Bardziej szczegółowo

LABARATORIUM 9 TESTY JEDNOSTKOWE JUNIT 3.8

LABARATORIUM 9 TESTY JEDNOSTKOWE JUNIT 3.8 Inżynieria Oprogramowania 2013/14 LABARATORIUM 9 TESTY JEDNOSTKOWE JUNIT 3.8 Hierarchia klas: TestCase klasa testująca, będąca klasą bazową dla wszystkich przypadków testowych. Zawiera przypadki testowe

Bardziej szczegółowo

Warunek wielokrotnego wyboru switch... case

Warunek wielokrotnego wyboru switch... case Warunek wielokrotnego wyboru switch... case Działanie instrukcji switch jest zupełnie inne niż w przypadku instrukcji if o czym będziesz mógł się przekonać w niniejszym rozdziale. Różnice pomiędzy instrukcjami

Bardziej szczegółowo

Klasa jest nowym typem danych zdefiniowanym przez użytkownika. Najprostsza klasa jest po prostu strukturą, np

Klasa jest nowym typem danych zdefiniowanym przez użytkownika. Najprostsza klasa jest po prostu strukturą, np Klasy Klasa jest nowym typem danych zdefiniowanym przez użytkownika Wartości takiego typu nazywamy obiektami Najprostsza klasa jest po prostu strukturą, np struct Zespolona { Klasy jako struktury z operacjami

Bardziej szczegółowo

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach? Część XVIII C++ Funkcje Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach? Umiemy już podzielić nasz

Bardziej szczegółowo

Wykład 3 Składnia języka C# (cz. 2)

Wykład 3 Składnia języka C# (cz. 2) Wizualne systemy programowania Wykład 3 Składnia języka C# (cz. 2) 1 dr Artur Bartoszewski -Wizualne systemy programowania, sem. III- WYKŁAD Wizualne systemy programowania Metody 2 Metody W C# nie jest

Bardziej szczegółowo

Programowanie obiektowe

Programowanie obiektowe Laboratorium z przedmiotu Programowanie obiektowe - zestaw 02 Cel zajęć. Celem zajęć jest zapoznanie z praktycznymi aspektami projektowania oraz implementacji klas i obiektów z wykorzystaniem dziedziczenia.

Bardziej szczegółowo

C++ Przeładowanie operatorów i wzorce w klasach

C++ Przeładowanie operatorów i wzorce w klasach C++ i wzorce w klasach Andrzej Przybyszewski numer albumu: 89810 14 listopada 2009 Ogólnie Przeładowanie (przeciążanie) operatorów polega na nadaniu im nowych funkcji. Przeładowanie operatora dokonuje

Bardziej szczegółowo

Wstęp do informatyki- wykład 7

Wstęp do informatyki- wykład 7 1 Wstęp do informatyki- wykład 7 Operatory przypisania, złożone operatory przypisania, Pętla while i do..while Treści prezentowane w wykładzie zostały oparte o: S. Prata, Język C++. Szkoła programowania.

Bardziej szczegółowo

PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec

PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec PROE wykład 2 operacje na wskaźnikach dr inż. Jacek Naruniec Zmienne automatyczne i dynamiczne Zmienne automatyczne: dotyczą kontekstu, po jego opuszczeniu są usuwane, łatwiejsze w zarządzaniu od zmiennych

Bardziej szczegółowo

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki Dariusz Brzeziński Politechnika Poznańska, Instytut Informatyki Object-oriented programming Najpopularniejszy obecnie styl (paradygmat) programowania Rozwinięcie koncepcji programowania strukturalnego

Bardziej szczegółowo

JUnit TESTY JEDNOSTKOWE. Waldemar Korłub. Platformy Technologiczne KASK ETI Politechnika Gdańska

JUnit TESTY JEDNOSTKOWE. Waldemar Korłub. Platformy Technologiczne KASK ETI Politechnika Gdańska JUnit TESTY JEDNOSTKOWE Waldemar Korłub Platformy Technologiczne KASK ETI Politechnika Gdańska Testy aplikacji 2 Ręczne testowanie Czasochłonne Powtarzalność trudna do uzyskania Nudne Testowanie automatyczne

Bardziej szczegółowo

PROJEKTOWANIE. kodowanie implementacja. PROJEKT most pomiędzy specyfikowaniem a kodowaniem

PROJEKTOWANIE. kodowanie implementacja. PROJEKT most pomiędzy specyfikowaniem a kodowaniem PROJEKTOWANIE określenie wymagań specyfikowanie projektowanie kodowanie implementacja testowanie produkt konserwacja Faza strategiczna Analiza Dokumentacja Instalacja PROJEKT most pomiędzy specyfikowaniem

Bardziej szczegółowo

Zadanie 2: Arytmetyka symboli

Zadanie 2: Arytmetyka symboli 1 Cel ćwiczenia Zadanie 2: Arytmetyka symboli Wykształcenie umiejętności abstrahowania operacji arytmetycznych. Zapoznanie się i przećwiczenie mechanizmu tworzenia przeciążeń funkcji operatorowych. Utrwalenie

Bardziej szczegółowo

2. Tablice. Tablice jednowymiarowe - wektory. Algorytmy i Struktury Danych

2. Tablice. Tablice jednowymiarowe - wektory. Algorytmy i Struktury Danych 2. Tablice Tablica to struktura danych przechowująca elementy jednego typu (jednorodna). Dostęp do poszczególnych elementów składowych jest możliwy za pomocą indeksów. Rozróżniamy następujące typy tablic:

Bardziej szczegółowo

Zad. 3: Układ równań liniowych

Zad. 3: Układ równań liniowych 1 Cel ćwiczenia Zad. 3: Układ równań liniowych Wykształcenie umiejętności modelowania kluczowych dla danego problemu pojęć. Definiowanie właściwego interfejsu klasy. Zwrócenie uwagi na dobór odpowiednich

Bardziej szczegółowo

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami 1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami Celem tych zajęć jest zrozumienie i oswojenie z technikami programowania przy pomocy wskaźników w języku C++. Proszę przeczytać rozdział 8.

Bardziej szczegółowo

Zad. 3: Rotacje 2D. Demonstracja przykładu problemu skończonej reprezentacji binarnej liczb

Zad. 3: Rotacje 2D. Demonstracja przykładu problemu skończonej reprezentacji binarnej liczb Zad. 3: Rotacje 2D 1 Cel ćwiczenia Wykształcenie umiejętności modelowania kluczowych dla danego problemu pojęć. Definiowanie właściwego interfejsu klasy. Zwrócenie uwagi na dobór odpowiednich struktur

Bardziej szczegółowo

TABLICA (ang. array) pojedyncza zmienna z wieloma komórkami, w których można zapamiętać wiele wartości tego samego typu danych.

TABLICA (ang. array) pojedyncza zmienna z wieloma komórkami, w których można zapamiętać wiele wartości tego samego typu danych. Złożone typy danych - TABLICE TABLICA (ang. array) pojedyncza zmienna z wieloma komórkami, w których można zapamiętać wiele wartości tego samego typu danych. * Może przechowywać dowolny typ danych, typ

Bardziej szczegółowo

Podstawy programowania skrót z wykładów:

Podstawy programowania skrót z wykładów: Podstawy programowania skrót z wykładów: // komentarz jednowierszowy. /* */ komentarz wielowierszowy. # include dyrektywa preprocesora, załączająca biblioteki (pliki nagłówkowe). using namespace

Bardziej szczegółowo

Lab 9 Podstawy Programowania

Lab 9 Podstawy Programowania Lab 9 Podstawy Programowania (Kaja.Gutowska@cs.put.poznan.pl) Wszystkie kody/fragmenty kodów dostępne w osobnym pliku.txt. Materiały pomocnicze: Wskaźnik to specjalny rodzaj zmiennej, w której zapisany

Bardziej szczegółowo

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p. Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni Wykład 3 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411B Plan prezentacji Abstrakcja funkcyjna Struktury Klasy hermetyzacja

Bardziej szczegółowo

KUP KSIĄŻKĘ NA: PRZYKŁADOWY ROZDZIAŁ KOMUNIKATY DLA UŻYTKOWNIKA

KUP KSIĄŻKĘ NA:   PRZYKŁADOWY ROZDZIAŁ KOMUNIKATY DLA UŻYTKOWNIKA KUP KSIĄŻKĘ NA: WWW.PRAKTYCZNEPHP.PL PRZYKŁADOWY ROZDZIAŁ KOMUNIKATY DLA UŻYTKOWNIKA KOMUNIKATY DLA UŻYTKOWNIKA W większości aplikacji potrzebujesz mieć możliwość powiadomienia użytkownika o rezultacie

Bardziej szczegółowo

Zad. 4: Rotacje 2D. 1 Cel ćwiczenia. 2 Program zajęć. 3 Opis zadania programowego

Zad. 4: Rotacje 2D. 1 Cel ćwiczenia. 2 Program zajęć. 3 Opis zadania programowego Zad. 4: Rotacje 2D 1 Cel ćwiczenia Wykształcenie umiejętności modelowania kluczowych dla danego problemu pojęć. Definiowanie właściwego interfejsu klasy. Zwrócenie uwagi na dobór odpowiednich struktur

Bardziej szczegółowo

Podstawy Programowania 2

Podstawy Programowania 2 Podstawy Programowania 2 Laboratorium 7 Instrukcja 6 Object Pascal Opracował: mgr inż. Leszek Ciopiński Wstęp: Programowanie obiektowe a programowanie strukturalne. W programowaniu strukturalnym, któremu

Bardziej szczegółowo

Weryfikacja i walidacja. Metody testowania systemów informatycznych

Weryfikacja i walidacja. Metody testowania systemów informatycznych Weryfikacja i walidacja Metody testowania systemów informatycznych Zagadnienia Weryfikacja a walidacja Etapy procesu testowania Rola planowania w procesie testowania systemów Przegląd różnych strategii

Bardziej szczegółowo

C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie C++ - DZIEDZICZENIE.

C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie C++ - DZIEDZICZENIE. C++ - DZIEDZICZENIE Do najważniejszych cech języka C++ należy możliwość wielokrotnego wykorzystywania kodu Prymitywnym, ale skutecznym sposobem jest kompozycja: deklarowanie obiektów wewnątrz innych klas,

Bardziej szczegółowo

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów Operatory są elementami języka C++. Istnieje zasada, że z elementami języka, takimi jak np. słowa kluczowe, nie można dokonywać żadnych zmian, przeciążeń, itp. PRZECIĄŻANIE OPERATORÓW Ale dla operatorów

Bardziej szczegółowo

Dokumentacja do API Javy.

Dokumentacja do API Javy. Dokumentacja do API Javy http://java.sun.com/j2se/1.5.0/docs/api/ Klasy i obiekty Klasa jest to struktura zawierająca dane (pola), oraz funkcje operujące na tych danych (metody). Klasa jest rodzajem szablonu

Bardziej szczegółowo

Część XVII C++ Funkcje. Funkcja bezargumentowa Najprostszym przypadkiem funkcji jest jej wersja bezargumentowa. Spójrzmy na przykład.

Część XVII C++ Funkcje. Funkcja bezargumentowa Najprostszym przypadkiem funkcji jest jej wersja bezargumentowa. Spójrzmy na przykład. Część XVII C++ Funkcje Funkcja bezargumentowa Najprostszym przypadkiem funkcji jest jej wersja bezargumentowa. Spójrzmy na przykład. 2 3 Tworzymy deklarację i definicję funkcji o nazwie pobierzln() Funkcja

Bardziej szczegółowo

Testowanie I. Celem zajęć jest zapoznanie studentów z podstawami testowania ze szczególnym uwzględnieniem testowania jednostkowego.

Testowanie I. Celem zajęć jest zapoznanie studentów z podstawami testowania ze szczególnym uwzględnieniem testowania jednostkowego. Testowanie I Cel zajęć Celem zajęć jest zapoznanie studentów z podstawami testowania ze szczególnym uwzględnieniem testowania jednostkowego. Testowanie oprogramowania Testowanie to proces słyżący do oceny

Bardziej szczegółowo

PHP 5 język obiektowy

PHP 5 język obiektowy PHP 5 język obiektowy Wprowadzenie Klasa w PHP jest traktowana jak zbiór, rodzaj różnych typów danych. Stanowi przepis jak stworzyć konkretne obiekty (instancje klasy), jest definicją obiektów. Klasa reprezentuje

Bardziej szczegółowo

XQTav - reprezentacja diagramów przepływu prac w formacie SCUFL przy pomocy XQuery

XQTav - reprezentacja diagramów przepływu prac w formacie SCUFL przy pomocy XQuery http://xqtav.sourceforge.net XQTav - reprezentacja diagramów przepływu prac w formacie SCUFL przy pomocy XQuery dr hab. Jerzy Tyszkiewicz dr Andrzej Kierzek mgr Jacek Sroka Grzegorz Kaczor praca mgr pod

Bardziej szczegółowo

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość 1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość 2. Poprawna definicja wskażnika b to: a) float *a, **b = &a; b) float

Bardziej szczegółowo

Pierwsze kroki. Algorytmy, niektóre zasady programowania, kompilacja, pierwszy program i jego struktura

Pierwsze kroki. Algorytmy, niektóre zasady programowania, kompilacja, pierwszy program i jego struktura Materiał pomocniczy do kursu Podstawy programowania Autor: Grzegorz Góralski ggoralski.com Pierwsze kroki Algorytmy, niektóre zasady programowania, kompilacja, pierwszy program i jego struktura Co znaczy

Bardziej szczegółowo

Podstawy Programowania C++

Podstawy Programowania C++ Wykład 3 - podstawowe konstrukcje Instytut Automatyki i Robotyki Warszawa, 2014 Wstęp Plan wykładu Struktura programu, instrukcja przypisania, podstawowe typy danych, zapis i odczyt danych, wyrażenia:

Bardziej szczegółowo

Utworzenie pliku. Dowiesz się:

Utworzenie pliku. Dowiesz się: Dowiesz się: 1. Jak rozpocząć pisanie programu 2. Jak wygląda szkielet programu, co to są biblioteki i funkcja main() 3. Jak wyświetlić ciąg znaków w programie 4. Jak uruchamiać (kompilować) napisany program

Bardziej szczegółowo

SCENARIUSZ LEKCJI. Streszczenie. Czas realizacji. Podstawa programowa

SCENARIUSZ LEKCJI. Streszczenie. Czas realizacji. Podstawa programowa Autorzy scenariusza: SCENARIUSZ LEKCJI OPRACOWANY W RAMACH PROJEKTU: INFORMATYKA MÓJ SPOSÓB NA POZNANIE I OPISANIE ŚWIATA. PROGRAM NAUCZANIA INFORMATYKI Z ELEMENTAMI PRZEDMIOTÓW MATEMATYCZNO-PRZYRODNICZYCH

Bardziej szczegółowo

Wprowadzenie do projektu QualitySpy

Wprowadzenie do projektu QualitySpy Wprowadzenie do projektu QualitySpy Na podstawie instrukcji implementacji prostej funkcjonalności. 1. Wstęp Celem tego poradnika jest wprowadzić programistę do projektu QualitySpy. Będziemy implementować

Bardziej szczegółowo

Testowanie i walidacja oprogramowania

Testowanie i walidacja oprogramowania i walidacja oprogramowania Inżynieria oprogramowania, sem.5 cz. 3 Rok akademicki 2010/2011 Dr inż. Wojciech Koziński Zarządzanie testami Cykl życia testów (proces) Planowanie Wykonanie Ocena Dokumentacja

Bardziej szczegółowo

3. Macierze i Układy Równań Liniowych

3. Macierze i Układy Równań Liniowych 3. Macierze i Układy Równań Liniowych Rozważamy równanie macierzowe z końcówki ostatniego wykładu ( ) 3 1 X = 4 1 ( ) 2 5 Podstawiając X = ( ) x y i wymnażając, otrzymujemy układ 2 równań liniowych 3x

Bardziej szczegółowo

Makropolecenia w Excelu

Makropolecenia w Excelu Makropolecenia w Excelu Trochę teorii Makropolecenie w skrócie nazywane makro ma za zadanie automatyczne wykonanie powtarzających się po sobie określonych czynności. Na przykładzie arkusza kalkulacyjnego

Bardziej szczegółowo

Szablony klas, zastosowanie szablonów w programach

Szablony klas, zastosowanie szablonów w programach Szablony klas, zastosowanie szablonów w programach 1. Szablony klas i funkcji 2. Szablon klasy obsługującej uniwersalną tablicę wskaźników 3. Zastosowanie metody zwracającej przez return referencję do

Bardziej szczegółowo

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) { zdefiniuje. Integer::operator=(ri);

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) { zdefiniuje. Integer::operator=(ri); Przeciążanie operatorów [] Przykład: klasa reprezentująca typ tablicowy. Obiekt ma reprezentować tablicę, do której można się odwoływać intuicyjnie, np. Tab[i] Ma być też dostępnych kilka innych metod

Bardziej szczegółowo