18. listopadu 2013, Brno Připravil: David Procházka. Programovací jazyk C++

Podobné dokumenty
<surface name="pozadi" file="obrazky/pozadi/pozadi.png"/> ****************************************************************************

Preprocesor. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze. Karel Richta, Martin Hořeňovský, Aleš Hrabalík, 2016

Funkční objekty v C++.

PB161 Programování v jazyce C++ Přednáška 8

10. března 2015, Brno Připravil: David Procházka. Programovací jazyk C++

Připravil: David Procházka. Programovací jazyk C++

Abstraktní třídy, polymorfní struktury

Šablony, kontejnery a iterátory

Pokročilé programování v jazyce C pro chemiky (C3220) Statické proměnné a metody, šablony v C++

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

Zpracoval:

Programování v C++ 1, 17. cvičení

Šablony, kontejnery a iterátory

Programování v C++ 1, 5. cvičení

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

PB161 Programování v jazyce C++ Přednáška 9

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

C++ přetěžování funkcí a operátorů. Jan Hnilica Počítačové modelování 19

Jazyk C# (seminář 6)

Více o konstruktorech a destruktorech

přetížení operátorů (o)

Statické proměnné a metody. Tomáš Pitner, upravil Marek Šabo

PB161 Programování v jazyce C++ Přednáška 9

PROGRAMOVÁNÍ V C++ CVIČENÍ

Jazyk C++, některá rozšíření oproti C

Dědičnost. Časová náročnost lekce: 3 hodiny Datum ukončení a splnění lekce: 23.března

Pokročilé programování v jazyce C pro chemiky (C3220) Pokročilá témata jazyka C++

Konstruktory a destruktory

Dynamická identifikace typů v C++.

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Vector datový kontejner v C++.

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Programování v C++ 3, 3. cvičení

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Programování v C++ 2, 4. cvičení

PB161 Programování v jazyce C++ Přednáška 10

přetížení operátorů (o)

Jazyk C++ II. Šablony a implementace

Přetěžování operátorů

Pokročilé programování v jazyce C pro chemiky (C3220) Vstup a výstup v C++

Množina čísel int stl-set-int.cpp

Zapouzdření. Tomáš Pitner, upravil Marek Šabo

Mělká a hluboká kopie

Syntaxe vyjímek. #include <iostream> #include <string> using namespace std; // Trida vyjimek class Vyjimka { private:

24. listopadu 2013, Brno Připravil: David Procházka

8 Třídy, objekty, metody, předávání argumentů metod

16. února 2015, Brno Připravil: David Procházka. Konstruktory a destruktory

Programování v C++ 1, 14. cvičení

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. December 7, 2016

KTE / ZPE Informační technologie

C++ objektově orientovaná nadstavba programovacího jazyka C

8. Načítání a zápis PDB souboru

Programování v jazyce C pro chemiky (C2160) 12. Specifické problémy při vývoji vědeckého softwaru

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Polymorfismus. Časová náročnost lekce: 3 hodiny Datum ukončení a splnění lekce: 30.března

map, multimap - Asociativní pole v C++.

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

Úvod do programovacích jazyků (Java)

Programování v C++ 1, 6. cvičení

Programování v C++ První kroky

Základy jazyka C# Obsah přednášky. Architektura.NET Historie Vlastnosti jazyka C# Datové typy Příkazy Prostory jmen Třídy, rozhraní

1 PRVOCISLA: KRATKY UKAZKOVY PRIKLAD NA DEMONSTRACI BALIKU WEB 1

Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++

PB161 Programování v jazyce C++ Přednáška 10

Automatické testování softwaru. Testujte svůj kód! Předpoklady: Příklad: sum_digits() Možnost 1: Zkusíme funkci použít v konzoli Pythonu.

Dynamicky vázané metody. Pozdní vazba, virtuální metody

Programování v C++ 1, 1. cvičení

PB161 Programování v C++ Proudy pro standardní zařízení Souborové proudy Paměťové proudy Manipulátory

Jazyk C++ II. Výjimky

Algoritmizace a programování

PROGRAMOVÁNÍ V C++ URČENO PRO VZDĚLÁVÁNÍ V AKREDITOVANÝCH STUDIJNÍCH PROGRAMECH ROSTISLAV FOJTÍK

1 Nejkratší cesta grafem

Úvod do programování - Java. Cvičení č.4

IUJCE Přednáška č. 11. další prvky globální proměnné, řízení viditelnosti proměnných, funkcí

