Modell megvalósítása. Gregorics Tibor: Eseményvezérelt alkalmazások fejlesztése I.

Hasonló dokumentumok
Eseményvezérelt alkalmazások fejlesztése I 11. előadás. Szoftverek tesztelése

Eseményvezérelt alkalmazások fejlesztése I 5. előadás. Grafikus felületű alkalmazások architektúrája

Eseményvezérelt alkalmazások fejlesztése I 5. előadás. Grafikus felületű alkalmazások architektúrája. Grafikus felületű alkalmazások architektúrája

3. Beadandó feladat dokumentáció

Szoftvertechnológia 10. előadás. Verifikáció és validáció. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Programozási technológia II 7. előadás. Verifikáció és validáció Giachetta Roberto

Általános szoftver architektúrák

Eseményvezérelt alkalmazások fejlesztése I 12. előadás. Összetett szoftver architektúrák. Giachetta Roberto

Eseményvezérelt alkalmazások fejlesztése I 8. előadás. Általános szoftver architektúrák. Giachetta Roberto

ELTE, Informatikai Kar december 12.

JUnit. JUnit használata. IDE támogatás. Parancssori használat. Teszt készítése. Teszt készítése

Programozási technológia 2.

A legalacsonyabb szintű tesztelés. A programot felépítő egységek tesztelése Unit: egy rendszer legkisebb önálló egységként tesztlehető része.

Unit Teszt. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) Unit Teszt / 22

Webes alkalmazások fejlesztése 10. előadás. Webszolgáltatások tesztelése (ASP.NET Core) Cserép Máté

Elemi alkalmazások fejlesztése III.

Eseményvezérelt alkalmazások fejlesztése II 4. előadás. Windows Forms alkalmazások architektúrája és tesztelése. Giachetta Roberto

bool _freehand = false; QPoint _lastpoint; // ebben a pontban volt az utolsó rajzolásnál az egérmutató

Elemi alkalmazások fejlesztése III.

Térinformatikai és távérzékelési alkalmazások fejlesztése. Szoftverek minőségbiztosítása

3D-s számítógépes geometria és alakzatrekonstrukció

2. Beadandó feladat dokumentáció

Programozási nyelvek II. JAVA

Eseménykezelés. Aszinkron kommunikáció

Programozás II gyakorlat. 6. Polimorfizmus

2. Beadandó feladat dokumentáció

Elemi alkalmazások fejlesztése III.

Elemi alkalmazások fejlesztése III.

1. Beadandó feladat dokumentáció

3D-s számítógépes geometria és alakzatrekonstrukció

Eseményvezérelt alkalmazások fejlesztése II 5. előadás. Windows Forms alkalmazások párhuzamosítása. Giachetta Roberto

Név: Neptun kód: Pontszám:

A jobboldalon a pnlright egy Stacked Widget Állítsuk be az első lapot és nevezzük el pnldraw-ra:

OAF Gregorics Tibor: Minta dokumentáció a 3. házi feladathoz 1.

Megoldások a mintavizsga kérdések a VIMIAC04 tárgy ellenőrzési technikák részéhez kapcsolódóan (2017. május)

Bevezetés a programozásba II. 8. Előadás: Osztályok, objektumok, osztályszintű metódusok

Szálkezelés. Melyik az a hívás, amelynek megtörténtekor már biztosak lehetünk a deadlock kialakulásában?

Programozási nyelvek Java

Szerző. Varga Péter ETR azonosító: VAPQAAI.ELTE cím: Név: Kurzuskód:

JUnit.

Bevezetés a Programozásba II 11. előadás. Adatszerkezetek megvalósítása. Adatszerkezetek megvalósítása Adatszerkezetek

Objektumelvű programozás

Elemi grafika. Stílusok, időzítő, képek

Sikeres végrehajtás(pass): ez azt jelenti, hogy a teszt rendben lefutott, és az ellenőrzési feltételek mind teljesültek.

Tervezőeszközök, fejlesztőeszközök használata Qt alapú alkalmazásoknál. Saját vezérlő használata tervezőben (worldclocks)

Elemi alkalmazások fejlesztése III. A Qt assistant elindítása. Ajánlott ir odalom. A Qt assistant nyitó ablaka

Eseményvezérelt alkalmazások fejlesztése I 11. előadás. Adatkezelés speciális eszközökkel. Giachetta Roberto

Eseményvezérelt alkalmazások fejlesztése II 4. előadás. Windows Forms alkalmazások architektúrája és tesztelése

Szoftvertechnolo gia gyakorlat

A gyakorlat során az alábbi ábrán látható négy entitáshoz kapcsolódó adatbevitelt fogjuk megoldani.

Adatok speciális megjelenítése

Eseményvezérelt alkalmazások fejlesztése I 7. előadás. Összetett grafikus felületű alkalmazások. Giachetta Roberto

Elemi alkalmazások fejlesztése IV. Adatbázis-kezelő GUI alkalmazás készítése 3. Összetett tábla karbantartása

public class HelloWorld extends TestCase { public void testmultiplication() { // Testing if 3*2=6: assertequals ("Multiplication", 6, 3*2);

3. Beadandó feladat dokumentáció

Programozás II. ATM példa Dr. Iványi Péter

OO rendszerek jellemzői

Szoftvertechnológia 6. előadás. Objektumorientált tervezés: állapotkezelés. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

1. Melyik szabvány foglalkozik dokumentumok tulajdonságainak megfogalmazásával? a. RDFS b. FOAF c. Dublin Core d. DBPedia

Integrációs mellékhatások és gyógymódok a felhőben. Géczy Viktor Üzletfejlesztési igazgató

MŰSZAKI TESZTTERVEZÉSI TECHNIKÁK STRUKTÚRA ALAPÚ, VAGY FEHÉRDOBOZ TECHNIKÁK TAPASZTALAT ALAPÚ TECHNIKÁK

Programozási technológia

Programozás II gyakorlat. 4. Öröklődés

Java Programozás 4. Gy: Java GUI. Tipper, MVC kalkulátor

Grafikus Qt programok írása segédeszközök nélkül

Tervminták a valósidejű gyakorlatban

Eseményvezérelt alkalmazások fejlesztése I 3. előadás. Dinamikus felületű alkalmazások. Giachetta Roberto

C# nyelv alapjai. Krizsán Zoltán 1. Objektumorientált programozás C# alapokon tananyag. Általános Informatikai Tanszék Miskolci Egyetem

Teszt terv Új funkció implementációja meglévı alkalmazásba

Szoftvertechnológia 7. előadás. Objektumorientált tervezés: végrehajtás. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Swing GUI készítése NetBeans IDE segítségével

Eseményvezérelt alkalmazások fejlesztése II 5. előadás. Windows Forms alkalmazások párhuzamosítása. Cserép Máté

Alkalmazások fejlesztése III. Qt 4 /C++ alapú grafikus alkalmazás Bevezetés I.

Dinamikus felületű alkalmazások. Stílusok, időzítő, képek

BEÁGYAZOTT RENDSZEREK ALAPJAI. Grafikus benchmark alkalmazás

munkafüzet open eseményéhez

Eseményvezérelt alkalmazások fejlesztése I 4. előadás. Elemi grafika és egérkezelés

OpenCL alapú eszközök verifikációja és validációja a gyakorlatban

WEBFEJLESZTÉS 2. ADATBÁZIS-KEZELÉS, OSZTÁLYOK

Bevezetés a Programozásba II 3. előadás. Biztonságos adattípusok megvalósítása

C#, OOP. Osztályok tervezése C#-ban

Objektumok inicializálása

Egységes és objektumközpontú adatbázis-kezelés (2. rész)

Programozási alapismeretek beadandó feladat: ProgAlap beadandó feladatok téma 99. feladat 1

Vizuális és eseményvezérelt programozás , II. félév BMF NIK

Vezérlési szerkezetek

Programozási nyelvek Java

Java Programozás 11. Ea: MVC modell

Programozási nyelvek II. JAVA

Bevezetés a Programozásba II 8. előadás. Polimorfizmus Giachetta Roberto

Eseményvezérelt alkalmazások fejlesztése I 4. előadás. Elemi grafika és egérkezelés. Elemi grafika és egérkezelés Rajzolás grafikus felületen

osztályok kapcsolata Származtatatás C++ Izsó Tamás március 19. Izsó Tamás Származtatatás/ 1

Java Programozás 9. Gy: Java alapok. Adatkezelő 5.rész

Bevezetés a Programozásba II 2. előadás. Adattípusok megvalósítása egységbe zárással. Adattípusok megvalósítása egységbe zárással

Mechatronika és mikroszámítógépek 2017/2018 I. félév. Bevezetés a C nyelvbe

Objektumorientált programozás C# nyelven

Bevezetés a Programozásba II 3. előadás. Biztonságos adattípusok megvalósítása. Biztonságos adattípusok megvalósítása

Szerző Lővei Péter LOPSAAI.ELTE IP-08PAEG/25 Daiki Tennó

Elemi Alkalmazások Fejlesztése Beadandó Feladat Juhász Ádám

Átírás:

Modell megvalósítása Mivel modell független a nézettől, és újrahasznosítható, nem tudható előre, milyen módon, milyen körülmények között hívják meg műveleteit. A hívás paramétereit, a modell állapotát ellenőrizni kell a tevékenységek végrehajtása előtt. Egy lépés előtt azt is megnézzük, hogy az végrehajtható-e. A modell és a nézet közötti kommunikációban mindkét irányban törekedni kell az egyértelműségre és a lehető legkevesebb hibalehetőségre. Korlátozott értékhalmazra használjunk felsoroló típusokat (enum). 1

5.Feladat Módosítsuk a Tic-Tac-Toe programot úgy, hogy a modellben a játékost és a szimbólumokat enumeráció segítségével valósítjuk meg. 2

5.Feladat: tervezés Felvesszük a játékos (Player) felsoroló típust beágyazott típusként három lehetséges értékkel (NoPlayer, PlayerX, PlayerO). A játéktábla reprezentációját, valamint a metódusok, események paramétereit is ennek megfelelően alakítjuk át. -_gametable 9 «enumeration» TicTacToeModel:: Player NoPlayer PlayerX PlayerO -_currentplayer TicTacToeWidget QWidget TicTacToeModel QObject - _tablelayout :QGridLayout* - _mainlayout :QVBoxLayout* - _newgamebutton :QPushButton* - _gametablebuttons :QVector<QVector<QPushButton*> > - _model :TicTacToeModel - generatetable() :void - newgame() :void + TicTacToeWidget(QWidget*) «slot» + buttonclicked() :void + model_fieldchanged(int, int, TicTacToeModel::Player) :void + model_gameover() :void + model_gamewon(tictactoemodel::player) :void + newgamebuttonclicked() :void -_model - _stepnumber :int - _currentplayer :Player - _gametable :Player** - checkgame() :void + getfield(int, int) :Player + newgame() :void + stepgame(int, int) :void + stepnumber() :int + TicTacToeModel() + ~TicTacToeModel() «signal» + fieldchanged(int, int, Player) :void + gameover() :void + gamewon(player) :void 3

5.Feladat: megvalósítás TicTacToeModel::TicTacToeModel(){ _gametable = new Player*[3]; for (int i = 0; i < 3; ++i) _gametable[i] = new Player[3]; void TicTacToeModel::newGame(){ for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) _gametable[i][j] = NoPlayer; _stepnumber = 0; játékos szimbólum _currentplayer = PlayerX; 4

5.Feladat: megvalósítás void TicTacToeModel::stepGame(int x, int y){ // lépés előfeltételének vizsgálata _gametable[x][y] = _currentplayer; szignál küldése fieldchanged(x, y, _currentplayer); _currentplayer = (Player)(_currentPlayer % 2 + 1); checkgame(); konverzió void TicTacToeModel::checkGame(){ Player won = NoPlayer; szignál küldése // won beállítása, ha van 3 azonos egy sorban, oszlopban, átlóban if (won!= NoPlayer) gamewon(won); szignál küldése else if (_stepnumber == 9) gameover(); TicTacToeModel::Player TicTacToeModel::getField(int x, int y){ if (x < 0 x > 2 y < 0 y > 2) return NoPlayer; return _gametable[x][y]; 5

5.Feladat: megvalósítás void TicTacToeWidget::model_fieldChanged(int x, int y, TicTacToeModel::Player player){ switch (player){ case TicTacToeModel::PlayerX: _gametablebuttons[x][y]->settext("x"); _gametablebuttons[x][y]->setenabled(false); break; case TicTacToeModel::PlayerO: void TicTacToeWidget::model_gameWon(TicTacToeModel::Player _gametablebuttons[x][y]->settext("o"); player){ char* _gametablebuttons[x][y]->setenabled(false); str; switch break; (player){ case TicTacToeModel::PlayerX: str = "Az X nyerte a játékot!"; break; case TicTacToeModel::PlayerO: str = "Az X nyerte a játékot!"; break; QMessageBox::information(this, trutf8("játék vége!"), trutf8(str)); newgame(); 6

6.Feladat Módosítsuk a Tic-Tac-Toe programot úgy, hogy változtatunk a nézeten, és a felületen alakzatok rajzaival jelenítjük meg a játékállást. 7

6.Feladat: tervezés Csak a nézet változik. A képernyőről levesszük az összes vezérlőt, a megjelenítését rajzolás segítségével (QPainter) valósítjuk meg. A játékosok egér segítségével foglalhatják el a mezőket, új játékot pedig a Ctrl+N billentyűkombinációval indíthatnak. Ehhez felüldefiniáljuk a billentyű- és egérlenyomás eseménykezelőket (keypressevent, mousepressevent). 8

6.Feladat: tervezés -_gametable 9 «enumeration» TicTacToeModel:: Player NoPlayer PlayerX PlayerO -_currentplayer TicTacToeWidget - _tablegraphics :QVector<QLineF> - _playerxgraphics :QVector<QLineF> - _playerographics :QRectF - _model :TicTacToeModel QWidget # keypressevent(qkeyevent*) :void # mousepressevent(qmouseevent*) :void # paintevent(qpaintevent*) :void + TicTacToeWidget(QWidget*) «slot» - model_fieldchanged(int, int, TicTacToeModel::Player) :void - model_gameover() :void - model_gamewon(tictactoemodel::player) :void -_model TicTacToeModel - _stepnumber :int - _currentplayer :Player - _gametable :Player** - checkgame() :void + getfield(int, int) :Player + newgame() :void + stepgame(int, int) :void + stepnumber() :int + TicTacToeModel() + ~TicTacToeModel() QObject «signal» + fieldchanged(int, int, Player) :void + gameover() :void + gamewon(player) :void 9

6.Feladat: megvalósítás TicTacToeWidget::TicTacToeWidget(QWidget *parent) : QWidget(parent) { setminimumsize(400, 400); setbasesize(400,400); setwindowtitle(tr("tic-tac-toe")); // mezők grafikája: _tablegraphics.append(qlinef(0, 66, 200, 66)); _tablegraphics.append(qlinef(0, 132, 200, 132)); _tablegraphics.append(qlinef(66, 0, 66, 200)); _tablegraphics.append(qlinef(132, 0, 132, 200)); // játékosok grafikája: _playerxgraphics.append(qlinef(10, 10, 56, 56)); _playerxgraphics.append(qlinef(10, 56, 56, 10)); _playerographics = QRectF(10.0, 10.0, 46.0, 46.0); 10

6.Feladat: megvalósítás TicTacToeWidget::TicTacToeWidget(QWidget *parent) : QWidget(parent) { // modell eseményeinek feldolgozása connect( &_model, SIGNAL(gameWon(TicTacToeModel::Player)), this, SLOT(model_gameWon(TicTacToeModel::Player))); connect( &_model, SIGNAL(gameOver()), this, SLOT(model_gameOver())); connect( &_model,signal(fieldchanged(int,int,tictactoemodel::player)), this, SLOT(model_fieldChanged(int,int, TicTacToeModel::Player))); _model.newgame(); // új játék indítása 11

6.Feladat: megvalósítás void TicTacToeWidget::paintEvent(QPaintEvent *) { QPainter painter(this); // rajzoló objektum painter.setrenderhint(qpainter::antialiasing); // élsimítás painter.scale(width() / 200.0, height() / 200.0); // skálázás painter.setpen(qpen(qt::black, 2)); painter.setbrush(qt::red); painter.drawlines(_tablegraphics); // tábla kirajzolása for(int i = 0; i < 3; i++){ for(int j = 0; j < 3; j++){ painter.save(); // elmentjük a rajztulajdonságokat painter.translate(i * 200.0 / 3, j * 200.0 / 3); 12

6.Feladat: megvalósítás void TicTacToeWidget::paintEvent(QPaintEvent *) { switch (_model.getfield(i, j)){ // mező kirajzolása case TicTacToeModel::PlayerX: painter.setpen(qpen(qt::blue, 4)); painter.drawlines(_playerxgraphics); break; case TicTacToeModel::PlayerO: painter.setpen(qpen(qt::black, 2)); painter.drawellipse(_playerographics); break; painter.restore(); // visszatöltjük a korábbi állapotot 13

6.Feladat: megvalósítás void TicTacToeWidget::keyPressEvent(QKeyEvent *event){ if (event->key() == Qt::Key_N && QApplication::keyboardModifiers() == Qt::ControlModifier){ _model.newgame(); lekezeljük a Ctrl+N kombinációt update(); void TicTacToeWidget::mousePressEvent(QMouseEvent *event){ int x = event->pos().x() * 3 / width(); int y = event->pos().y() * 3 / height(); az event->pos() megadja az egérpozíciót, ami QPoint típusú, ebből _model.stepgame(x, y); kiszámolható, melyik mezőn vagyunk: 14

6.Feladat: megvalósítás void TicTacToeWidget::model_gameWon(TicTacToeModel::Player player) { // az eredmény függvényében jelenítjük meg a győztest char* str; switch (player){ case TicTacToeModel::PlayerX: str = "Az X nyerte a játékot!"; break; case TicTacToeModel::PlayerO: str = "Az X nyerte a játékot!"; break; QMessageBox::information(this, trutf8("játék vége!"), trutf8(str)); newgame(); 15

6.Feladat: megvalósítás void TicTacToeWidget::model_gameOver() { QMessageBox::information(this, trutf8("játék vége!"), trutf8("a játék döntetlen lett!")); _model.newgame(); void TicTacToeWidget::model_fieldChanged(int x, int y, TicTacToeModel::Player player) { update(); 16

Tesztelés

Tesztelés célja és módja A tesztelés célja a szoftverhibák felfedezése és szoftverrel szemben támasztott minőségi elvárások ellenőrzése. A tesztelés során különböző teszteseteket (test case) különböztetünk meg, amelyek az egyes funkciókat, illetve elvárásokat tudják ellenőrizni: megadjuk, adott bemenő adatokra mi a várt eredmény (expected result), amelyet a teszt lefutása után összehasonlítunk a kapott eredménnyel (actual result). 18

Tesztelés szakaszai A tesztelés nem a teljes program elkészülte után, egyben történik, hanem általában 3 lépésből áll: fejlesztői teszt (development testing), kiadásteszt (release testing), felhasználói teszt (acceptance testing). A fejlesztői tesztnek további három szakasza van: egységteszt (unit test): a programegységeket (osztályok, metódusok) külön-külön, egymástól függetlenül teszteljük integrációs teszt (integration test): a programegységek együttműködésének tesztje, a rendszer egy komponensének vizsgálata rendszerteszt (system test): az egész rendszer együttes tesztje, a rendszert alkotó komponensek közötti kommunikáció vizsgálata 19

Automatikus tesztelés A tesztelés egy része automatizálható, bizonyos részét azonban mindenképpen manuálisan kell végrehajtanunk. Az egységtesztek automatizálását, és az eredmények kiértékelését hatékonyabbá tehetjük tesztelési keretrendszerek (unit testing frameworks) használatával. Általában a tényleges főprogramoktól függetlenül építhetünk teszteseteket, amelyeket futtathatunk, és megkapjuk a futás pontos eredményét. A tesztestekben egy, vagy több ellenőrzés (assert) kap helyet, amelyek jelezhetnek hibákat. Amennyiben egy hibajelzést sem kaptunk egy tesztesetből, akkor az eset sikeres (pass), egyébként sikertelen (fail). Alapvető eszköze a tesztvezérelt fejlesztésnek (Test Driven Development, TDD). 20

Egységtesztek TestSuit Object Tester loop testcase() execute() assert() alt [test succeeded] [test failed] pass() fail() 21

Tesztelés Qt keretrendszerben A Qt keretrendszer tartalmaz egy beágyazott tesztelő modult (QTestLib), amely lehetőségeket ad egységtesztek és teljesítménytesztek könnyű megfogalmazására, és végrehajtására. A tesztekhez szükséges funkciókat a QtTest fájlban találjuk. A tesztkörnyezetet QObject leszármazott osztályokban valósítjuk meg (amelyeket ellátunk Q_OBJECT makróval). A tesztesetek eseménykezelők lesznek, amelyekben ellenőrzéseket végzünk. A projektben megjelöljük a modul használatát (QT += testlib). 22

Makrók Az ellenőrzéseket makrók segítségével valósítjuk meg, pl.: Logikai kifejezés ellenőrzése: QVERIFY(<kifejezés>) Összehasonlítás: QCOMPARE(<aktuális érték>, <várt érték>) hiba: QFAIL(<üzenet>) figyelmeztetés: QWARN(<üzenet>) A teszt futtatását a QTEST_MAIN(<osztálynév>) vagy a QTEST _APPLESS_MAIN(<osztálynév>) makróval végezhetjük, amely automatikusan legenerál egy főprogramot, és végrehajtja a teszteseteket, így a tesztek egyszerű konzolos alkalmazásként futtathatóak. 23

Példa tesztelendő osztály class MyClass { private: int _value; publikus metódusokat teszteljük public: MyClass (int v) { _value = v; void add(int v) { _value += v; int getvalue() const { return _value; 24

Példa tesztkörnyezet class MyClassTest : QObject { Q_OBJECT private slots: tesztesetek, mint eseménykezelők void testgetvalue() { MyClass mc(10); QVERIFY(mc.getValue() == 10); // másképp: QCOMPARE(mc.getValue(), 10); void testadd() { MyClass mc(10); mc.add(5); QCOMPARE(mc.getValue(), 15); mc.add(15); QCOMPARE(mc.getValue(), 30); tetszőleges sok ellenőrzést végezhetünk 25

Tesztprojekt A Qt Creator biztosít egy teszt projekt típust (Qt Unit Test). Létrehozza a megadott tesztkörnyezetet, valamint a főprogram generátort (egy forrásfájlban). A tesztünk futtatása részletes eredményt ad, tesztesetenként láthatjuk az eredményt, az esetleges hibajelenséget, valamint a hiba helyét: PASS : MyClassTest::testGetValue() PASS : MyClassTest::testAddValue() FAIL! : MyClassTest:: () Compared values are not the same Loc : [../MyTest/myclasstest.cpp(106)]! Totals: 2 passed, 1 failed, 0 skipped 26

Tesztkörnyezet beállítása Lehetőségünk van a tesztkörnyezet konfigurálására: A tesztkörnyezetben mezőként bármilyen adatot eltárolhatunk, ezeket speciális eseménykezelőkkel állíthatjuk. Az első teszteset előtt lefut a tesztkörnyezet inicializálás (inittestcase). Az utolsó teszteset után lefut a tesztkörnyezet megsemmisítés (cleanuptestcase). Minden teszt előtt lefut a teszteset inicializálás (init). Minden teszt után lefut a teszteset megsemmisítés (cleanup). 27

Példa class MyClassTest : QObject { Q_OBJECT tesztkörnyezet értékei private: MyClass* _mc; private slots: inicializálás void inittestcase() { _mc = new MyClass(10); megsemmisítés void cleanuptestcase() { delete _mc; 28

Feladat Teszteljük le a Tic-Tac-Toe játék kétrétegű megvalósításának modelljét. Létrehozunk egy tesztprojektet, amelybe bemásoljuk a TicTacToeModel osztályt. Létrehozunk egy tesztkörnyezetet (TicTacToeModelTest), amelyben teszteljük új játék kezdését (testnewgame), és a lépések végrehajtását (teststepgame). a tesztkörnyezet tárolja a modell egy példányát, amelyet inicializál (inittestcase), majd megsemmisít (cleanuptestcase) 29

Feladat: tervezés TicTacToeModel QObject - _stepnumber :int - _currentplayer :Player - _gametable :Player** + TicTacToeModel() + ~TicTacToeModel() + newgame() :void + stepgame(int, int) :void + getfield(int, int) :Player {query + stepnumber() :int {query - checkgame() :void «signal» + fieldchanged(int, int, TicTacToeModel::Player) :void + gameover() :void + gamewon(tictactoemodel::player) :void -_model QObject TicTacToeModelTest - _model :TicTacToeModel* «slot» - inittestcase() :void - cleanuptestcase() :void - testnewgame() :void - teststepgame() :void - teststepgameerrors() :void 30

Teszt osztály #include <QtTest> #include "tictactoemodel.h" class TicTacToeModelTest : public QObject{ Q_OBJECT private: TicTacToeModel* _model; private slots: void inittestcase(); void cleanuptestcase(); void testnewgame(); void teststepgame(); void teststepgameerrors(); ; QTEST_APPLESS_MAIN(TicTacToeModelTest) #include "tictactoemodeltest.moc" 31

Teszt osztály metódusai void TicTacToeModelTest::initTestCase(){ _model = new TicTacToeModel(); void TicTacToeModelTest::cleanupTestCase(){ delete _model; void TicTacToeModelTest::testNewGame(){ _model->newgame(); QCOMPARE(_model->stepNumber(), 0); for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) tesztkörnyezet létrehozása tesztkörnyezet megsemmisítése tesztesetek ellenőrizzük, hogy kezdetben minden mező üres, és a lépésszám 0 QCOMPARE(_model->getField(i, j),tictactoemodel::noplayer); 32

Teszt osztály metódusai void TicTacToeModelTest::testStepGame(){ _model->newgame(); _model->stepgame(0, 0); QCOMPARE(_model->stepNumber(), 1); QCOMPARE(_model->getField(0, 0), TicTacToeModel::PlayerX); for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) QVERIFY((i == 0 && j == 0) ellenőrizzük, hogy kezdetben minden mező üres, és a lépésszám 0 ellenőrizzük, hogy közben más mező nem változott (_model->getfield(i, j) == TicTacToeModel::NoPlayer)); _model->stepgame(0, 1); ellenőrizzük, hogy ezután O QCOMPARE(_model->stepNumber(), 2); következik QCOMPARE(_model->getField(0, 1), TicTacToeModel::PlayerO); _model->stepgame(0, 2); majd ismét az X QCOMPARE(_model->stepNumber(), 3); QCOMPARE(_model->getField(0, 2), TicTacToeModel::PlayerX); 33

Teszt osztály metódusai void TicTacToeModelTest::testStepGameErrors(){ _model->newgame(); _model->stepgame(-1, 0); _model->stepgame(0, -1); _model->stepgame(3, 0); _model->stepgame(0, 3); QCOMPARE(_model->stepNumber(), 0); for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) QVERIFY(_model->getField(i, j) == TicTacToeModel::NoPlayer); _model->stepgame(0, 0); _model->stepgame(0, 0); QCOMPARE(_model->stepNumber(), 1); ellenőrizzük, hogy nem tudunk rossz mezőre lépni ellenőrizzük, hogy kétszer nem tudunk lépni ugyanarra a mezőre QCOMPARE(_model->getField(0, 0), TicTacToeModel::PlayerX); 34

Teszt eredmények 35

Teszt eredmények 36