PB161 Programování v jazyce C++ Přednáška 9

PB161 Programování v jazyce C++ Přednáška 5

Dědění, polymorfismus

Hotelová škola, Obchodní akademie a Střední průmyslová škola Teplice,Benešovo náměstí 1, příspěvková organizace

konstruktory a destruktory (o)

Základy programovaní 3 - Java. Unit testy. Petr Krajča. Katedra informatiky Univerzita Palackého v Olomouci. 26.,27.

Aplikace Embedded systémů v Mechatronice. Michal Bastl A2/713a

PREPROCESOR POKRAČOVÁNÍ

Testování. Zadání příkladu. Vytvoření kostry třídy. Obsah:

Obsah přednášky 9. Skrývání informací. Skrývání informací. Zapouzdření. Skrývání informací. Základy programování (IZAPR, IZKPR) Přednáška 9

Úvod Třídy Rozhraní Pole Konec. Programování v C# Hodnotové datové typy, řídící struktury. Petr Vaněček 1 / 39

PB161 Programování v jazyce C++ Přednáška 4

Množina v C++ (set, multiset).

Architektura COM. Historie Component Object Model (COM) Komunikace s komponentami Rozhraní komponent COM komponenty v.net.

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

Objekty a třídy. Procedurální a objektově orientované programování. V této kapitole se naučíte: Procedurální a objektově orientované programování

Digitální učební materiál

Generické programování

Jazyk C# (seminář 5)

Chování konstruktorů a destruktorů při dědění

Výčtový typ strana 67

Jazyk C++ I. Šablony

Jazyk C++ I. Šablony 2

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

Transkript:

18. listopadu 2013, Brno Připravil: David Procházka Defenzivní programování Programovací jazyk C++

Proč testovat Strana 2 / 36 Obsah přednášky 1 Proč testovat 2 Aserce 3 Testování 4 CUnit a ty další 5 Shrnutí

Proč testovat Strana 3 / 36 Motivace Přiznejme si: aplikace jsou složité a plné chyb. Chceme však vytvářet co nejméně chybový kód, proto musíme používat nástroje, které je eliminují. Na aplikaci se budeme dívat ze dvou pohledů: pohledu programátora: jak to má fungovat hlídáme pomocí aserce, pohledu testera: co to doopravdy dělá hlídáme pomocí testů. Jedna persona by neměla ovládat druhou ( Tester by neměl vědět, co metoda udělá.).

Aserce Strana 4 / 36 Obsah přednášky 1 Proč testovat 2 Aserce 3 Testování 4 CUnit a ty další 5 Shrnutí

Aserce Strana 5 / 36 Invariant Při běhu aplikace byste měli být schopni prohlásit, že určité podmínky platí (např. že hodnota tohoto indexu je menší, než x). Tyto výroky, které pro korektní běh aplikace musí být splněny nazýváme invarianty. Invarinaty by měly být definovány pouze u podmínek jejichž platnost jsme schopni zajistit. Nepoužívat např. na testování vstupu od uživatele. Platnost těchto invariantů můžeme ověřit pomocí makra assert().

Aserce Strana 6 / 36 Příklad aserce 1 MyVector :: push_ back ( int value ){ 2 if ( pozice == kapacita ){ 3 zvetsit (); 4 } 5 // nikdy nepredpokladejte, ze neco plati 6 // dokazte to... 7 assert ( pozice < kapacita ); 8 data [ pozice +1] = value ; 9 } V případě neplatnosti bude vráceno následující: Assertion failed: (pozice<kapacita), function push back, file /Users/apple/Desktop/aserce/main.cpp, line 8. Abort trap

Aserce Strana 7 / 36 Další příklad aserce 1 # include < iostream > 2 # include < cassert > 3 4 class Trida { 5 private : 6 float normalizevector ( float x, float y, float z){ 7 float size = sqrt ( sqr (x)+ sqr (y)+ sqr (z) ); 8 x /= size ; y /= size ; z /= size ; 9 } 10 public : 11 void calculateequation ( float x, float y, float z){ 12... 13 normalizevector (x, y, z); 14 assert ((x <=1) and (y <=1) and (z <=1)); 15 } 16 };

Aserce Strana 8 / 36 Vypnutí aserce Aserci můžeme vypnout definování makra NDEBUG. Obvykle definujeme pro celou aplikaci najednou: c++ -DNDEBUG main.cc... Programátoři často aserci vypínají při finálním sestavení aplikace. Nicméně vypínání je diskutabilní. Je přirovnáváno k tomu, když začínající námořník nosí plovací vestu na tréningu, ale nevezme si ji na moře.

Aserce Strana 9 / 36 Základní myšlenka aserce Na ošetření vstupů od uživatele a selhání zdrojů používáme podmínky a výjimky. Aserce je používána na ošetření vnitřní logiky programu. Veškeré problémy signalizované asercí je nutné vyřešit v době vývoje aplikace.

Testování Strana 10 / 36 Obsah přednášky 1 Proč testovat 2 Aserce 3 Testování 4 CUnit a ty další 5 Shrnutí

Testování Strana 11 / 36 Testování Metodika testování je v zásadě manažerský/filozofický postoj. Existuje řada postupů, jak testování integrovat do vývojového cyklu aplikace. Všechny metodiky se shodují na tom, že testování je potřeba.

Testování Strana 12 / 36 Přístup první: Testy pište dřívě, než kód 1 Rozmyslete si, jak má aplikace fungovat a stanovte vstupy, výstupy (získáte hlavičkový soubor). 2 Určete mezní podmínky a reakce na ně. 3 Napište testy. 4 Implementujte metody tak, aby splňovaly testy Proč takto? 1 Programátoři rádi používají ukázněné vstupy. 2 Je nutné prošmátrat tmavé kouty aplikace. 3 Dobrý test je ten, který odhalí chybu. Ne ten, který skončí bezchybně. Stane se, že test i způsobí vyvolání výjimky nebo pád aplikace. To je v pořádku. Postupně testy odkomentovávejte a zjistěte který to byl (a proč).

Testování Strana 13 / 36 Mejme třídu datum 1 class Date { 2 public : 3 Date (); 4 Date ( int year, int month, int day ); 5 Date ( const std :: string &); 6 int getyear () const ; 7 int getmonth () const ; 8 int getday () const ; 9 std :: string tostring () const ; 10 friend bool operator <( const Date &, const Date &); 11 friend bool operator >( const Date &, const Date &); 12 friend bool operator <=( const Date &, const Date &); 13 friend bool operator >=( const Date &, const Date &); 14 friend bool operator ==( const Date &, const Date &); 15 friend bool operator!=( const Date &, const Date &); 16 };

Testování Strana 14 / 36 Před implementací navrhneme test 1 # include " Date.h" 2 # include < iostream > 3 using namespace std ; 4 5 int npass = 0, nfail = 0; // testovaci pocitadlo 6 void test ( bool t) { 7 if( t) npass ++; else nfail ++; 8 } 9 10 int main () { 11 Date mybday (1951, 10, 1); 12 test ( mybday. getyear () == 1951); 13 test ( mybday. getmonth () == 10); 14 test ( mybday. getday () == 1); 15 cout << " Passed : " << npass << ", Failed : " 16 << nfail << endl ; 17 }

Testování Strana 15 / 36 Potřebné testy: operátory 1 // test operatoru 2 test ( mybday < today ); 3 test ( mybday <= today ); 4 test ( mybday!= today ); 5 test ( mybday == mybday ); 6 test ( mybday >= mybday ); 7 test ( mybday <= mybday ); 8 test ( myevebday < mybday ); 9 test ( mybday > myevebday ); 10 test ( mybday >= myevebday ); 11 test ( mybday!= myevebday );

Testování Strana 16 / 36 Potřebné testy: metody 1 // testy metod 2 test ( mybday. getyear () == 1951); 3 test ( mybday. getmonth () == 10); 4 test ( mybday. getday () == 1); 5 test ( myevebday. getyear () == 1951); 6 test ( myevebday. getmonth () == 9); 7 test ( myevebday. getday () == 30); 8 test ( mybday. tostring () == " 19511001 ");

Testování Strana 17 / 36 Ted doopravdy: napíšeme testovací třídu 1 class DateTest : public TestSuite :: Test { 2 Date mybday ; 3 Date today ; 4 Date myevebday ; 5 public : 6 DateTest (){ 7 mybday = Date (1951, 10, 1); 8 myevebday = Date (" 19510930 "); 9 }; 10 void run (); // prekryta z TestSuite 11 private : 12 void testops (); 13 void testfunctions (); 14 };

Testování Strana 18 / 36 Implementace testu opratorů 1 void DateTest :: testops () { 2 test_ ( mybday < today ); 3 test_ ( mybday <= today ); 4 test_ ( mybday!= today ); 5 test_ ( mybday == mybday ); 6 test_ ( mybday >= mybday ); 7 test_ ( mybday <= mybday ); 8 test_ ( myevebday < mybday ); 9 test_ ( mybday > myevebday ); 10 test_ ( mybday >= myevebday ); 11 test_ ( mybday!= myevebday ); 12 }

Testování Strana 19 / 36 Implementace testu zakladních metod 1 void DateTest :: testfunctions () { 2 test_ ( mybday. getyear () == 1951); 3 test_ ( mybday. getmonth () == 10); 4 test_ ( mybday. getday () == 1); 5 test_ ( myevebday. getyear () == 1951); 6 test_ ( myevebday. getmonth () == 9); 7 test_ ( myevebday. getday () == 30); 8 test_ ( mybday. tostring () == " 19511001 "); 9 test_ ( myevebday. tostring () == " 19510930 "); 10 }

Testování Strana 20 / 36 Zavolání testu 1 # include < iostream > 2 # include " DateTest.h" 3 using namespace std ; 4 5 int main () { 6 DateTest test ; 7 test. run (); 8 // return test. report (); 9 }

Testování Strana 21 / 36 Co dělá test? 1 // pseudokod 2 void test_ ( bool condition ){ 3 if ( condition ){ 4 npass ++ 5 // rozumne by bylo zapisovat si to 6 // do atributu a ten vypsat v metode report 7 cout << " Test " << typeid (* this ). name () 8 << " Passed " << endl ; 9 } else { 10 nfail ++; 11 cout << " Test " << typeid (* this ). name () 12 << " Failed " << endl ; 13 } 14 }

Testování Strana 22 / 36 Testování více tříd Uděláme si zásobník testů, které se budou provádět. 1 TestSuite suite (" Date and Time Tests "); 2 suite. addtest ( new MonthInfoTest ); 3 suite. addtest ( new JulianDateTest ); 4 suite. addtest ( new JulianTimeTest ); 5 suite. addtest ( new DateTest ); 6 suite. addtest ( new TimeTest ); 7 suite. run (); 8 suite. report (); 9... Aby bylo možné testy provolávat, byla pro odvození testu použita dědičnost.

Testování Strana 23 / 36 Testování výjimek 1 void testexceptions () { 2 try { 3 Date d (0,0,0); // Invalid 4 fail_ (" Invalid date undetec. in Date int ctor "); 5 } catch ( Date :: DateError &) { 6 succeed_ (); 7 } 8 9 try { 10 Date d(""); // Invalid 11 fail_ (" Inv. date undetec. in Date string ctor "); 12 } catch ( Date :: DateError &) { 13 succeed_ (); 14 } 15 }

CUnit a ty další Strana 24 / 36 Obsah přednášky 1 Proč testovat 2 Aserce 3 Testování 4 CUnit a ty další 5 Shrnutí

CUnit a ty další Strana 25 / 36 Knihovny pro automatizované testování Zřejmě nejznámější je knihovna CUnit: http://cunit.sourceforge.net/, Statická knihovna primárně pro C, která se přilinkuje. Několik rozhraní: Automated (výstup do XML), Basic (standardní výstup), Console (interaktivní režim), Curses (interaktivní grafický režim). Dobrá je knihovna Boost: http://www.boost.org/: Experimentální funkce pro C++, http://www.boost.org/doc/libs/1_45_0/libs/test/ doc/html/index.html, Paralelou JUnit je CppUnit (2): https://launchpad.net/cppunit2: Rozsáhlá knihovna, podpora pro TDD. Jednoduchou alternativou je CuTest: http://cutest.sourceforge.net/, Jeden.c a.h soubor, přiloží se k projektu.

CUnit a ty další Strana 26 / 36 Základní test v CppUnit: MoneyApp.cpp 1 # include " stdafx.h" 2 # include < cppunit / CompilerOutputter. h > 3 # include < cppunit / extensions / TestFactoryRegistry. h > 4 # include < cppunit /ui/ text / TestRunner.h> 5 6 int main ( int argc, char * argv []){ 7 // vytvorime testovaci suite 8 CppUnit :: Test * suite = CppUnit :: TestFactoryRegistry 9 :: getregistry (). maketest (); 10 // pridame spoustec testu 11 CppUnit :: TextUi :: TestRunner runner ; 12 runner. addtest ( suite ); 13 // nastaveni vystupu 14 runner. setoutputter ( 15 new CppUnit :: CompilerOutputter (& runner. result (), 16 std :: cerr ) ); 17...

CUnit a ty další Strana 27 / 36 Základní test v CppUnit: MoneyApp.cpp 2 1 // spusteni testu 2 bool wassucessful = runner. run (); 3 // Return error code 1 if the one of test failed. 4 return wassucessful? 0 : 1; 5 } 6 To nejhorsi mame za sebou...

CUnit a ty další Strana 28 / 36 Základní test: hlavičkový soubor MoneyTest 1 # ifndef MONEYTEST_ H 2 # define MONEYTEST_ H 3 4 # include < cppunit / extensions / HelperMacros.h> 5 6 class MoneyTest : public CppUnit :: TestFixture { 7 CPPUNIT_ TEST_ SUITE ( MoneyTest ); // skupina 8 CPPUNIT_ TEST ( testconstructor ); // test konst. 9 CPPUNIT_TEST_SUITE_END (); 10 public : 11 void testconstructor (); 12 }; 13 # endif // MONEYTEST_ H

CUnit a ty další Strana 29 / 36 Základní test: implem. soubor MoneyTest 1 # include " MoneyTest.h" 2 3 CPPUNIT_TEST_SUITE_REGISTRATION ( MoneyTest ); 4 5 void MoneyTest :: testconstructor (){ 6 // zatim prazdna implementace, jen hlaseni chyby 7 CPPUNIT_ FAIL ( " not implemented " ); 8 }

CUnit a ty další Strana 30 / 36 Už víme jak bude vypadat třída a její konstr. Uděláme nejdříve jeho testovací metodu. 1 void MoneyTest :: testconstructor (){ 2 // vytvoreni pomocnych promennych 3 const std :: string currencyff = " FF"; 4 const double longnumber = 12345678. 90123; 5 6 // pokus o vytvoreni 7 Money money ( longnumber, currencyff ); 8 9 // aserce 10 CPPUNIT_ ASSERT_ EQUAL ( longnumber, 11 money. getamount ()); 12 CPPUNIT_ ASSERT_ EQUAL ( currencyff, 13 money. getcurrency ()); 14 }

CUnit a ty další Strana 31 / 36 Vytvoříme třídu s konstruktorem 1... 2 class Money { 3 double m_ amount ; 4 std :: string m_ currency ; 5 public : 6 Money ( double amount, std :: string currency ){ 7 m_ amount = amount ; 8 m_ currency = m_ currency ; 9 } 10 double getamount () const { 11 return m_ amount ; 12 } 13 std :: string getcurrency () const { 14 return m_ currency ; 15 } 16...

CUnit a ty další Strana 32 / 36 A test skončí chybou... Takže opravíme konstruktor... 1 Money ( double amount, std :: string currency ){ 2 m_ amount = amount ; 3 m_ currency = currency ; // tady byl preklep 4 }

CUnit a ty další Strana 33 / 36 A postupně dodáváme další testy... V MoneyTest.h: 1... 2 CPPUNIT_ TEST_ SUITE ( MoneyTest ); 3 CPPUNIT_ TEST ( testconstructor ); 4 CPPUNIT_ TEST ( testequal ); 5 CPPUNIT_TEST_SUITE_END (); 6 7 public : 8... 9 void testequal (); 10...

CUnit a ty další Strana 34 / 36 Implementujeme nový test... V MoneyTest.cpp: 1 void MoneyTest :: testequal (){ 2 // pomocne promenne 3 const Money money123ff ( 123, " FF" ); 4 const Money money123usd ( 123, " USD " ); 5 const Money money12ff ( 12, " FF" ); 6 const Money money12usd ( 12, " USD " ); 7 8 // stejna mena 9 CPPUNIT_ ASSERT ( money123ff == money123ff ); 10 CPPUNIT_ ASSERT ( money12ff!= money123ff ); 11 // ruzna mena 12 CPPUNIT_ ASSERT ( money123usd!= money123ff ); 13 CPPUNIT_ ASSERT ( money12usd!= money123ff ); 14 }

Shrnutí Strana 35 / 36 Obsah přednášky 1 Proč testovat 2 Aserce 3 Testování 4 CUnit a ty další 5 Shrnutí

Shrnutí Strana 36 / 36 Základní myšlenky testování Testujeme systematicky (po sebemenší úpravě v systému), testujeme automatizovaně (nemáme sílu testovat systematicky ručně), testuje důsledně (nic nepředpokládáváme, žádnou (sebejasnější) podmínku nevynecháme).