gregor zorc avtomatsko preizkuŠanje grafi … · drugi in tretji parameter dolo čata poziciji...
TRANSCRIPT
Gregor Zorc
AVTOMATSKO PREIZKUŠANJE GRAFI ČNEGA UPORABNIŠKEGA VMESNIKA V OKOLJU WINDOWS
Diplomsko delo
Maribor, januar 2009
I
Diplomsko delo visokošolskega strokovnega študijskega programa
AVTOMATSKO PREIZKUŠANJE GRAFI ČNEGA UPORABNIŠKEGA VMESNIKA V OKOLJU WINDOWS
Študent: Gregor Zorc
Študijski program: VS ŠP Računalništvo in informatika
Smer: Programska oprema
Mentor: izr. prof. dr. Božidar POTOČNIK
Maribor, januar 2009
II
ZAHVALA
Mentorju za vodenje, družini za podporo
in Nini za motivacijo.
III
AVTOMATSKO PREIZKUŠANJE GRAFI ČNEGA
UPORABNIŠKEGA VMESNIKA V OKOLJU WINDOWS
Klju čne besede: preizkušanje programske opreme, avtomatsko preizkušanje, grafični uporabniški vmesnik, regresijsko preizkušanje UDK: 004.4.05 : 004.514 (043.2) Povzetek
Grafični uporabniški vmesnik omogoča uporabniku intuitivno interakcijo z aplikacijo s
pomočjo oken, menijev, različnih gumbov in drugih gradnikov. Avtomatizacija
preizkušanja takega vmesnika predstavlja svojevrsten izziv, saj pričakujemo, da bodo
programi za preizkušanje pravilno delovali tudi v primerih, ko se, denimo, spremenijo
dimenzije okna aplikacije. V pričujočem diplomskem delu obravnavamo načrtovanje in
implementacijo robustnega programa za preizkušanje grafičnega uporabniškega vmesnika
na osnovi že razvitih postopkov za dostop do gradnikov vmesnika. Za bolj intuitiven vnos
preizkusnih podatkov povezujemo implementirani program z elektronsko preglednico
orodja Excel. S preizkušanjem realne aplikacije ugotavljamo, da je po opisanem postopku
moč učinkovito preizkusiti grafične uporabniške vmesnike Windows-aplikacij, ki
uporabljajo standardne gradnike.
IV
AUTOMATED GRAPHICAL USER INTERFACE TESTING IN WINDOWS ENVIRONMENT Key words: software testing, automated testing, graphical user interface, GUI, regression testing UDK: 004.4.05 : 004.514 (043.2) Abstract
A graphical user interface (GUI) allows user an intuitive interaction with the application
using windows, menus, various buttons, and other components. Automation of such
interface testing presents a unique challenge, because we expect that testing programs will
work correctly even in the cases, when, for example, dimensions of window change. In this
diploma work we discuss planning and implementation of a robust GUI testing program
using already designed procedures for accessing GUI components. For a more intuitive
input of testing data we combine the implemented program with an electronic spreadsheet
tool Excel. By testing a real application we ascertain that proposed testing procedure
could be efficiently used for testing GUIs of Windows-based applications, which use
standard GUI components.
V
VSEBINA
1 UVOD ........................................................................................................................... 1
2 AVTOMATSKO PREIZKUŠANJE GRAFI ČNEGA UPORABNIŠKEGA
VMESNIKA ......................................................................................................................... 3
2.1 ORODJA ZA PREIZKUŠANJE GRAFIČNEGA UPORABNIŠKEGA VMESNIKA................... 4
3 AVTOMATSKO PREIZKUŠANJE APLIKACIJE ZA VODENJE U ČENCEV
GLASBENE ŠOLE.............................................................................................................. 6
3.1 OPIS APLIKACIJE..................................................................................................... 6 3.2 IMPLEMENTACIJA PROGRAMA ZA PREIZKUŠANJE GRAFIČNEGA UPORABNIŠKEGA
VMESNIKA .......................................................................................................................... 8 3.3 SNEMANJE INTERAKCIJE S PROGRAMOM................................................................. 9 3.4 OPTIMIZACIJA IZVORNE KODE ZAJETE INTERAKCIJE............................................. 14 3.5 IMPLEMENTACIJA PRIMERJAVE DEJANSKIH IN PRIČAKOVANIH REZULTATOV ........ 22
4 POVEZAVA PROGRAMA ZA PREIZKUŠANJE Z ORODJEM EXCEL .. ..... 29
4.1 IMPLEMENTACIJA RAZREDA EXCELADAPTER....................................................... 30 4.2 UPORABA RAZREDA EXCELADAPTER................................................................... 34
5 STATISTI ČNI REZULTATI PREIZKUŠANJA................................................... 36
5.1 DODAJANJE NOVEGA UČENCA .............................................................................. 36 5.2 SPOROČILNA OKNA ............................................................................................... 38 5.3 UREJANJE PREDMETA UČENCA.............................................................................. 40 5.4 UREJANJE RAZREDA UČENCA................................................................................ 44 5.5 NADALJNJI PREIZKUSI........................................................................................... 46
6 SKLEP........................................................................................................................ 47
VIRI .................................................................................................................................... 50
PRILOGE........................................................................................................................... 51
A. GENERIRANI PROGRAM ORODJA RANOREX............................................................... 51 B. PREGLEDNICA ORODJA EXCEL V FORMATU XML..................................................... 53 C. RAZRED EXCELADAPTER......................................................................................... 55 D. PROGRAM ZA PREIZKUŠANJE.................................................................................... 57
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 1
1 UVOD
Dosledno preizkušanje programske opreme je danes nepogrešljivi del praktično
vsakega projekta, ki želi zagotoviti kakovost in zanesljivost programske rešitve. V
preteklosti se je preizkušanje večinoma izvajalo ročno. Danes bi bila uporaba izključno
ročnega preizkušanja zaradi uvajanja večnivojskih arhitektur (angl. multitier architectures)
in porazdeljenih aplikacij predraga. Prav tako pa bi zaradi zamudnosti podaljšala razvoj
programske rešitve. K avtomatizaciji se je smiselno zateči tudi zaradi suhoparnosti ročnega
preizkušanja, ki dela preizkuševalca manj pozornega na morebitna odstopanja v delovanju
programa.
Avtomatsko preizkušanje predstavitvenega nivoja (angl. presentation layer) aplikacij
pridobiva na kompleksnosti šele v zadnjih letih zaradi uvajanja grafičnega uporabniškega
vmesnika. Ta uporabniku, za razliko od ukaznega načina, ki zahteva poznavanje ukazov za
izvedbo opravil, omogoča bolj intuitivno interakcijo z aplikacijo s pomočjo oken, menijev,
različnih gumbov in drugih gradnikov oz. kontrolnikov. Pravimo, da kontrolniki ob
interakciji prožijo dogodke (angl. events), pri čemer vsak dogodek predstavlja potencialen
vhod, na katerega se mora aplikacija pravilno odzvati in uporabniku ponuditi rezultate.
Zaradi te, t.i. dogodkovno vodene (angl. event-driven) narave aplikacij, predstavlja
preizkušanje programov, ki temeljijo na grafičnem uporabniškem vmesniku, svojevrsten
izziv.
Od programov za preizkušanje grafičnega uporabniškega vmesnika poleg informacij o
(logični) pravilnosti izhoda glede na podani vhod, mnogokrat zahtevamo tudi informacije o
pravilnosti prikaza kontrolnikov (npr. velikosti gumba in njegovega odmika od roba okna).
Pri tem si načeloma želimo, da bi bili programi za preizkušanje čimbolj robustni. Pomeni,
da znajo aplikacijo uspešno preizkusiti tudi v primerih, ko npr. spremenimo dimenzije
njenega okna ali povečamo pisavo. Tega programi, ki delujejo zgolj na osnovi primerjave
zaslonskih slik ne zmorejo. Robustnost programov za preizkušanje grafičnih uporabniških
vmesnikov je nujna tudi zato, ker je grafični uporabniški vmesnik načeloma podvržen
spremembam pogosteje kot poslovna logika [1].
V diplomski nalogi bomo prikazali razvoj programa za preizkušanje grafičnega
uporabniškega vmesnika. V 2. poglavju se bomo seznanili s programskimi produkti za
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 2
preizkušanje grafičnega uporabniškega vmesnika, ki so na voljo danes. Pretežni del 3.
poglavja bomo namenili implementaciji programa za preizkušanje grafičnega
uporabniškega vmesnika te aplikacije s pomočjo knjižnice orodja Ranorex. V 4. poglavju
bomo program za preizkušanje nadgradili tako, da bo preizkusne podatke lahko zajemal iz
elektronske preglednice orodja Excel. Zadnje poglavje pa namenjamo pregledu rezultatov
preizkušanja z implementiranim programi za preizkušanje grafičnega uporabniškega
vmesnika.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 3
2 AVTOMATSKO PREIZKUŠANJE GRAFI ČNEGA UPORABNIŠKEGA VMESNIKA
V diplomski nalogi se bomo osredotočili na avtomatsko preizkušanje grafičnega
uporabniškega vmesnika aplikacije, ki smo jo razvili za operacijski sistem Windows.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika je v tem sistemu praviloma
vezano na klice ustreznih funkcij programskega vmesnika operacijskega sistema Windows
[2] (angl. Windows Application Programming Interface, tudi WinAPI). Ena izmed takih
funkcij je denimo funkcija mouse_event s katero lahko posnemamo premik miške in
pritisk na njene gumbe. Preizkušana aplikacija interpretira informacije o akcijah z miško
na enak način kot bi z miško upravljal človek.
Testerji klice programskega vmesnika, sicer implementiranega v programskem jeziku
C, velikokrat povežejo s skriptnim (interpretiranim) jezikom (npr. z VBScript-om, Python-
om, Ruby-jem [3], ipd.), ki omogočajo hitrejši razvoj preizkusnih skript. Koda 2.1 kaže
primer klica funkcije mouse_event iz skriptnega jezika Python z uporabo razširitve PyWin.
import win32api import win32con ... win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOW N, 0, 0) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTTUP , 0, 0)
Koda 2.1: Skript v jeziku Python, ki upravlja z miško s pomočjo WinAPI-funkcije mouse_event.
Gornji skript simulira pritisk na gumb miške, in sicer tako, da izvede pritisk na levi
miškin gumb (MOUSEEVENTF_LEFTDOWN) in ga nato sprosti
(MOUSEEVENTF_LEFTTUP). Drugi in tretji parameter določata poziciji koordinat, kjer
naj se klik izvede. V našem primeru se je klik izvedel na trenutni poziciji miškinega
kurzorja. Opazimo tudi lahko, da sta obe koordinati enaki nič.
Zaradi kompleksnosti, ki bi jo zahtevala implementacija lastnih postopkov za
programsko upravljanje z različnimi kontrolniki grafičnega uporabniškega vmesnika, smo
se v našem primeru odločili, da raje posežemo po namenskih orodjih za preizkušanje.
Skriptni jeziki teh orodij praviloma vsebujejo ovojnice (angl. wrappers) za funkcije
vmesnika WinAPI ter funkcije za dostop do specifičnih gradnikov vmesnika, ki pohitrijo
implementacijo skript za preizkušanje. Poleg skriptnega jezika ponujajo orodja za
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 4
preizkušanje grafičnega uporabniškega vmesnika še ostale funkcionalnosti, ki jih bomo
predstavili v nadaljevanju.
2.1 Orodja za preizkušanje grafičnega uporabniškega vmesnika
Pri izbiri programskega produkta za preizkušanje uporabniškega vmesnika, smo se
osredotočili na naslednja orodja: WinRunner [4] in QuickTest Professional [5] podjetja HP,
Ranorex [6] podjetja Ranorex ter TestComplete [7] podjetja AutomatedQA. Pri tem smo
želeli, da programski produkt zadosti naslednjim kriterijem:
• programski produkt mora poleg prestrezanja in predvajanja nuditi tudi možnost
urejanja zajetih akcij,
• skriptni jezik orodja mora biti dovolj zmogljiv; idealno bi bilo, da bi temeljil na že
uveljavljenem skriptnem oz. programskem jeziku,
• dokumentacija programskega produkta in podpora zanj morata biti kvalitetni.
Večina profesionalnih programskih produktov za preizkušanje grafičnih uporabniških
vmesnikov združuje postopek prestrezanja in predvajanja uporabnikovih akcij s skriptnim
jezikom. Rezultat prestrezanja je torej programska koda, ki jo je moč ročno urejati. To
seveda pomeni, da lahko zajemanje akcij izpustimo in sekvenco, ki bo predvajana, v celoti
napišemo sami. Izkaže se, da je poseganje v programsko kodo sekvence pri večini
preizkusov pravzaprav nujno in se mu lahko izognemo le pri izdelavi najbolj trivialnih
preizkusov.
Vsi programski produkti, ki smo jih preizkusili, podpirajo prestrezanje in predvajanje
uporabnikov akcij. Prestrezanje je pri vseh prav tako podprto s skriptnim (tj.
interpretiranim) jezikom. Orodje Ranorex poleg skriptnega jezika Python (različice 2.3, 2.4
in 2.5) podpira še prevajane programske jezike C++ , C# in Visual Basic.NET. Orodje
WinRunner uporablja lasten skriptni jezik Test Script Language (TLL), preostali pa se tako
kot orodje Ranorex opirajo na enega ali več že uveljavljenih jezikov. Orodje QuickTest
Professional tako uporablja skriptni jezik VBScript. Tega poleg skriptnih jezikov JScript-
a, DelphiScript-a, C++Script-a in C#Script-a podpira tudi orodje TestComplete.
Opozorimo na razliko med C#Script-om (TestComplete) in C#-om (Ranorex). Medtem ko
prvi temelji na bolj znanem skriptnem jeziku JScript, je programska koda, ki jo tvori
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 5
orodje Ranorex, v celoti združljiva z Microsoftovim ogrodjem .NET. To pomeni, da imamo
pri implementaciji preizkusov z orodjem Ranorex proste roke pri izbiri integriranega
razvojnega okolja oz. natančneje, prevajalnika. Edini pogoj je združljivost slednjega z
ogrodjem .NET 1.1 ali 2.0 in vključitev knjižnice DLL orodja Ranorex ob prevajanju
programske kode sekvence akcij. Na omenjeni knjižnici temeljijo tudi skripti za skriptni
jezik Python orodja Ranorex, ki jih poženemo z okenskim interpreterjem za Python.
Prednost uporabe skriptnega jezika Python pred prevajanimi jeziki je seveda v tem, da
skripta ne rabimo prevesti, kadar spremenimo izvorno kodo.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 6
3 AVTOMATSKO PREIZKUŠANJE APLIKACIJE ZA VODENJE UČENCEV GLASBENE ŠOLE
Teoretična znanja, ki smo jih o avtomatskem preizkušanju opisali v prejšnjem poglavju,
smo v praksi uporabili pri preizkušanju programa Glasovir. Program je namenjen vodenju
podatkov o učencih, osebju in dejavnostih, povezanih z delovanjem glasbene šole. Zahteva
naročnika je bila, da se na osnovi vnesenih podatkov tvorijo poročila. Ta so namenjena
bodisi za interno rabo ali pa sovpadajo s tistimi, ki jih ob koncu šolskega leta zahteva
Statistični urad RS.
3.1 Opis aplikacije
Program Glasovir smo razvili s programskim jezikom C# in temelji na Microsoftovi
platformi .NET (verzija 1.1). Deluje pod operacijskim sistemom Windows. Grafični
uporabniški vmesnik tega produkta smo razdelili v več zavihkov (npr. zavihki Učenci,
Učitelji, Izpiti, Poročila) s podobno funkcionalnostjo. Razen zavihka Poročila in
Napredno vsebujejo zavihki vsaj en seznam (tipa ListView), ki mu je moč dodati nove
elemente. Slika 3.1 prikazuje primer takega seznama.
Zavihki s seznami lahko vsebujejo tudi enega ali več podrejenih seznamov. V primeru
zavihka Predmeti, ki ga prikazuje zgornja slika, je seznamu predmetov podrejen seznam
učiteljev, ki predmet poučujejo. Podrejeni seznam se ustrezno napolni ob kliku na element
glavnega seznama. V primeru klarineta podrejeni seznam pokaže učitelja s šiframa 83 in
69. Po dodajanju novega, ali urejanju že obstoječega elementa, se vrstica seznama, ki
vsebuje podatke tega elementa, samodejno označi. To uporabniku omogoča dodajanje
novega vnosa v podrejeni seznam brez poprejšnjega izbiranja elementa v nadrejenem
seznamu. Kot je razvidno s kontekstnega menija (Slika 3.1), lahko uporabnik poleg
dodajanja in urejanja, izvaja tudi brisanje elementov. Isti kontekstni meni prikažejo tudi
podrejeni seznami.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 7
Slika 3.1: Grafični uporabniški vmesnik programa Glasovir: zavihek s seznamom predmetov.
Dodajanje in urejanje elementa prikažeta, glede na izbrani seznam, vedno isto
pogovorno okno. Slika 3.2 kaže primer takega okna.
Slika 3.2: Pogovorno okno za dodajanje novega predmeta.
Pogovorna okna v nekaterih primerih, glede na uporabnikovo izbiro, onemogočijo
uporabo določenih kontrolnikov. Pogovorno okno za dodajanje novega predmeta (Slika
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 8
3.2), na primer, onemogoči uporabo spustnega seznama za izbiro vrste skupine, če je
uporabnik izbral predmet.
Na napake pri vnosu program Glasovir opozarja s sporočilnimi okni. Slika 3.3 kaže
primer takega sporočilnega okna.
Slika 3.3: Sporočilo o napaki pri vnosu podatkov.
V nadaljevanju bomo prikazali implementacijo programa za preizkušanje ene izmed
funkcionalnosti programa Glasovir s pomočjo orodja Ranorex.
3.2 Implementacija programa za preizkušanje grafičnega uporabniškega vmesnika
Funkcionalnosti grafičnega uporabniškega vmesnika programa Glasovir, ki smo jih
želeli preizkusiti, so bile naslednje:
• konsistentnost podatkov v seznamih in pogovornih oknih ter samodejno
označevanje vrstice seznama po dodajanju/urejanju elementa,
• onemogočanje kontrolnikov pogovornega okna v povezavi z uporabnikovo izbiro
in
• prikazovanje sporočilnih oken.
Podrobnejše opise naštetih funkcionalnosti podajamo v prejšnjem poglavju. Za
preizkušanje grafičnega vmesnika smo uporabili programsko orodje Ranorex, in sicer tako,
da smo:
1. zajeli oz. posneli akcije z miško in tipkovnico,
2. po potrebi optimizirali izvorno kodo dobljenega zaporedje programskih vnosov iz
tipkovnice in klikov miške ter
3. v kodo vgradili primerjavo dejanskih in pričakovanih podatkov s pomočjo knjižnice
RanorexNet.dll.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 9
Na koncu smo po prevajanju izvorne kode dobili samostojni program za preizkušanje,
ki najprej ponovi posneto zaporedje korakov, opravi primerjavo dejanskih in pričakovanih
rezultatov ter izpiše na zaslon kratko poročilo o uspešnosti preizkušanja.
V nadaljevanju se bomo osredotočili na implementacijo najbolj kompleksnega izmed
programov za preizkušanje funkcionalnosti grafičnega uporabniškega vmesnika, tj.
programa za preizkušanje konsistentnosti podatkov v seznamih in pogovornih oknih.
3.3 Snemanje interakcije s programom
Prvi korak pri implementaciji programa za preizkušanje konsistentnosti podatkov v
seznamih in pogovornih oknih je bil ta, da smo s snemalnikom orodja Ranorex posneli
interakcijo s pogovornim oknom programa Glasovir. Podajmo postopek za zajemanje akcij
ob vnosu novega učenca iz pogovornega okna:
1. Poženemo RanorexRecorder, v našem primeru je bil nameščen v direktoriju
C:\Program Files\Ranorex 1.5.1\Bin.
2. S klikom na gumb Record v razdelku Actions sprožimo prestrezanje. Program se ob
tem minimira v območje za obvestila, tj. območje z uro na desni strani opravilne
vrstice (Slika 3.4).
3. Poženemo program Glasovir.
4. S klikom na desni miškin gumb v seznamu učencev prikličemo kontekstni meni in
izberemo Dodaj.
5. Pojavi se pogovorno okno za dodajanje novega učenca. Vnesemo zahtevane
podatke (ime, priimek, spol, stalno prebivališče itd.) in kliknemo Dodaj. Novo
dodani učenec se bo pokazal v seznamu.
6. Zajemanje prekinemo s klikom na ikono RanorexRecorder-ja v območju za
obvestila.
Slika 3.4: Sporočilo orodja RanorexRecorder o pričetku zajemanja.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 10
Po končanem zajemanju se v tabeli pod zavihkom Actions prikažejo vse akcije, ki smo
jih izvedli s tipkovnico in/ali miško (Slika 3.5). Vnosi iz tipkovnice imajo zabeleženo
trajanje tipkanja (stolpec Time) ter niz tipk (stolpec Text), ki so bile pritisnjene. Akcije z
miško v stolpcu Time prikazujejo trajanje poti, ki jo miškin kurzor opravi med
koordinatama. V stolpcu Text pa so podana imena forme, kontrolnika in elementa. Ta
hierarhija (angl. form/control/element) je dodana za lažjo preglednost. S slike (Slika 3.5) je
razvidno tudi, da smo v zadnjem koraku kliknili gumb Dodaj, ki je del pogovornega okna
za dodajanje in urejanje učencev. Med pomembnejšimi podatki pri akcijah z miško, sta v
tej tabeli še koordinati dotika (tj. položaj na zaslonu, kjer je bil izveden klik - stolpec
Position) in ročica (stolpec Handle) okna/kontrolnika.
Slika 3.5: Seznam vseh izvedenih akcij z miško in tipkovnico.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 11
Posamezne akcije, prikazane v tabeli Actions, sovpadajo z datoteko XML, ki jo orodje
RanorexRecorder tvori med zajemanjem. Po uspešno končanem zajemanju, je vsebina te
datoteke prikazana v zavihku XML (Slika 3.6).
Slika 3.6: Zajete akcije v obliki generirane datoteke XML.
Če želimo zgolj modificirati katero izmed zajetih akcij z miško ali tipkovnico in se tako
izogniti ponovnemu zajemanju, tega žal ne moremo storiti iz tabele Actions. Iz nje lahko
posamezne akcije z uporabo gumba Delete Action zgolj brišemo. Za spreminjanje akcij s
tipkovnico in/ali miško moramo zato poseči v datoteko XML. Koda 3.1 podaja njeno
strukturo.
<RanorexRecorder> <Version>1.5.1.4066</Version> <Speed>10</Speed> <Cycle>1</Cycle> <Records>
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 12
<!-- Koraki prestrezanja. --> <Records> </RanorexRecorder>
Koda 3.1: Struktura datoteke XML, ki jo generira or odje za zajemanje RanorexRecorder.
Pomembne so značke Speed, Cycle in Records. S prvo določimo hitrost predvajanja in
je preslikava drsnika Speed v razdelku Actions. Privzeta vrednost te značke je 10, kar
ustreza vrednosti 1 v drsniku, in predstavlja premikanje miške in tipkanje v realnem času.
Nižje vrednosti (najnižja je 1) predstavljajo upočasnitev gibanja, višje (najvišja je 100) pa
pohitritev. Značka Cycle ustreza istoimenskemu vnosnemu polju v razdelku Actions,
določa pa število ponovitev zajete sekvence.
Znotraj značke Records se nahajajo definicije vseh zajetih akcij miške in tipkovnice. To
mesto je v izvlečku izvorne kode (glej Koda 3.1) označeno kot <!-- Koraki prestrezanja. --
> . Vsaka od definicij posamezne akcije se nahaja v znački <Record>. Koda 3.2 kaže
strukturo zapisa v primeru akcije z miško:
<Record> <Message Id="513" Time="3261" Point="420,588" / > <Form Title="U čenec" ClassName="WindowsForms10.Window.8.app3" Handle="264104" Point="279,427" /> <Control Name="btnDodaj" Text="Dodaj" Id="19882 0" ClassName="WindowsForms10.BUTTON.app3" Instance="4" Handle="198820" Point="39,11" Par entName="FrmUcenec" /> <Element Role="43" Name="Dodaj" ClassName="Wind owsForms10.BUTTON.app3" Position="381,577,456,600" Point="39,11" /> <Keystrokes Keys="" Count="0" /> </Record>
Koda 3.2: XML-zapis akcije z miško.
Pomembnejši elementi, tj. Name, Text, Handle in Point (Position v tabeli) ustrezajo že
podanim opisom stolpcev v tabeli zavihka Actions.
Struktura zapisa v primeru vnašanja s tipkovnico je podobna (glej Koda 3.3).
<Record> <Message Id="256" Time="18346" Point="0,0" /> <Form Title="" ClassName="" Handle="0" Point="0 ,0" /> <Control Name="" Text="" Id="0" ClassName="" In stance="0" Handle="0" Point="0,0" ParentName="" /> <Element Role="0" Name="" ClassName="" Position ="0,0,0,0" Point="0,0" /> <Keystrokes Keys="1234{TAB}{SHIFTDOWN}N{SHIFTUP}ovak{TAB}{SHIFT DOWN}J{SHIFTUP} anez{TAB}{TAB}{SHIFTDOWN}S{SHIFTUP}lovena{BACK SPACE}ska{SPACE}5{TAB}
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 13
{SHIFTDOWN}" Count="39" /> </Record>
Koda 3.3: XML-zapis akcije s tipkovnico.
RanorexRecorder v celoti posnema način vnosa, ki smo ga uporabili pri izpolnjevanju
pogovornega okna. V našem primeru smo se namesto s klikanjem, med vpisnimi polji
premikali s tabulatorjem. To je razvidno tudi iz vrednosti atributa Keys (niz {TAB}) v
gornjem izvlečku izvorne kode. Niza {SHIFTDOWN} in {SHIFTUP} podobno označujeta
pritisk oz. sprostitev dvigalke (angl. shift). Orodje RanorexRecorder je pravilno zaznalo
tudi uporabo brisalke (angl. backspace). Slednje se nam je v našem primeru zdelo odveč,
saj nam je bilo bistveno preizkusiti ali vneseni podatki sovpadajo s tistimi, ki se po zaprtju
pogovornega okna prikažejo v seznamu. Da sekvence ne bi rabili posneti še enkrat, smo se
odločili, da generirano datoteko XML ročno spremenimo. Žal pa dobljene XML-datoteke
ni moč spreminjati neposredno iz orodja RanorexRecorder. Datoteko smo zato najprej
shranili s klikom na gumb Save v direktorij, ki smo ga določili pod Location v razdelku
Record. Datoteko XML smo nato odprli s tekstovnim urejevalnikom in izbrisali niz
a{BACKSPACE} (glej Koda 3.3). Opozorimo, da moramo pri spreminjanju atributa Keys
pod atributom Count posodobiti morebitno spremenjeno število pritiskov na tipkovnico. Z
zmanjšanim številom pritiskov se ustrezno zmanjša tudi čas tipkanja, zato smo ustrezno
posodobili tudi vrednost atributa Time. Koda 3.4 podaja spremenjeno različico izvorne
kode 3.4:
<Record> <Message Id="256" Time="18345" Point="0,0" /> <Form Title="" ClassName="" Handle="0" Point="0 ,0" /> <Control Name="" Text="" Id="0" ClassName="" In stance="0" Handle="0" Point="0,0" ParentName="" /> <Element Role="0" Name="" ClassName="" Position ="0,0,0,0" Point="0,0" /> <Keystrokes Keys="1234{TAB}{SHIFTDOWN}N{SHIFTUP}ovak{TAB}{SHIFT DOWN}J{SHIFTUP} anez{TAB}{TAB}{SHIFTDOWN}S{SHIFTUP}lovenska{SP ACE}5{TAB} {SHIFTDOWN}" Count="37" /> </Record>
Koda 3.4: XML-zapis akcije s tipkovnico, pri čemer smo odstranili pritisk na tipko backspace.
Izvedene akcije se zaenkrat nahajajo v obliki datoteke XML, ki jo zna orodje
RanorexRecorder predvajati in tako ponoviti akcije uporabnika (tj. vnesti novega učenca v
program Glasovir). S pomočjo datoteke XML lahko torej predvajamo zajete akcije, ne
moremo pa vgraditi primerjave pričakovanih in dejanskih rezultatov, ki so v našem
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 14
primeru povezani z vnašanjem novega učenca. V nadaljevanju bomo na osnovi dobljene
datoteke XML tvorili izvorno kodo programskega jezika C# in jo optimizirali. Tako bomo
dobili osnovo za kasnejšo implementacijo primerjave pričakovanih in dejanskih rezultatov
preizkušanja.
3.4 Optimizacija izvorne kode zajete interakcije
Za vgradnjo avtomatizirane primerjave rezultatov moramo dobljeno (in po potrebi
spremenjeno) datoteko XML najprej pretvoriti v programsko kodo. To lahko storimo
bodisi tako, da v uporabniškem vmesniku orodja RanorexRecorder kliknemo gumb Play v
razdelku Actions, ali pa program poženemo iz ukazne vrstice in kot prvi argument podamo
ime datoteke XML, npr. RanorexRecorder.exe posneta_sekvenca.xml.
Orodje prične s predvajanjem posnete sekvence tako, da se ponovno minimira v
območje za obvestila in izpiše Replaying recorded actions. Po končanem predvajanju
(izpiše se sporočilo Replaying Finished) se program maksimira in nam v zavihkih C#,
Python in C++ ponudi programsko kodo. V našem primeru smo uporabili izvorno kodo
programskega jezika C#, ki jo bomo v nadaljevanju najprej optimizirali ter ji na koncu
vgradili primerjavo pričakovanih in dejanskih rezultatov.
Generirano kodo smo najprej skopirali v nov projekt, ki smo ga z Microsoftovim
razvojnim okoljem Visual Studio 2003 ustvarili po naslednjem postopku:
1. V pogovornem oknu New Project (File, New, Project...) smo pod Project Types
izbrali Visual C# Projects.
2. Izmed ponujenih predlog (Templates) na desni smo izbrali konzolno aplikacijo
(Console Application) kot prikazuje slika (Slika 3.7).
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 15
Slika 3.7: Ustvarjanje novega projeta z Visual Studiem 2003.
3. Projekt smo poimenovali (Name) in mu dodelili mesto na trdem disku (Location).
4. Po kliku na gumb OK smo vsebino datoteke Class1.cs zamenjali z izvorno kodo, ki
jo je generiral RanorexRecoder.
5. Da bi prevajalnik lahko prepoznal imenski prostor Ranorex, smo z desnim klikom
na References v drevesu Solution Explorerja priklicali kontekstni meni in kliknili
na Add Reference... (Slika 3.8)
Slika 3.8: Kontekstni meni za dodajanje reference.
6. Odprlo se je pogovorno okno Add Reference (Slika 3.9).
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 16
Slika 3.9: Pogovorno okno za dodajanje reference obstoječemu projektu.
7. S klikom na gumb Browse smo odprli pogovorno okno Select Component (Slika
3.10) in izbrali datoteko RanorexNet.dll v direktoriju C:\Program Files\Ranorex
1.5.1\Bin\Net1.1.
Slika 3.10: Pogovorno okno za izbiro želene datoteke dll.
8. Izbrana datoteka se je pojavila v seznamu Selected Components (Slika 3.11)
pogovornega okna Add Reference, ki smo ga nato s klikom na gumb OK zaprli.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 17
Slika 3.11: Po dodajanju Ranorexove reference.
9. Po dodani referenci smo morali določiti še izhodni direktorij. Z desnim klikom na
projekt v drevesu Solution Explorerja smo priklicali kontekstni meni in kliknili
Properties (Slika 3.12).
Slika 3.12: Kontekstni meni za dostopanje do lastnosti izbranega projekta.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 18
10. Odprlo se je pogovorno okno ime_projekta Property Pages. V drevesu na desni
smo izbrali Configuration Propetries, Build. Kot izhodni direktorij Output Path pa
nato določili C:\Program Files\Ranorex 1.5.1\Bin\Net1.1 (Slika 3.13)
Slika 3.13: Določanje izhodne poti za prevedeno izvorno kodo.
11. Generirana izvorna koda se je s klikom na gumb Build, Build Solution uspešno
prevedla.
Če prevedeni konzolni program poženemo, le-ta izvede posnete akcije na isti način kot
jih je prej izvedlo orodje RanorexRecorder ob podpori generirane datoteke XML. Pri
izvajanju program v konzolo izpisuje informacije o korakih, ki jih trenutno izvaja. Slika
3.14 prikazuje uspešno izvedeni konzolni program, ki s posnemanjem prej zajetih
uporabnikov akcij v programu Glasovir doda novega učenca.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 19
Slika 3.14: Izpis generiranega konzolnega programa, ki simulira vnos novega učenca.
Preden generirano izvorno kodo optimiziramo in vanjo vgradimo primerjavo
rezultatov, si oglejmo del kode (glej Koda 3.6), ki izvede pritisk na gumb Dodaj v
pogovornem oknu za dodajanje novega učenca:
form = Application.FindForm("U čenec", SearchMatchMode.MatchExact, "WindowsForms10.Window.8.app3", false, (int)(timeSc ale*5000)); form.Activate(); control = form.FindControlName("btnDodaj"); control.Focus(); controlElement = control.Element; element = controlElement.FindChild(Role.PushButto n, "Dodaj", null, new Point(240, 416)); Mouse.ClickElement(element, MouseButtonType.LeftB utton, new Point(39, 11), 1, (int)(timeScale*543));
Koda 3.6: Akcija z miško v kodi programskega jezika C#, kot jo je generiralo orodje RanorexRecorder.
Spremenljivka control je v gornjem primeru tipa Control, form pa tipa Form.
Opozorimo, da sta le-ti del imenskega prostora (angl. namespace) Ranorex in ne
System.Windows.Forms, kakor bi lahko sklepali iz njunih imen. Seveda je razlika tudi v
metodah. V gornjem primeru vidimo denimo klic metode
Ranorex.Form.FindControlName. Ta vrne kontrolnik trenutno izbrane forme glede na
podano ime (btnDodaj). V našem primeru je izbrana forma pogovorno okno za dodajanje
oz. urejanje učenca. To je naslovljeno z Učenec, kot je razvidno iz prvega parametra klica
metode FindForm. Z drugim parametrom določimo način ujemanja imena forme. V našem
primeru (MatchExact) je orodje RanorexRecorder zahtevalo, da se podani niz, tj. Učenec v
celoti ujema z imenom forme. Naslednji parameter (WindowsForms10.Window.8.app3) je
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 20
razredno ime (angl. class name) kontrolnika. S četrtim parametrom podamo ali naj
kontrolnik postane aktiven, zadnji pa določa časovno omejitev (v milisekundah) pri iskanju
forme (spremenljivka timeScale ima privzeto vrednost 1.0).
Iskanje elementa znotraj izbranega kontrolnika (tj. gumba btnDodaj) v nadaljevanju je
odvečno. Orodje Ranorex namreč ponuja metodo Mouse.ClickControl(Control kontrolnik).
Ta nam v primeru gumba prihrani dostopanje do edinega elementa, ki skrbi za izvedbo
klika. Primer nujnega dostopa do elementa s pomočjo metode FindChild je denimo pogled
v obliki seznama (angl. list view), kjer vrstice seznama predstavljajo posamezne elemente,
kakor bomo pokazali v nadaljevanju. Upoštevajoč to dejstvo, lahko klik na gumb za
dodajanje učenca zapišemo kot Mouse.ClickControl(control). Namesto metode
Application.FindForm lahko v primerih, ko so pogovorna okna enolično poimenovana,
uporabimo metodo Application.FindFormTitle. Ta prejme ime pogovornega okna kot prvi
parameter. Koda 3.7 podaja primer optimizirane izvorne kode:
form = Application.FindFormTitle("U čenec"); form.Activate(); control = form.FindControlName("btnDodaj"); Mouse.ClickControl(control);
Koda 3.7: Optimizirani del izvorne kode, ki najde in pritisne gumb za dodajanje novega učenca.
Oglejmo si še del generirane izvorne kode (glej Koda 3.8) za primer vnosa iz
tipkovnice na osnovi podane XML-datoteke (glej Koda 3.3):
Application.SendKeys("1234{TAB}{SHIFTDOWN}N{SHIFTUP }ovak{TAB}{SHIFTDOWN}J{SHIFTUP} anez{TAB}{TAB}{SHIFTDOWN}S{SHIFTUP}lovenska{SPAC E}5{TAB}{SHIFTDOWN}", 41);
Koda 3.8: Generirana koda programskega jezika C# na osnovi akcije s tipkovnico.
Vidimo, da je prvi parameter metode Application.SendKeys, tj. niz
1234{TAB}{SHIFTDOWN}... enak vrednosti atributa Keys znotraj elementa Keystrokes v
datoteki XML. Drugi parameter (41) določa dolžino intervala (v milisekundah) med dvema
pritiskoma tipke. V našem primeru (Koda 3.9) smo se zadovoljili s privzeto vrednostjo, tj.
5 milisekund in vsakič klicali enoparametersko obliko metode.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 21
Application.SendKeys("1234{TAB}{SHIFTDOWN}N{SHIFTUP }ovak{TAB}{SHIFTDOWN}J{SHIFTUP} anez{TAB}{TAB}{SHIFTDOWN}S{SHIFTUP}lovenska{SPAC E}5{TAB}{SHIFTDOWN}");
Koda 3.9: Primer klica enoparameterske oblike metode SendKeys.
Izvorna koda programa, ki jo je generiralo orodje RanorexRecorder, je na voljo v
prilogi tega diplomskega dela. Koda 3.10 podaja optimizirano različico:
using System; using System.Drawing; using Ranorex; namespace RanorexTestApplication { class Program { [STAThread] static int Main(string[] args) { try { Form form; Control control; Control parent; float timeScale = 1.0f; Application.ErrorAsException = tr ue; Element.IgnoreInvisible = true; form = Application.StartWindowsApplication(@"D:\glasovir\b in\ glasovir.exe", null, (int)(timeScale*5000)); parent = form.FindControlName("ta bUcenci"); control = parent.FindControlName( "listUcenci"); control.Focus(); Mouse.ClickControl(control, Mouse ButtonType.RightButton); Application.PopupMenuSelectItem(" Dodaj",(int)(timeScale*275)); Application.SendKeys("1234{TAB}{S HIFTDOWN}N{SHIFTUP}ovak{TAB} {SHIFTDOWN}J{SHIFTUP}anez{TAB}{TAB}{SHIFTDOWN}S{SH IFTUP} lovenska{SPACE}5{TAB}{SHIFTDOWN} ", 41); Application.SendKeys("S{SHIFTUP}p odnji{SPACE}{SHIFTDOWN}K {SHIFTUP}ašelj{TAB}1.1.1990{TAB}{SHIFTDOWN}S{SHIFT UP}podnji {SPACE}{SHIFTDOWN}K{SHIFTUP}ašel kj{BACKSPACE}", 35); Application.SendKeys("{BACKSPACE} j{TAB}555{NUMPADSUB}763{TAB} {TAB}{TAB}1.9.2008", 71); form = Application.FindFormTitle( "Učenec"); control = form.FindControlName("b tnDodaj"); Mouse.ClickControl(control); return 0; } catch (RanorexException e)
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 22
{ return 1; } } } }
Koda 3.10: Optimizirana izvorna koda programa, ki "zaigra" vstavljanje novega učenca.
Optimizirana izvorna koda, ki izvede vstavljanje novega učenca v program Glasovir,
predstavlja ogrodje na osnovi katerega bomo v nadaljevanju implementirali program za
preizkušanje konsistentnosti podatkov pogovornega okna in seznama.
3.5 Implementacija primerjave dejanskih in pri čakovanih rezultatov
Upoštevajoč dejstvo, da mora program Glasovir po vnosu podatkov označiti in
fokusirati vrstico z vnesenim učencem, bomo izvorno kodo iz prejšnjega poglavja
nadgradili tako, da bo program učenca po vnosu najprej poiskal v seznamu in preveril, ali
je označen. Pravilnost podatkov pa bo nato določil tako, da bo podatke iz vrstice seznama
primerjal s tistimi, ki so bili vneseni v pogovorno okno za dodajanje novega učenca.
Izvorno kodo za dostop do seznama z učenci (parent.FindControlName("listUcenci"))
nam je generiralo že orodje RanorexRecorder. Do vrstice seznama nato dostopamo s
pomočjo metode FindChild, ki jo izvršimo nad seznamom učencev (glej Koda 3.11).
Element iskanaVrstica = listUcenci.Element.FindCh ild(Role.ListItem, sifra);
Koda 3.11: Dostop do vrstice seznama.
Prvi parameter metode FindChild je vloga (podatkovni tip Role) elementa. V našem
primeru je to vrstica seznama (ListItem). Kot drugi parameter zahteva metoda FindChild
ime iskanega elementa. Ime elementa je v primerih, ko dostopamo do vrstic seznama,
enako kar vrednosti, ki je zapisana v prvem stolpcu. V našem primeru (glej Koda 3.11) je
to šifra učenca, ki jo metodi FindChild podamo s parametrom sifra tipa string.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 23
Slika 3.15: Prikaz stanja vrstice seznama z orodjem RanorexSpy.
Potem, ko spremenljivka iskanaVrstica vsebuje referenco na vrstico seznama, ki
ustreza podatkom vstavljenega učenca, lahko v skladu z zahtevami naročnika preverimo,
ali je ta vrstica tudi izbrana in fokusirana. "Izbranost" predstavlja eno izmed možnih stanj
elementa kontrolnika. Pri tem se lahko element kontrolnika nahaja v več stanjih hkrati. Z
orodjem RanorexSpy, ki prikaže informacije o aktivnih elementih uporabniškega
vmesnika, tako ugotovimo, da je vrstica seznama po uspešnem vnosu novega učenca v
stanjih selected, focused, selectable, focusable in multiple selectable (Slika 3.15).
Preverjanje možnih stanj elementa orodje Ranorex rešuje s pomočjo zastavic, in sicer
tako, da z bitnim ali primerjamo stanje elementa z ustrezno vrednostjo vgrajenega
naštevnega tipa State. V našem primeru smo tako napisali spodnjo metodo, ki vrne logično
vrednost true, če je vrstica hkrati izbrana in fokusirana:
private bool JePravilnoStanjeVrstice(Element vrst ica) { return ((vrstica.State & State.Selected) != 0 && (vrstica.State & State.Focused) != 0); }
Koda 3.12: Metoda, ki vrne logično vrednost true, če je vrstica seznama izbrana in fokusirana.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 24
Če program deluje pravilno, bo po vnosu učenca metoda JePravilnoStanjeVrstice za
spremenljivko iskanaVrstica (glej Koda 3.12) vrnila logično vrednost true.
Sledila je implementacija primerjave podatkov v vrstici seznama s tistimi, ki so bili
vneseni iz pogovornega okna za dodajanje in urejanje učenca (Slika 3.16). Vhodne podatke
(tj. tiste, ki so bili vneseni iz pogovornega okna) smo vnesli v slovar vhodov, izhodne (tj.
tiste, ki so se prikazali v vrstici seznama) pa v slovar izhodov. Oba slovarja sta bili
spremenljivki vgrajene podatkovne strukture StringDictionary.
Slovar vhodov napolnimo preden program za preizkušanje pritisne gumb za potrditev
vnosa novega učenca. To storimo tako, da v slovar zapišemo vsebino vseh vpisnih polj
(šifra, ime, priimek itd.), spustnega seznama (status) in vrednosti obeh izbirnih gumbov
(spol, privatni učenec). Podajmo izvorno kodo metode za polnjenje slovarja vhodov:
private void NapolniSlovarVhodov(Form form) { slovarVhodov.Add("šifra", form.FindControlName(" tbSifra").Text); slovarVhodov.Add("priimek", form.FindControlName ("tbPriimek").Text); slovarVhodov.Add("ime", form.FindControlName("tb Ime").Text); slovarVhodov.Add("ulica", form.FindControlName(" tbUlica").Text); slovarVhodov.Add("kraj", form.FindControlName("t bKraj").Text); slovarVhodov.Add("datum rojstva", form.FindControlName("tbDatumRojstva").Text); slovarVhodov.Add("kraj rojstva", form.FindControlName("tbKrajRojstva").Text); slovarVhodov.Add("datum vpisa", form.FindControlName("tbDatumVpisa").Text); slovarVhodov.Add("telefon", form.FindControlName ("tbTelefon").Text); slovarVhodov.Add("status", form.FindControlName( "cbStatus").Text); slovarVhodov.Add("spol", JeIzbranGumb(form, "rbM oski") ? "M" : "Ž"); slovarVhodov.Add("privat", JeIzbranGumb(form, "r bJePrivat") ? "Da" : "Ne"); }
Koda 3.13: Metoda, ki vsebino pogovornega okna zapiše v slovar vhodov.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 25
Slika 3.16: Pogovorno okno za dodajanje novega učenca.
Koda 3.13 kaže, da do besedila v vpisnih poljih (tbSifra, tbPriimek itd.) in v spustnem
seznamu cbStatus, dostopamo s pomočjo lastnosti Text izbranega kontrolnika. Referenco
na kontrolnik (tj. na vpisna polja, spustni seznam in izbirne gumbe) dobimo z metodo
FindControlName, ki jo izvršimo nad objektom tipa Form. Slednjega zahteva metoda na
vhodu in predstavlja referenco na pogovorno okno za dodajanje novega učenca.
Za dostop do vrednosti izbirnih gumbov (angl. radio button), moramo kontrolnik
pretvoriti (angl. cast) v tip RadioButton, ki vsebuje lastnost Checked. Ta nam pove, ali je
dani izbirni gumb izbran ali ne. Pretvorbo kontrolnika in določanje izbranosti smo združili
v metodi JeIzbranGumb (glej Koda 3.14).
private bool JeIzbranGumb(Form form, string gumb) { return ((RadioButton)form.FindControlName(gumb)) .Checked; }
Koda 3.14: Metoda, ki vrne logično vrednost true, če je izbirni gumb pogovornega okna izbran.
Potem, ko se metoda NapolniSlovarVhodov uspešno izvrši, vsebuje spremenljivka
slovarVhodov vrednosti vseh kontrolnikov pogovornega okna, ki jim uporabnik lahko
(potencialno) spreminja vrednost.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 26
Izhodni slovar napolnimo z vrednostmi iz vrstice seznama, ki je bila seznamu dodana
po uspešnem vnosu novega učenca. Koda 3.15 podaja metodo za polnjenje izhodnega
slovarja.
private void NapolniSlovarIzhodov(Element vrstica ) { slovarIzhodov.Add("Šifra", vrstica.Name); string [] niziPodpicja = vrstica.Description.Spl it(';'); foreach (string niz in niziPodpicja) { string [] nizDvopicje = niz.Split(':'); slovarIzhodov.Add(nizDvopicje[0].Trim(), nizDvo picje[1].Trim()); } }
Koda 3.15: Metoda, ki vsebino vrstice seznama zapiše v slovar izhodov.
Za branje besedila v vrstici seznama smo uporabili lastnosti Name in Description, ki
smo ju izvršili nad objektom vrstica tipa Element. Referenco na ta objekt dobimo iz
vhodnega parametra metode NapolniSlovarIzhodov. Lastnost Name vrne vrednost v prvem
stolpcu. V našem primeru je bila to šifra učenca. Do ostalih podatkov (npr. ime, priimek,
spol) smo dostopali z lastnostjo Description, ki vrne niz v obliki
podatek_1: vrednost_podatka_1; podatek_2: vrednos t_podatka_2;
oziroma v našem primeru
Ime: Janez; Priimek: Novak; Spol: M;
Ta niz v metodi NapolniSlovarIzhodov najprej razdelimo pri podpičjih z uporabo
metode Split (vrstica.Description.Split(';')). Dobljeni pari podatek: vrednost_podatka se
nahajajo v polju niziPodpicja. V nadaljevanju vsakega izmed parov tega polja razdelimo
pri dvopičjih niz.Split(':') in ga vnesemo v slovar izhodov. Pri tem podatek postane ključ
(lastnost Key), ki se mu priredi vrednost_podatka (lastnost Value).
V zadnjem koraku program za preverjanje konsistentnosti podatkov opravi primerjavo
vhodnega in izhodnega slovarja. Pri polnjenju vhodnega slovarja (glej Koda 3.13) smo
poskrbeli, da le-ta vsebuje isto poimenovane ključe (npr. šifra, datum vpisa, spol) kot
izhodni slovar. To nam je omogočilo enostavno primerjavo slovarjev. Koda 3.16 podaja
izvorno kodo metode StaEnakaSlovarja, ki vrne logično vrednost true, če sta slovarja
enaka.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 27
private bool StaEnakaSlovarja() { bool rezultat = true; if (slovarIzhodov.Count != slovarVhodov.Count) rezultat = false; foreach ( DictionaryEntry de in slovarIzhodov ) { if (slovarVhodov[de.Key.ToString()] != de.Value .ToString()) { slovarNapak.Add(de.Key.ToString(), de.Value.To String()) rezultat = false; } } return rezultat; }
Koda 3.16: Metoda, ki vrne logično vrednost true, če slovarja vsebujeta iste podatke.
V metodi StaEnakaSlovarja upoštevamo, da morata imeti slovarja isto število vnosov,
zato najprej opravimo primerjavo lastnosti Count. Nadaljujemo s primerjavo vrednosti. V
zanki zaporedoma preverjamo ujemanje vrednosti za podani ključ in v primeru odstopanja,
ključ in vrednost izhodnega slovarja zapišemo v slovar napak (spremenljivka
slovarNapaka. V nasprotnem primeru sta slovarja enaka. Pomeni, da podatki iz vrstice v
seznamu učencev ustrezajo tistim, ki so bili vneseni iz pogovornega okna za dodajanje
novega učenca.
Končni program za preizkušanje deluje tako, da:
1. Požene program Glasovir.
2. Prikliče kontekstni meni nad seznamom učencev in pritisne gumb Dodaj.
3. Vnese podatke o novem učencu.
4. Pred zaključkom vnosa napolni vhodni slovar z vnesenimi podatki.
5. Ob vrnitvi v seznam učencev napolni izhodni slovar na osnovi novo vstavljene
vrstice.
6. Opravi primerjavo in izpiše rezultat primerjave.
Slabost implementiranega programa je, da se podatki za vhodni slovar (tj. pričakovani
rezultati) nahajajo v izvorni kodi programa. Njihovo spreminjanje je zato zamudno, prav
tako pa moramo po vsaki modifikaciji podatkov program za preizkušanje ponovno
prevesti. Prevajanju kode bi se v primeru, če bi namesto programskega jezika C# izbrali
skriptni jezik Python, sicer izognili, a bi kljub temu želeli ločiti preizkusne podatke od
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 28
programa. V nadaljevanju bomo pokazali implementacijo razreda, ki nam je omogočil, da
preizkusne podatke v program za preizkušanje vstavljamo iz preglednice orodja Excel.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 29
4 POVEZAVA PROGRAMA ZA PREIZKUŠANJE Z ORODJEM EXCEL
Preizkusne podatke smo želeli ločiti od izvorne kode programa za preizkušanje, da bi
pridobili več fleksibilnosti pri spreminjanju teh podatkov. Hkrati smo si želeli tudi
enostavnega načina za dodajanje novih serij preizkusnih podatkov. Zaradi tabelarične
oblike preizkusnih podatkov je bila izbira elektronske preglednice za njihovo hrambo
intuitivna. Poleg enostavnega urejanja preizkusnih podatkov smo se za uporabo orodja
Excel odločili tudi zaradi:
• dodatnih funkcionalnosti orodja,
• lažje izmenjave preizkusnih podatkov z naročnikom in
• preproste obdelave preglednic v ogrodju .NET 1.1.
Z dodatnimi funkcionalnostmi orodja Excel mislimo predvsem možnosti kot so, npr.
filtriranje, urejanje podatkov po abecednem redu, samodejno generiranje zaporednih števil
(možnost Auto Fill), enostavno podvajanje nizov ipd., ki bi nam olajšali pripravo
preizkusnih podatkov.
Lažja izmenjava preizkusnih podatkov z naročnikom je možna zaradi razširjenosti
elektronskih preglednic (in posebno orodja Excel). Če program za preizkušanje že v osnovi
omogoča branje datotek takega formata, nam to prihrani pretvorbo v obliko zapisa, ki jo
razume samo program za preizkušanje.
Programski dostop do podatkov v preglednici oblikovani z orodjem Excel je glede na
format datoteke, ki ga izberemo pri shranjevanju, možen na več načinov. Med drugim
lahko, če gre za običajno binarno datoteko orodja Excel s končnico XLS, do preglednice
dostopamo s pomočjo objektne knjižnice orodja Excel. V primeru, da prej opravimo
pretvorbo binarne preglednice v format XML, pa lahko do podatkov preglednice
dostopamo z vgrajenimi razredi za obdelavo zapisa v jeziku XML.
Da bi programom za preizkušanje omogočili dostop do preizkusnih podatkov, smo
implementirali razred ExcelAdapter. Ta na zahtevo programa za preizkušanje zaporedoma
vrača vrstice preglednice v obliki slovarjev nizov. Ti slovarji (tj. objekti tipa
StringDictionary) predstavljajo zbirko pričakovanih rezultatov, ki jih program za
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 30
preizkušanje primerja s slovarjem pričakovanih rezultatov, kot smo pokazali v poglavju
3.5. V nadaljevanju bomo opisali postopek implementacije razreda ExcelAdapter.
4.1 Implementacija razreda ExcelAdapter
Razred ExcelAdapter implementiranim programom za preizkušanje omogoča dostop do
preizkusnih podatkov shranjenih v preglednici orodja Excel. Slika 4.1 kaže razredni
diagram razreda ExcelAdapter.
Slika 4.1: Razredni diagram implementiranega razreda ExcelAdapter.
Preglednice izdelane z orodjem Excel lahko v ogrodju .NET obdelujemo kot binarne
datoteke ali pa kot tekstovne datoteke formata XML. Binarni pristop zahteva vključitev t.i.
COM-knjižnice v izvorno kodo programa za preizkušanje. Ta knjižnica, ki je sicer del
paketa Microsoft Office, nam ob vključitvi nato omogoči dostop do posameznih celic in
delovnih listov (angl. data sheets) datoteke orodja Excel. Knjižnico vključimo podobno kot
smo vključili knjižnico orodja Ranorex v podpoglavju 3.4, le da v pogovornem oknu Add
Reference kliknemo na zavihek COM in v seznamu izberemo Microsoft Excel 11.0 Object
Library (Slika 4.2). Različica knjižnice je odvisna od različice nameščenega paketa
Microsoft Office. V našem primeru smo uporabljali verzijo 2003, ki namesti različico 11.0
omenjene COM-knjižnice.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 31
Slika 4.2: Dodajanje reference na knjižnico COM orodja Excel
Dostopanje do elementov preglednice s pomočjo knjižnice COM je sicer manj
fleksibilno od metod, ki so v ogrodju .NET namenjene obdelavi XML-dokumentov.
Knjižnico smo v našem primeru zato vključili izklju čno zaradi pretvorbe preglednice iz
binarnega formata v format XML. Koda 4.1 kaže del konstruktorja razreda ExcelAdapter,
ki pretvori binarno preglednico na lokaciji datotekaXls v datoteko XML na lokaciji
datotekaXml.
public ExcelAdapter(string datotekaXls) { Microsoft.Office.Interop.Excel.Application excel App = new Microsoft.Office.Interop.Excel.Application( ); Mirosoft.Office.Interop.Excel.Workbook workBook = excelApp.Workbooks.Open(datotekaXls, ...); workBook.SaveAs(datotekaXml, ...); ... }
Koda 4.1: Del izvorne kode konstruktorja ExcelAdapter, ki preglednico orodja Excel pretvori v datoteko XML.
Pri klicu metode Open razreda Workbooks in metode SaveAs razreda Workbook (glej
Koda 4.1) zaradi preglednosti podajamo samo prvi parameter, tj. pot do datoteke. Popolna
klica obeh metod prikazuje izvorna koda v prilogi tega diplomskega dela. Rezultat
pretvorbe je datoteka XML. Koda 4.2 podaja njeno osnovno strukturo:
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 32
<?xml version="1.0"?> <?mso-application progid="Excel.Sheet"?> <Workbook xmlns="urn:schemas-microsoft-com:office :spreadsheet" ... <!-- Preostale definicije imenskih prostorov --> ... > <DocumentProperties xmlns="urn:schemas-microsoft -com:office:office"> <!-- Zna čke za dolo čanje avtorja, datuma nastanka preglednice, razli čico orodja ipd. --> </DocumentProperties> <ExcelWorkbook xmlns="urn:schemas-microsoft-com: office:excel"> <!-- Zna čke za dolo čanje dimenzij preglednice ipd. --> </ExcelWorkbook> <Styles> <!-- Zna čke za dolo čanje slogov uporabljenih v preglednici, npr. oblika pisave, robov in poravnave. --> <Worksheet ss:Name="Sheet1"> <Table ss:ExpandedColumnCount="4" ss:ExpandedRo wCount="2" x:FullColumns="1" x:FullRows="1"> <Row> <Cell ss:StyleID="s21"><Data ss:Type="String" >Šifra</Data></Cell> <Cell ss:StyleID="s21"><Data ss:Type="String" >Priimek</Data></Cell> <Cell ss:StyleID="s21"><Data ss:Type="String" >Ime</Data></Cell> <Cell ss:StyleID="s21"><Data ss:Type="String">Sp ol</Data></Cell> </Row> <Row> <Cell><Data ss:Type="Number">1989</Data></Cel l> <Cell><Data ss:Type="String">Novak</Data></Ce ll> <Cell><Data ss:Type="String">Janez</Data></Ce ll> <Cell><Data ss:Type="String">moški</Data></Cell> </Row> </Table> <WorksheetOptions xmlns="urn:schemas-microsoft- com:office:excel"> <!-- Zna čke za dolo čanje nastavitev pri tiskanju, zna čke s podatki o aktivni celici ipd. --> </WorksheetOptions> </Worksheet> </Workbook>
Koda 4.2: Preglednica orodja Excel shranjena v formatu XML.
Dobljena datoteka XML je identična datoteki, ki jo dobimo, če pri shranjevanju
preglednice v orodju Excel (različica 2003) namesto Microsoft Office Excelov delovni
zvezek (*.xls) izberemo možnost XML preglednica (*.xml). Manj pomembne značke smo
izpustili in jih nadomestili s komentarji znotraj značk <!-- in --> (glej Koda 4.2). Celotno
vsebino datoteke podajamo v prilogi tega diplomskega dela. Ključni podatki se nahajajo
znotraj vozlišča Table. Vidimo, da prva (tj. naslovna) vrstica (značka Row) vsebuje celice
(vozlišče Cell) z nizi Šifra, Priimek, Ime in Spol. Druga vrstica pa vsebuje konkretne
podatke (1989, Novak itd.).
Po pretvorbi binarne preglednice v XML-datoteko (glej Koda 4.1), naložimo dobljeno
XML-datoteko na lokaciji datotekaXml v objekt tipa XmlDocument, kot prikazujemo v
nadaljevanju izvorne kode konstruktorja ExcelAdapter (Koda 4.3). V ogrodju .NET 1.1 sta
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 33
delu z datotekami XML namenjena razreda XmlTextReader in XmlDocument. Prvi se pri
daljših XML-datotekah izkaže za časovno in prostorsko učinkovitejšega [8] [9], ker do
XML datoteke dostopa zaporedno z uporabo vmesnega pomnilnika. Ker so bile XML-
datoteke s preizkusnimi podatki relativno kratke (tj. vsebovale so največ 50 preizkusnih
primerov), smo se zaradi lažje implementacije odločili za uporabo razreda XmlDocument.
Potem, ko smo datoteko XML naložili v objekt XmlDocument, smo iz korena (objekt
koren) datoteke XML nato želeli dostopati do posameznih vrstic znotraj preglednice –
natančneje do vseh vozlišč Row znotraj vozlišča Table. Uporaba enoparameterske oblike
metode SelectNodes se je izkazala za neuspešno. Uporabiti smo morali dvoparametersko
obliko. Ta je poleg poti do vozlišč z vrsticami zahtevala še referenco na objekt tipa
XmlNamespaceManager, ki mu po kreiranju dodamo imenski prostor urn:schemas-
microsoft-com:office:spreadsheet potreben za dostop do vozlišč.
public ExcelAdapter(string datotekaXls) { ... FileStream stream = File.Open(datotekaXml, FileM ode.Open); XmlDocument document = new XmlDocument(); document.Load(stream); XmlNamespaceManager nsMgr= new XmlNamespaceManag er(document.NameTable); nsMgr.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet"); XmlElement koren = document.DocumentElement; vrsticePreglednice = koren.SelectNodes("//ss:Wor ksheet/ss:Table/ss:Row", nsMgr); ... }
Koda 4.3: Nadaljevanje izvorne kode konstruktorja ExcelAdapter.
Po izvršitvi metode SelectNodes vsebuje objekt vrsticePreglednice, ki je tipa
XmlNodeList, vsa vozlišča Row (tj. vrstice preglednice) datoteke XML (glej Koda 4.2). Iz
objekta vrsticePreglednice smo v nadaljevanju tvorili slovarje nizov s pričakovanimi
rezultati, ki jih je zahteval program za preizkušanje. Pri tem so podatki prve vrstice (tj.
naslovi stolpcev) preglednice predstavljali ključe slovarja, vrednosti za slovar pa smo
dobili iz nadaljnjih vrstic.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 34
4.2 Uporaba razreda ExcelAdapter
Implementirani programi za preizkušanje konsistentnosti pogovornega okna in seznama
delujejo tako, da slovar pričakovanih rezultatov primerjajo s slovarjem dejanskih
rezultatov in izpišejo informacije o uspešnosti primerjave. Javna metoda
VrniNaslednjiSlovar razreda ExcelAdapter (Slika 4.1) programu za preizkušanje
konsistentnosti omogoča, da zaporedno dostopa do preizkusnih podatkov. S temi podatki
program ustrezno napolni pogovorno okno, potrdi vnos podatkov in opravi primerjavo s
podatki, ki se po vnosu (ali spreminjanju) izpišejo v seznamu.
Koda 4.4 prikazuje del izvorne kode nadgrajenega programa za preizkušanje
konsistentnosti, ki v zanki vsakič napolni pogovorno okno s trenutno vrstico preglednice,
potrdi vnos in opravi primerjavo s podatki iz seznama. Pred koncem zanke pa izpiše
rezultate primerjave.
static int Main(string[] args) { ... ExcelAdapter excelAdapter = new ExcelAdapter(); StringDictionary sd; while ((sd = excelAdapter.VrniNaslednjiSlovar()) != null) { Console.Write("Vstavljam u čenca {0} (od {1})... ", excelAdapter.TrenutniSlovar, excelAdapter.SkupajSlovarjev); // Prikli či pogovorno okno za dodajanje novega u čenca. Mouse.ClickControl(listUcenci, MouseButtonType. RightButton); Point curPos = Mouse.Position; Mouse.Click(MouseButtonType.LeftButton, curPos. X + 10, curPos.Y + 60); Form frmUcenec = Application.FindFormTitle("U čenec"); cls.VrniKontrolnik(frmUcenec, "tbSifra").Text = sd["šifra"]; cls.VrniKontrolnik(frmUcenec, "tbPriimek").Text = sd["priimek"]; cls.VrniKontrolnik(frmUcenec, "tbIme").Text = s d["ime"]; if (sd["spol"] == "ženski") ((RadioButton)cls.VrniKontrolnik(frmUcenec, "rbZenski")).Checked = true; control gumbDodaj = form.FindControlName("btnDo daj"); Mouse.ClickControl(gumbDodaj); NapolniSlovarIzhodov(); if (StaEnakaSlovarja()) { Console.Write("V redu.\n") } else {
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 35
Console.Write("NAPAKA pri ID {0}:\n", sd["šifr a"]) Console.Write(slovarNapak); } } }
Koda 4.4: Primer uporabe razreda ExcelAdapter znotraj programa za preizkušanje.
Celotna izvorna koda implementiranega programa za preizkušanje konsistentnosti
podatkov pogovornega okna in seznama je na voljo v prilogi tega diplomskega dela.
Primere uporabe programov za preizkušanje podajamo v naslednjem poglavju.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 36
5 STATISTI ČNI REZULTATI PREIZKUŠANJA
Zaradi zahtev naročnika po novih funkcionalnostih, je bil program Glasovir podvržen
stalnim modifikacijam. Te modifikacije bi lahko vplivale na delovanje obstoječih
funkcionalnosti programa. S programi za preizkušanje smo zato po vsakem uspešnem
prevajanju programa Glasovir preverili, ali obstoječe funkcionalnosti, kljub modifikacijam,
delujejo v skladu z zahtevami naročnika. V nadaljevanju tega poglavja podajamo nekaj
primerov, ko je prišlo zaradi sprememb v izvorni kodi in/ali podatkovni bazi do napačnega
delovanja programa.
Vrednosti preizkusnih podatkov smo v primeru osebnih podatkov učencev generirali s
pomočjo generatorja dostopnega na spletu [10]. Številske vrednosti in vrednosti datumov
smo tvorili z uporabo funkcij RAND in RANDBETWEEN orodja Excel. Koda 5.1 prikazuje
primer uporabe funkcije RANDBETWEEN za generiranje datumov med 1.1.2000 in
31.12.2007. Za pravilen izpis datuma moramo obliko celice nastaviti na Datum.
=RANDBETWEEN(36526;39447)
Koda 5.1: Funkcija, ki v orodju Excel generira datume med 1.1.2000 in 31.12.2007.
Preizkusne podatke smo izjemoma vnašali tudi ročno (npr. v primeru sporočil o
napakah, glej poglavje 5.2).
5.1 Dodajanje novega učenca
Pogovorno okno Učenec programa Glasovir služi dodajanju novega ali urejanju
obstoječega učenca glasbene šole (Slika 3.16). Pogovorno okno ob vnosu novega učenca
zahteva najmanj dva datuma, ki ju zahtevata vpisni polji Datum rojstva in Datum vpisa. Če
želi uporabnik vnesti učenca, ki je šolanje že zaključil, zahtevamo od njega še vnos
ustreznega datuma v vpisno polje Datum izpisa.
Program za preizkušanje konsistentnosti podatkov pogovornega okna in seznama, je pri
vstavljanju petih novih učencev na uporabnikovem računalniku, v treh primerih javil
neuspešen zaključek operacije. V dveh primerih je bila operacija vstavljanja sicer uspešno
zaključena, a je program zaznal napako pri preverjanju konsistentnosti datumov. Podajmo
izpis programa:
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 37
Vstavljam u čenca 1 (od 5)... NAPAKA pri ID 5458: Datum vpisa: 09.01.2007 (pri čakovan 01.09.2007) Datum rojstva: 04.05.1990 (pri čakovan 05.04.1990) Vstavljam u čenca 2 (od 5)... NEUSPEŠEN ZAKLJU ČEK OPERACIJE! Vstavljam u čenca 3 (od 5)... NEUSPEŠEN ZAKLJU ČEK OPERACIJE! Vstavljam u čenca 4 (od 5)... NAPAKA pri ID 4732: Datum vpisa: 01.08.2003 (pri čakovan 08.01.2003) Datum rojstva: 06.02.1989 (pri čakovan 02.06.1989) Datum izpisa: 06.11.2005 (pri čakovan 11.06.2005) Vstavljam u čenca 5 (od 5)... NEUSPEŠEN ZAKLJU ČEK OPERACIJE!
Iz izpisa programa za preizkušanje je razvidno, da je v obeh primerih, ko se je operacija
kljub napaki uspešno zaključila, prišlo do zamenjave dneva in meseca v datumu oz.
natančneje, do spremembe v obliki zapisa datuma. V obeh primerih, ko je bil učenec
uspešno vstavljen, je datum veljaven tako v obliki dan/mesec/leto kakor tudi v obliki
mesec/dan/leto. V treh primerih, ko se operacija vstavljanja ni zaključila uspešno, pa je bila
pretvorba iz ene oblike v drugo neveljavna (npr. iz 22.03.1994 v 03.22.1994). V teh
primerih je seveda prišlo do predčasnega zaključka operacije zaradi logične napake v
delovanju programa Glasovir.
Program za preizkušanje je na razvojnem računalniku v vseh petih primerih uspešno
vstavil učence in prav tako ugotovil konsistentnost podatkov. Sklepali smo torej, da
naročnikov operacijski sistem uporablja napačne regionalne nastavitve. Ker nismo hoteli,
da bi spreminjanje le-teh vplivalo na delovanje programa Glasovir, smo njegovo izvorno
kodo nadgradili z eksplicitno pretvorbo datuma v zapis oblike dan/mesec/leto.
Izvorno kodo pogovornega okna Učenec smo nadgradili tako, da najprej ustvarimo
objekt tipa CultureInfo, pri čemer konstruktorju podamo niz sl-SI. Ta niz zahteva kreiranje
objekta s slovenskimi regionalnimi nastavitvami, ki med drugim definirajo tudi datum v
obliki dan/mesec/leto. Koda 5.2 kaže kreiranje instance razreda CultureInfo.
System.Globalization.CultureInfo cInfo = new System.Globalization.CultureInfo("sl-SI");
Koda 5.2: Kreiranje objekta CultureInfo s slovenskimi regionalnimi nastavitvami.
Datume, ki jih uporabnik vnaša v pogovornem oknu Učenec, shranjujemo v objekte
tipa DateTime. Ta objekt vrne statična metoda Parse razreda DateTime, ki datum zapisan v
obliki niza razčleni (angl. parse) v posamezne atribute objekta DateTime (npr. uro, dan in
mesec). Pred modificiranjem izvorne kode smo klicali enoparametersko obliko metode
Parse (glej Koda 5.3). Spremenljivka tbDatumRojstva predstavlja referenco na vpisno
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 38
polje Datum rojstva, pri čemer z lastnostjo Text dostopamo do samega niza z datumom, ki
je bil vpisan v to polje.
DateTime datumRojstva = DateTime.Parse(tbDatumRoj stva.Text);
Koda 5.3: Primer klica metode Parse za razčlenitev datuma rojstva brez upoštevanja regionalnih nastavitev.
Ker pri klicu metode Parse nismo eksplicitno zahtevali uporabe ustreznih regionalnih
nastavitev, je prihajalo pri uporabi programa na naročnikovem računalniku do napake pri
razčlenitvi datumov rojstva, vpisa in izpisa učenca, če ti niso bili zapisani v obliki
dan/mesec/leto. Vse klice metode Parse smo zato zamenjali z dvoparametersko obliko. Ta
kot drugi parameter zahteva objekt z regionalnimi nastavitvami (CultureInfo). V našem
primeru je bil to objekt cInfo, čigar kreiranje smo prikazali v koda_cs_cultureinfo. Koda
5.4 kaže primer modificiranega klica metode Parse.
DateTime datumRojstva = DateTime.Parse(tbDatumRoj stva.Text, cInfo);
Koda 5.4: Klic metode Parse, ki datum rojstva razčleni ob upoštevanju regionalnih nastavitev.
V nadaljnjem procesu nadgrajevanja izvorne kode, smo razčlembo datuma po opisanem
postopku spremenili tudi v preostalih pogovornih oknih, ki zahtevajo vpisovanje datumov
(npr. pogovorno okno za vpisovanje opravljenega izpita učencu).
5.2 Sporočilna okna
Uporabnike programa Glasovir o napakah obveščamo s sporočilnimi okni. Slika 3.3
kaže primer takega sporočilnega okna. To sporočilno okno se prikaže takrat, ko uporabnik
v pogovornem oknu Učenec (Slika 3.16) ne izpolni vpisnega polja Šifra učenca. Vsako
sporočilno okno vsebuje poleg gumba za potrditev še naslov, ki je v našem primeru
Napaka vnosa: šifra učenca in besedilo (Vnesti morate šifro učenca.). S programom za
preizkušanje po vsaki večji modifikaciji izvorne kode programa Glasovir preizkusimo
pravilno delovanje sporočilnih oken. To storimo tako, da s preizkusnim programom v
pogovorna okna vnašamo logično neustrezne podatke, nato prestrežemo sporočilno okno in
preverimo pravilnost naslova ter besedila sporočilnega okna.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 39
Niza z naslovom in besedilom sporočilnega okna sta bila prvotno del izvorne kode
pogovornega okna. V primeru sporočilnega okna s slike (Slika 3.3) je bilo to pogovorno
okno Učenec.
Koda 5.5 prikazuje del izvorne kode tega pogovornega okna, ki je skrbela za prikaz
sporočila o napaki vnosa. Pri tem lblDatumRojstva.Text predstavlja ime labele (npr. Datum
rojstva), tbDatumRojstva.Text pa datum, ki je bil vpisan v vpisno polje (npr. 21.6.1995).
string naslov = "Napaka pri vnosu"; string besedilo = lblDatumRojstva.Text + " " + t bDatumRojstva.Text + " je podan v napa čni obliki."; MessageBox.Show(besedilo, naslov, MessageBoxButto ns.OK, MessageBoxIcon.Exclamation);
Koda 5.5: Izvorna koda pogovornega okna Učenec za prikaz sporočilnega okna o napaki pred uvedbo razreda Konstante.
Pri nadgrajevanju programa Glasovir smo se kasneje odločili, da vse številske
konstante in konstantne nize preselimo v t.i. datoteko z viri (angl. resource file). S tem smo
pridobili na preglednosti izvorne kode in lažjemu vzdrževanju, saj do vseh konstant
dostopamo samo iz enega mesta. Konstantne nize smo v primerih, kjer je bilo to smiselno,
tudi parametrizirali. Namesto sintaktično nepreglednega in manj fleksibilnega sestavljanja
nizov z znakom + , kot je npr. vidno pri prirejanju vrednosti spremenljivki besedilo (glej
Koda 5.5), smo uvedli t.i. formatirane nize. Primer takega niza je denimo
{0} {1} je podan v napa čni obliki.
Z metodo Format razreda String tak niz nato uporabimo tako
String.Format("{0} {1} je podan v napa čni obliki.", "Datum rojstva", "21.6.1995");
Pri tem se niza {0} in {1} zamenjata s parametroma Datum izpisa in 21.6.1995.
Za dostop do konstant v datoteki z viri (v ogrodju .NET ima končnico resx)
uporabljamo razred Konstante. Ta razred smo implementirali po t.i. vzorcu singleton, kar
pomeni, da lahko v nekem trenutku obstaja kvečjemu ena instanca tega razreda. S
statičnimi metodami razreda Konstante v izvorni kodi programa Glasovir nato dostopamo
do posameznih konstant (npr. niza Vnesti morate šifro učenca.).
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 40
Po zamenjavi konstantnih nizov s klici razreda Konstante, smo pognali program za
preizkušanje sporočilnih oken. Ta je v šestih primerih od skupno 27-ih ugotovil
nekonsistentnost med dejanskim in pričakovanim besedilom sporočilnega okna. Podajamo
okrnjen izpis programa za preizkušanje.
Preverjam sporo čilno okno 1 (od 27)... V redu. Preverjam sporo čilno okno 2 (od 27)... V redu. ... Preverjam sporo čilno okno 10 (od 27)... NAPAKA: Besedilo: 'Datum rojstva 15.4.1994 {0} {1} je po dan v napa čni obliki.' (pri čakovano: 'Datum rojstva 15.4.1994 je podan v napa čni obliki.') ... Preverjam sporo čilno okno 13 (od 27)... V redu. ... Preverjam sporo čilno okno 24 (od 27)... NAPAKA:
Besedilo: 'Datum izpita 12.6.2007 {0} {1} ne sovpad a s šolskim letom učenčevega razreda.' (pri čakovano: 'Datum izpita 12.6.2007 ne sovpada s šolsk im letom učenčevega razreda.')
... Preverjam sporo čilno okno 27 (od 27)... V redu.
Po analizi napak smo ugotovili, da je do njih prišlo zaradi nepopolne modifikacije
izvorne kode. S funkcijo Find and Replace orodja Visual Studio smo konstantne nize
najprej zamenjali s klici statičnih metod razreda Konstante (glej Koda 5.6).
string besedilo = "lblDatumRojstva.Text" + " " + tbDatumRojstva.Text + Konstante.VrniNiz(Konstante.NapakaVnosa);
Koda 5.6: Zamenjava konstantnega niza s klicem statične metode razreda Konstante.
V nadaljevanju pa smo v primerih, kjer je prišlo do napake, pozabili zamenjati
sestavljanje nizov z znakom + s funkcijo Format (glej Koda 5.7).
string besedilo = String.Format(Konstante.VrniNiz (Konstante.NapakaVnosa), lblDatumRojstva.Text, tbDatumRojstva.Text);
Koda 5.7: Uporaba metode Format za vpisovanje parametrov v konstantni niz.
Potem, ko smo v vseh sedmih primerih opravili še drugi del modifikacije, pri
ponovnem preverjanju ni bilo več ugotovljenih odstopanj med pričakovanim in dejanskim
nizom zapisanim v besedilu sporočilnega okna.
5.3 Urejanje predmeta učenca
S pogovornim oknom Predmet/skupina učenca programa Glasovir učencu glasbene
šole določimo predmet in/ali skupino (npr. orkester), ki ga/jo učenec obiskuje (Slika 5.1).
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 41
Z istim oknom lahko obstoječe predmete in skupine učencev tudi spreminjamo. Pri
urejanju se v skladu z izbranim predmetom (skupino) iz seznama v pogovornem oknu
nastavijo
• izbirna gumba v razdelkih Vrsta in Stopnja,
• spustna seznama z imenom in statusom predmeta ter
• opomba.
Slika 5.1: Pogovorno okno za dodajanje/urejanje predmeta in skupine učenca.
V primeru na gornji sliki smo v seznamu učenčevih predmetov in skupin izbrali
predmet (razdelek Vrsta) trobenta (spustni seznam Ime), ki ga učenec obiskuje (spustni
seznam Status) na nižji stopnji (razdelek Stopnja). Vpisno polje Opomba je prazno, saj
opombe pri dodajanju predmeta učencu nismo vnesli.
Ko smo po eni izmed večjih modifikacij izvorne kode programa Glasovir pognali
program za preizkušanje, je program pri urejanju 50-ih predmetov oz. skupin učenca, v 32-
ih primerih javil napako o nekonsistentnosti podatkov seznama in pogovornega okna.
Podajmo okrnjen izpis programa.
Urejam razred/skupino u čenca 1 (od 50)... NAPAKA pri ID 43: Vrsta: 'skupina' (pri čakovana: 'predmet') Stopnja: 'brez' (pri čakovana: 'višja') ... Urejam razred/skupino u čenca 17 (od 50)... V redu. Urejam razred/skupino u čenca 18 (od 50)... NAPAKA pri ID 79: Vrsta: 'skupina' (pri čakovana: 'predmet') Urejam razred/skupino u čenca 19 (od 50)... V redu. ... Urejam razred/skupino u čenca 50 (od 50)... NAPAKA pri ID 108: Vrsta: 'skupina' (pri čakovana: 'predmet')
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 42
Stopnja: 'brez' (pri čakovana: 'nižja')
Analiza primerov, v katerih je prišlo do napake, je pokazala, da je pogovorno okno
Predmet/skupina učenca v razdelku Vrsta namesto pričakovane izbire Predmet vedno
izbralo možnost Skupina (Slika 5.1). Taka funkcionalnost je bila pričakovana zgolj v
primerih, ko je uporabnik želel urediti že vneseno skupino, ki jo je obiskoval učenec.
Ugotovili smo, da je program na napake v konsistentnosti naletel samo pri urejanju
predmetov, ki so jih imeli vpisane učenci, ne pa tudi pri urejanju skupin. Pri tem je bila v
vseh 32-ih primerih ugotovljena nekonsistentnost vrste predmeta. Med napačnimi primeri
je bilo 29 tudi takih z napačno stopnjo. Tak primer kažeta prva (ID 43) in tretja napaka (ID
108) v izpisu programa.
Po ročnem preizkušanju urejanja predmeta/skupine smo ugotovili, da je bilo pogovorno
okno Predmet/skupina učenca pri urejanju vseh predmetov, razen predmeta nauk o glasbi,
vedno v načinu za urejanje skupine. V spustnem seznamu Ime so bili kljub temu našteti vsi
predmeti razen predmeta nauk o glasbi. To je bil tudi edini predmet pri urejanju katerega je
pogovorno okno prešlo v pravi način urejanja (tj. urejanje predmeta). Pogovorno okno je v
takih primerih v spustnem seznamu Ime vedno vsebovalo zgolj predmet nauk o glasbi ne
pa tudi preostalih.
Za 3 primere, kjer je program za preizkušanje javil napako zgolj v neujemanju
izbirnega gumba Vrsta, je bilo ugotovljeno, da je šlo vedno za predmet glasbena
pripravnica. Ta predmet se, podobno kot skupine, ne deli na stopnje, vrednost izbirnega
gumba v razdelku Stopnja je bila v teh primerih torej pravilna (tj. brez). Tak primer kaže
napaka ID 79 v izpisu programa za preizkušanje.
V nadaljevanju smo ugotovili, da je do napake prišlo zaradi spremembe šifre, s katero
smo označevali vrsto predmeta oz. skupine. Šifra vrste predmeta je bila v tesni povezavi s
poročili o uspehu učencev (Slika 5.2). Predmeti z nižjo šifro so bili v skladu z zahtevami
naročnika uvrščeni višje v seznamu. Pred spremembo šifre so imeli vsi predmeti, vključno
s predmetom nauk o glasbi šifro 1, šifre skupin pa so bile višje od 1. Naročnik je kasneje
zahteval, da mora biti na začetku seznama pri posameznem učencu najprej predmet nauk o
glasbi, nato glasbilo (saksofon v primeru poročila na sliki) in na koncu še morebitne
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 43
skupine. V primeru na sliki sta to mladinski pihalni ork. in mladinski pevski zbor. V skladu
z zahtevami smo se odločili, da nauk o glasbi označimo s šifro 1, glasbila s šifro 2,
skupinam pa dodelimo šifre višje od 2.
Slika 5.2: Del poročila o šolskem uspehu učencev programa Glasovir.
Pri spreminjanju šifer nismo bili konsistentni, zato so deli programa Glasovir začeli
delovati napačno. V primeru napake pri urejanju predmetov in skupin učencev, smo
vrednost konstante VrstaSkupina nastavili na 3. Namesto konstante VrstaPredmet, ki je
imela vrednost 1, pa smo uvedli konstanti VrstaNauk (za predmet nauk o glasbi, vrednost
1) in VrstaGlabilo (za glasbila, vrednost 2). Do teh konstant v izvorni kodi pogovornega
okna dostopamo iz razreda Konstante (glej poglavje Sporočilna okna). Koda 5.8 kaže del
izvorne kode pogovornega okna Predmet/skupina učenca, ki izbirni gumb v razdelku Vrsta
postavi na Predmet, če je predmet, ki ga obiskuje učenec nauk o glasbi ali glasbilo. Na
podoben način smo zagotovili tudi pravilno delovanje izbirnega gumba v razdelku Stopnja.
if (predmetUcenca.IdVrstePredmeta == Konstante.VrniStevilo(Konstante.VrstaNauk) || Konstante.VrniStevilo(Konstante.VrstaGlasbilo) { ... rbPredmet.Checked = true; rbSkupina.Checked = false; ... }
Koda 5.8: Nastavljanje izbirnega gumba pogovornega okna Predmet/skupina učenca v razdelku Vrsta na vrednost Predmet.
Odpraviti smo morali še napako v prikazu spustnega seznama Ime. Ta dobiva podatke
iz dveh SQL-poizvedb. Prva priskrbi seznamu imena predmetov, druga pa imena skupin.
Koda 5.9 kaže modificirano verzijo prve poizvedbe. Z nizom Or IdVrstePredmeta=2 smo
poskrbeli, da so bila v seznamu, poleg predmeta nauk o glasbi, prikazana tudi glasbila.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 44
SELECT IdPredmeta, Ime FROM Predmeti WHERE IdVrstePredmeta=1 Or IdVrstePredmeta=2;
Koda 5.9: SQL-poizvedba za polnjenje spustnega seznama Ime z imeni predmetov.
5.4 Urejanje razreda učenca
Pogovorno okno Razred predmeta omogoča uporabniku dodajanje novega ali urejanje
obstoječega razreda učenca v programu Glasovir (Slika 5.3).
Slika 5.3: Pogovorno okno za dodajanje/urejanje učenca s spustnim seznamom za izbiro predmeta.
Spustni seznam Razred pogovornega okna Razred predmeta omogoča izbiro zgolj tistih
razredov, ki so možni za dani predmet. Število razredov določa stopnja predmeta, pri
čemer obstajata dve. Za predmet harmonika so, denimo, na prvi (nižji) stopnji možni
razredi od prvega do šestega, drugo (višjo) stopnjo pa predstavljata sedmi in osmi razred.
Primer pogovornega okna s slike (Slika 5.3) torej kaže, da izbrani učenec obiskuje tretji
razred predmeta harmonika.
Ko smo po implementaciji pogovornega okna Razred predmeta preizkusili s
programom za preverjanje konsistentnosti podatkov seznama in pogovornega okna, je
program za preizkušanje v štirih primerih, od skupno petdesetih v vzorcu, javil napako.
Napaka je bila v vseh štirih primerih enaka; program za preizkušanje je namesto številke
razreda, ki je bila zapisana v vrstici seznama, v spustnem seznamu Razred pogovornega
okna Razred predmeta prebral prazen niz. Podajmo okrnjen izpis programa za
preizkušanje.
Urejam razred u čenca 1 (od 50)... V redu. Urejam razred u čenca 3 (od 50)... V redu. Urejam razred u čenca 3 (od 50)... V redu.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 45
... Urejam razred u čenca 19 (od 50)... NAPAKA pri ID 4547: Razred: '' (pri čakovan: [1,4]) Urejam razred u čenca 20 (od 50)... V redu. Urejam razred u čenca 21 (od 50)... V redu. ... Urejam razred u čenca 32 (od 50)... NAPAKA pri ID 3668: Razred: '' (pri čakovan: [7,8]) ... Urejam razred u čenca 50 (od 50)... V redu.
Nadaljnja analiza primerov, v katerih je prišlo do napake, je pokazala, da smo lahko
napako uvrstili v eno izmed naslednjih kategorij:
• vpisani razred je bil višji, kot ga je dopuščala izbrana stopnja. Tak primer kaže prva
napaka (ID 4547) v izpisu programa za preizkušanje. Učenec je imel v tem primeru
vpisan peti razred predmeta bariton, čeprav je izbrana prva stopnja dopuščala samo
razrede od prvega do četrtega.
• vpisani razred je bil nižji kot ga je dopuščala izbrana stopnja. Tak primer kaže
druga napaka (ID 3668) v izpisu programa za preizkušanje. Učenec je imel v tem
primeru vpisan šesti razred predmeta klavir, čeprav je izbrana druga stopnja
dopuščala zgolj sedmi in osmi razred.
V 50-ih preizkušenih zapisih so trije zapisi ustrezali prvi, eden pa drugi kategoriji.
Program Glasovir je ustreznost razreda pri vnosu novega razreda izbranemu učencu
preverjal že pred uvedbo spustnega seznama. Nismo pa implementirali preverjanja
ustreznosti podatkov, uvoženih iz podatkovne baze programa, ki ga je naročnik uporabljal
pred uvedbo programa Glasovir. Izkazalo se je, da prejšnji program ni izvajal preverjanja
podatkov in je dovoljeval vpise v neobstoječe razrede. Po preverjanju vseh uvoženih 472-
ih zapisov je bilo ugotovljeno, da je takih z neustreznim razredom 31. Od tega je bil razred
v 24-ih zapisih višji, kot ga je dopuščala stopnja (1. kategorija napake), v sedmih pa nižji
(2. kategorija). Poudarimo, da smo v program Glasovir uvozili samo podatke za razrede, ki
so jih učenci obiskovali v trenutnem šolskem letu. Pri tem je program za preizkušanje
preverjal ustreznost razreda glede na aktualni učni načrt.
Z nadaljnjim preizkušanjem vseh razredov, ki so jih učenci imeli vpisane v aktivnem
šolskem letu, smo na podobno napako naleteli tudi pri spustnem seznamu Učitelj
pogovornega okna Razred predmeta. V primerih, ko učitelj ni bil več zaposlen na glasbeni
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 46
šoli (oz. ni bil več nosilec predmeta), je preizkusni program iz spustnega seznama Učitelj
prebral prazen niz in javil napako. Takih primerov je bilo 14 od skupno 472-ih.
V štirih primerih so imeli učenci vpisan napačen tako razred kakor tudi učitelja. V
sodelovanju z naročnikom so bili kasneje učencem vpisani veljavni razredi in učitelji.
5.5 Nadaljnji preizkusi
S preizkusnimi programi smo učinkovito izvajali regresijsko preizkušanje grafičnega
uporabniškega vmesnika programa Glasovir. Zagon implementiranih programov za
preizkušanje nam je po vsaki modifikaciji programa zagotovil, da s spreminjanjem
programske kode nismo uvedli novih programskih napak. Uspešno preizkušanje je prestala
tudi zadnja različica programa Glasovir, s katero smo dokončno zagotovili vse zahtevane
funkcionalnosti in jo predali naročniku.
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 47
6 SKLEP
V tem delu smo predstavili možen način preizkušanja grafičnega uporabniškega
vmesnika z uporabo preizkusnih programov, ki uporabnikovo interakcijo z gradniki
(kontrolniki) vmesnika simulirajo s pomočjo že razvitih (angl. third party) funkcij.
Povezava programov za preizkušanje z elektronsko preglednico nam je omogočila
enostavnejši vnos preizkusnih podatkov in njihovo generiranje.
Med razvojem programov za preizkušanje smo prišli do naslednjih ugotovitev:
• Menimo, da je upravičeno dvomiti v kakovost orodij za preizkušanje, ki jih podjetja
oglašujejo kot produkte, ki zahtevajo malo ali celo nič programerskega znanja.
Četudi orodje za preizkušanje ponuja funkcijo zajemanja in predvajanja (angl.
capture and playback), zahteva razvoj programov za preizkušanje kompleksnega
grafičnega uporabniškega vmesnika še veliko implementiranja.
• Izbira orodja za preizkušanje mora biti pogojena predvsem z zmogljivostjo
programskega (oz. skriptnega) jezika orodja. Pri čemer menimo, da mora imeti
nadgradljivost programskega jezika prednost pred enostavnostjo njegove uporabe.
Prav nadgradljivost nam je v našem primeru omogočila, da smo v programe za
preizkušanje vgradili dostop do elektronske preglednice in s tem bistveno izboljšali
njihovo uporabnost.
• Vložek časa je pri uporabi že razvitih funkcij za dostop do kontrolnikov bistveno
manjši, kot v primeru razvoja lastnih funkcij. V primeru programov z dovolj
kompleksnim grafičnim uporabniškim vmesnikov, ki uporabljajo kontrolnike do
katerih lahko orodje za preizkušanje dostopa, bi torej dali prednost uporabi že
razvitih funkcij.
• Kontrolniki, ki so v izvorni kodi aplikacije, ki jo preizkušamo, poimenovani s
privzetimi imeni (npr. TextBox4) namesto z opisnimi imeni (npr. ImeUcenca),
vodijo k nepreglednosti programov za preizkušanje, kar tudi pomeni njihovo težje
vzdrževanje. Ugotovili smo, da lahko preglednost programov za preizkušanje
izboljšamo tudi tako, da kontrolnike preizkušane aplikacije predznačimo s tipom
kontrolnika. S tb tako denimo predznačimo vsa vnosna polja (TextBox) s cb pa vse
spustne sezname (ComboBox). To nam omogoči, da v kodi programa za
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 48
preizkušanje zlahka razlikujemo, na primer, med vnosnim poljem za vnos ocene
(tbOcena) in spustnim seznamom za izbiro ocene (cbOcena).
Za dostop do kontrolnikov grafičnega uporabniškega vmesnika smo v implementiranih
programih za preizkušanje uporabili metode knjižnice orodja Ranorex (različica 1.5.1).
Uporaba te knjižnice se nam je obrestovala predvsem zaradi:
• možnosti dostopa do praktično vseh vrst kontrolnikov, ki sestavljajo grafični
uporabniški vmesnik programa Glasovir. To nam je prihranilo implementacijo
lastnih postopkov za dostop do posameznih kontrolnikov.
• povezave z znanim programskim jezikom (C#). Le-to nam je omogočilo hitrejšo
implementacijo programov za preizkušanje, hkrati pa smo pri implementaciji lahko
uporabili bogat nabor razredov vgrajenih v ogrodje .NET (npr. razred
StringDictionary, ki smo ga uporabili pri implementaciji primerjave pričakovanih
in dejanskih rezultatov).
• dobre dokumentacije in podpore. Orodju Ranorex je poleg dokumentacije
priloženih tudi nekaj primerov uporabe, ki omogočajo lažjo seznanitev z uporabo
knjižnice. Za dober vir informacij se je izkazala tudi spletna stran podjetja Ranorex,
ki poleg pomoči uporabnikom na spletnem forumu ponuja tudi spletni dnevnik, kjer
razvijalci orodja prikazujejo njegovo uporabo.
• možnosti izvajanja programov za preizkušanje nad prevedenim programom. Orodje
Ranorex bi za preizkušanje grafičnega uporabniškega vmesnika lahko uporabili
tudi v primeru, če ne bi imeli dostopa do izvorne kode programa Glasovir (npr. na
naročnikovem računalniku).
Velja omeniti, da orodje Ranorex sicer brez težav komunicira s kontrolniki, ki so del
orodij za razvoj aplikacij za operacijski sistem Windows (npr. Visual Studio, Borland
Delphi), vendar lahko naleti na težave pri dostopu do t.i. kontrolnikov po meri (angl.
custom controls), ki jih je moč integrirati v aplikacije za razvoj programske opreme.
Program Glasovir je uporabljal standardne kontrolnike, ki so na voljo v Visual Studiu
2003, zato ta omejitev ni prišla do izraza. Kljub temu, da smo programe za preizkušanje z
uporabo orodja Ranorex implementirali brez večjih težav, ima orodje še precej možnosti za
izboljšave. Menimo, da bi se avtorji orodja v prihodnosti morali osredotočiti predvsem na:
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 49
• izboljševanje snemalnika RanorexRecorder, ki se kažejo predvsem v nezmožnosti
spreminjanja posameznih korakov v seznamu posnete sekvence. Za vsako še tako
majhno modifikacijo moramo poseči v izvorno kodo posnete sekvence. Pričakovali
bi, na primer, vsaj možnost osnovnega urejanja nizov, ki bodo vpisani v vnosna
polja pogovornega okna.
• izboljševanje algoritma za generiranje izvorne kode. Izvorna koda snemalnika je
preveč splošna in zato zamudna za vzdrževanje. Uporabna je kvečjemu za
seznanitev z osnovnim delovanjem knjižnice. Večino kasnejših programov za
preizkušanje smo zato implementirali brez uporabe snemalnika.
• možnost dostopa do objektov ogrodja .NET. To funkcionalnost (sicer zgolj za
različico 2.0 ogrodja .NET) ponuja denimo orodje ManagedSpy11 kjer lahko do
kontrolnikov dostopamo na enak način kot iz izvorne kode programa, ki ga
preizkušamo. V primeru orodja Ranorex pa objekt tipa ListView ponuja, na primer,
zgolj nekatere funkcionalnosti objekta ListView ogrodja .NET.
Na podoben način, kot smo ga opisali v delu, bi lahko preizkusili poljuben program, ki
teče v operacijskem sistemu Windows in uporablja kontrolnike do katerih zna orodje
Ranorex dostopati. Menimo, da je prihranek časa pri razvoju lastnih funkcij za dostop do
kontrolnikov oz. uporabe obstoječih, vezan predvsem na kompleksnost grafičnega
uporabniškega vmesnika. Uporaba orodja Ranorex (oz. orodja, ki nudi podobno
funkcionalnost) je zato smiselna v primerih, ko bi zaradi kompleksnosti grafičnega
uporabniškega vmesnika morali vložiti veliko časa v razvoj lastnih funkcij za dostop do
kontrolnikov vmesnika. Menimo, da je orodje Ranorex vredno uporabiti tudi v primerih,
ko program uporablja relativno malo število kontrolnikov po meri. V tem primeru za
dostop do standardnih kontrolnikov uporabimo funkcije orodja Ranorex, do kontrolnikov
po meri pa dostopamo s pomočjo programskega vmesnika operacijskega sistema Windows
(denimo z uporabo imenskega prostora InteropServices v ogrodju .NET).
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 50
VIRI
[1] Mark Fewster, Dorothy Graham, Software Test Automation, Addison-Wesley Professional, 1999
[2] http://msdn.microsoft.com/en-us/library/aa383749(VS.85).aspx, Windows API Reference
[3] Ian Dees, Scripted GUI Testing with Ruby, Pragmatic Bookshelf, 2008
[4] https://h10078.www1.hp.com/cda/hpms/display/main/hpms_content.jsp?zn=bto&cp=1-11-127-24%5E1074_4000_100__, WinRunner
[5] https://h10078.www1.hp.com/cda/hpms/display/main/hpms_content.jsp?zn=bto&cp=1-11-127-24%5E1352_4000_100__, QuickTest Professional
[6] http://www.ranorex.com, Ranorex
[7] http://www.automatedqa.com/products/testcomplete/, TestComplete
[8] http://www.nearinfinity.com/blogs/page/jferner?entry=performance_linq_to_sql_vs, Performance: LINQ to XML vs XmlDocument vs XmlReader
[9] http://www.dotnetjunkies.com/WebLog/chris.taylor/archive/2004/10/01/27350.aspx, Performance - Loading XML Documents
[10] http://www.fakenamegenerator.com, Fake Name Generator
[11] http://msdn.microsoft.com/en-us/magazine/cc163617.aspx, Managed Spy: Deliver The Power Of Spy++ To Windows Forms With Our New Tool
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 51
PRILOGE
A. Generirani program orodja Ranorex
V podpoglavju 3.4 podajamo optimizirano različico izvorne kode, ki jo je generiral
snemalnik RanorexRecorder. Podajmo nemodificirano različico izvorne kode:
/////////////////////////////////////////////////// //////////////////////////// // // This file was automatically generated by Ranorex Recorder // You can embed it into your application or compil e it with csc.exe: // csc /out:filename.exe /r:RanorexNet.dll file name.cs // http://www.ranorex.com // /////////////////////////////////////////////////// //////////////////////////// using System; using System.Drawing; using Ranorex; namespace RanorexTestApplication { class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static int Main(string[] args) { System.Environment.CurrentDirectory = @"C:\Pr ogram Files\Ranorex 1.5.1\Bin\Net1.1-Pro"; try { Logger.Initialize(true, null, null, LogLeve l.Info); Application.ErrorAsException = true; Form form; Control control; Control parent; Element element; Element formElement; Element controlElement; Menu menu; Point point; float timeScale = 1.0f; Element.IgnoreInvisible = true; //----------------------------------------- ------------------------ Logger.Info("User", "Find form by title 'Pr ogram Manager' and class name 'Progman'."); //----------------------------------------- ------------------------ form = Application.FindForm("Program Manage r", SearchMatchMode.MatchExact, "Progman", false, (int) (timeScale*5000)); form.Activate(); Logger.Info("User", "Find child by control id '1'."); control = form.FindControlId(1); control.Focus();
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 52
Logger.Info("User", "Get the accessibility element of the control."); controlElement = control.Element; Logger.Info("User", "Find child element in control by Role='ListItem', Name='Glasovir' and Location=(75,297)."); element = controlElement.FindChild(Role.Lis tItem, "Glasovir", null, new Point(75, 297)); Logger.Info("User", "Click element 2 time(s ) with left mouse button at offset=(48,20)."); Mouse.ClickElement(element, MouseButtonType .LeftButton, new Point(48, 20), 2, (int)(timeScale*26)); //----------------------------------------- ------------------------ Logger.Info("User", "Find form by title 'Gl asovir' and class name 'WindowsForms10.Window.8.app3'."); //----------------------------------------- ------------------------ form = Application.FindForm("Glasovir", Sea rchMatchMode.MatchExact, "WindowsForms10.Window.8.app3", false, (int)(timeSc ale*5000)); form.Activate(); Logger.Info("User", "Find parent by control name 'tabUcenci'."); parent = form.FindControlName("tabUcenci"); Logger.Info("User", "Find child by control name 'listUcenci'."); control = parent.FindControlName("listUcenc i"); control.Focus(); Logger.Info("User", "Get the accessibility element of the control."); controlElement = control.Element; Logger.Info("User", "Find child element in control by Role='ListItem', Name='2316' and Location=(6,135)."); element = controlElement.FindChild(Role.Lis tItem, "2316", null, new Point(6, 135)); Logger.Info("User", "Click element 1 time(s ) with right mouse button at offset=(87,6)."); Mouse.ClickElement(element, MouseButtonType .RightButton, new Point(87, 6), 1, (int)(timeScale*377)); Logger.Info("User", "Select popup menu item by text 'Dodaj'."); Application.PopupMenuSelectItem("Dodaj",(in t)(timeScale*275)); // Send keystrokes Application.SendKeys("1234{TAB}{SHIFTDOWN}N{SHIFTUP }ovak{TAB}{SHIFTDOWN}J{SHIFTUP}anez{TAB}{TAB}{SHIFTDOWN}S{SHIFTUP}lovenska{SPACE }5{TAB}{SHIFTDOWN}", 41); Application.SendKeys("S{SHIFTUP}podnji{SPACE}{SHIFT DOWN}K{SHIFTUP}ašelj{TAB}1.1.1990{TAB}{SHIFTDOWN}S{SHIFTUP}podnji{SPACE}{SHIFTDO WN}K{SHIFTUP}ašelkj{BACKSPACE}", 35); Application.SendKeys("{BACKSPACE}j{TAB}555{NUMPADSU B}763{TAB}{TAB}{TAB}1.9.2008", 71); //----------------------------------------- ------------------------ Logger.Info("User", "Find form by title 'U čenec' and class name 'WindowsForms10.Window.8.app3'."); //----------------------------------------- ------------------------ form = Application.FindForm("U čenec", SearchMatchMode.MatchExact, "WindowsForms10.Window.8.app3", false, (int)(timeSc ale*5000)); form.Activate(); Logger.Info("User", "Find child by control name 'btnDodaj'."); control = form.FindControlName("btnDodaj"); control.Focus(); Logger.Info("User", "Get the accessibility element of the control."); controlElement = control.Element;
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 53
Logger.Info("User", "Find child element in control by Role='PushButton', Name='Dodaj' and Location=(240,416)."); element = controlElement.FindChild(Role.Pus hButton, "Dodaj", null, new Point(240, 416)); Logger.Info("User", "Click element 1 time(s ) with left mouse button at offset=(39,11)."); Mouse.ClickElement(element, MouseButtonType .LeftButton, new Point(39, 11), 1, (int)(timeScale*543)); Logger.Info("User", "TEST PASSED"); return 0; } catch (RanorexException e) { Logger.Error("User", "EXCEPTION\nSource='{0}'\nSender='{1}'\nMessage='{2 }'\nStackTrace='{3}'", e.Source, e.Control, e.Message, e.StackTrace); Logger.Error("User", "TEST FAILED"); return 1; } finally { Logger.Close(); } } } }
B. Preglednica orodja Excel v formatu XML
V podpoglavju 4.1 prikazujemo samo bistvene dele preglednice orodja Excel shranjene
v XML-formatu. Podajmo njeno celotno strukturo:
<?xml version="1.0"?> <?mso-application progid="Excel.Sheet"?> <Workbook xmlns="urn:schemas-microsoft-com:office:s preadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreads heet" xmlns:html="http://www.w3.org/TR/REC-html40"> <DocumentProperties xmlns="urn:schemas-microsoft-c om:office:office"> <Author>Midva</Author> <LastAuthor>Midva</LastAuthor> <Created>2008-12-09T18:37:05Z</Created> <LastSaved>2008-12-09T18:38:26Z</LastSaved> <Version>11.9999</Version> </DocumentProperties> <ExcelWorkbook xmlns="urn:schemas-microsoft-com:of fice:excel"> <WindowHeight>13050</WindowHeight> <WindowWidth>15315</WindowWidth> <WindowTopX>360</WindowTopX> <WindowTopY>105</WindowTopY> <ProtectStructure>False</ProtectStructure> <ProtectWindows>False</ProtectWindows> </ExcelWorkbook> <Styles> <Style ss:ID="Default" ss:Name="Normal"> <Alignment ss:Vertical="Bottom"/>
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 54
<Borders/> <Font x:CharSet="238"/> <Interior/> <NumberFormat/> <Protection/> </Style> <Style ss:ID="s21"> <Font x:CharSet="238" x:Family="Swiss" ss:Bold=" 1"/> </Style> </Styles> <Worksheet ss:Name="Sheet1"> <Table ss:ExpandedColumnCount="6" ss:ExpandedRowC ount="3" x:FullColumns="1" x:FullRows="1"> <Row> <Cell ss:StyleID="s21"><Data ss:Type="String">Š ifra</Data></Cell> <Cell ss:StyleID="s21"><Data ss:Type="String">P riimek</Data></Cell> <Cell ss:StyleID="s21"><Data ss:Type="String">I me</Data></Cell> <Cell ss:StyleID="s21"><Data ss:Type="String">S pol</Data></Cell> <Cell ss:StyleID="s21"/> <Cell ss:StyleID="s21"/> </Row> <Row> <Cell><Data ss:Type="Number">2479</Data></Cell> <Cell><Data ss:Type="String">Besic</Data></Cell > <Cell><Data ss:Type="String">Arijana</Data></Ce ll> <Cell><Data ss:Type="String">ženski</Data></Cel l> </Row> <Row> <Cell><Data ss:Type="Number">1989</Data></Cell> <Cell><Data ss:Type="String">Novak</Data></Cell > <Cell><Data ss:Type="String">Janez</Data></Cell > <Cell><Data ss:Type="String">moški</Data></Cell > </Row> </Table> <WorksheetOptions xmlns="urn:schemas-microsoft-co m:office:excel"> <Print> <ValidPrinterInfo/> <PaperSizeIndex>9</PaperSizeIndex> <HorizontalResolution>-3</HorizontalResolution> <VerticalResolution>0</VerticalResolution> </Print> <Selected/> <ProtectObjects>False</ProtectObjects> <ProtectScenarios>False</ProtectScenarios> </WorksheetOptions> </Worksheet> <Worksheet ss:Name="Sheet2"> <WorksheetOptions xmlns="urn:schemas-microsoft-co m:office:excel"> <ProtectObjects>False</ProtectObjects> <ProtectScenarios>False</ProtectScenarios> </WorksheetOptions> </Worksheet> <Worksheet ss:Name="Sheet3"> <WorksheetOptions xmlns="urn:schemas-microsoft-co m:office:excel"> <ProtectObjects>False</ProtectObjects> <ProtectScenarios>False</ProtectScenarios> </WorksheetOptions> </Worksheet> </Workbook>
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 55
C. Razred ExcelAdapter
Podšoglavje 4.1 namenjamo povezavi programa za preizkušanje z elektronsko
preglednico orodja Excel, ki vsebuje preizkusne podatke. V nadaljevanju prikazujemo
celotno izvorno kodo razreda ExcelAdapter, ki nam omogoča dostop do podatkov v
preglednici.
using System; using System.Collections; using System.Collections.Specialized; using System.Diagnostics; using System.Xml; using System.IO; using Microsoft.Office.Interop.Excel; namespace test_data_via_xml { /// <summary> /// Razred za dostop do preizkusnih podatkov v Ex celovi preglednici. /// </summary> public class ExcelAdapter { private StringDictionary slovar = new StringDic tionary(); private XmlNodeList nodes; private int trenutnoVozlisce = -1; private int steviloPodatkov = 0; private string[] imenaPodatkov; private string[] vrednostiPodatkov; /// <summary> /// Vrne število vrstic v preglednici s preizku snimi podatki. /// </summary> public int SteviloVrstic { get { return nodes.Count - 1; } } public ExcelAdapter(string datotekaXls) { string datotekaXml = datotekaXls.Replace(".xl s", ".xml"); // Potrebno zaradi programske napake opisane na http://support.microsoft.com/kb/320369 System.Threading.Thread.CurrentThread.Current Culture = new System.Globalization.CultureInfo("en-US"); Microsoft.Office.Interop.Excel.Application ex celApp = new Microsoft.Office.Interop.Excel.Applicat ion(); // Odpiranje Excelove datoteke. Microsoft.Office.Interop.Excel.Workbook workB ook = excelApp.Workbooks.Open(datotekaXls, 0, tru e, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.x lWindows, "\t", false, false, 0, true, false, false); // Shranjevanje v XML-format. workBook.SaveAs(datotekaXml, Microsoft.Office.Interop.Excel.XlFileFormat.xlXMLSp readsheet,
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 56
null, null, false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.x lNoChange, false, false, null, null, null); // Zapiranje preglednice brez shranjevanja sp rememb. workBook.Close(false, Type.Missing, Type.Miss ing); FileStream stream = File.Open(datotekaXml, Fi leMode.Open); // Ustvari nov XmlDocument objekt in ga napol ni s podatki iz datoteke. XmlDocument document = new XmlDocument(); document.Load(stream); // Definicija ustreznih imenskih prostorov po trebnih za branje XML-datoteke shranjene // z orodjem Excel. XmlNamespaceManager nsMgr= new XmlNamespaceMa nager(document.NameTable); nsMgr.AddNamespace("ss", "urn:schemas-microso ft-com:office:spreadsheet"); XmlElement root = document.DocumentElement; nodes = root.SelectNodes("//ss:Worksheet/ss:T able/ss:Row",nsMgr); steviloPodatkov = nodes[0].ChildNodes.Count; // Naplni polje, ki vsebuje imena podatkov, t j. naslovno vrstico preglednice. NapolniPolje(out imenaPodatkov); } private void NapolniPolje(out string[] polje) { XmlNode node = this.VrniNaslednjeVozlisce(); if (node != null) { polje = new string[steviloPodatkov]; for (int i = 0; i < node.ChildNodes.Count; i++) polje[i] = node.ChildNodes[i].InnerText; } else polje = null; } private XmlNode VrniNaslednjeVozlisce() { trenutnoVozlisce++; if (trenutnoVozlisce >= nodes.Count) return null; else return nodes[trenutnoVozlisce]; } /// <summary> /// Vrne naslednji slovar s preizkusnimi podatk i. /// </summary> /// <returns></returns> public StringDictionary VrniNaslednjiSlovar() { slovar.Clear(); NapolniPolje(out vrednostiPodatkov); if (vrednostiPodatkov != null) { for (int i = 0; i < steviloPodatkov; i++) {
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 57
slovar.Add(imenaPodatkov[i], vrednostiPod atkov[i]); } } else slovar = null; return slovar; } } }
D. Program za preizkušanje
V podpoglavju 4.2 prikazujemo del izvorne kode programa za preizkušanje. V
nadaljevanju podajamo celotno izvorno kodo. Za dostop do preizkusnih podatkov, ki so
shranjeni v preglednici orodja Excel uporablja program razred ExcelAdapter (glej prilogo
C).
using System; using System.Drawing; using System.Diagnostics; using System.Xml; using System.IO; using System.Collections; using System.Collections.Specialized; using Ranorex; class VstaviUcenca { /// <summary> /// Program, ki preizkusi vstavljanje novega u čenca s programom Glasovir. Za dostop do preglednice /// s preizkusnimi podatki uporablja razred Excel Adapter. /// </summary> [STAThread] static void Main(string[] args) { VstaviUcenca vstaviUcenca = new VstaviUcenca(); Form formGlasovir; Control listUcenci; Control parent; float timeScale = 1.0f; formGlasovir = Application.StartWindowsApplication(@"D:\Faksus\dip loma\glasovir\bin\glasovir.exe", null, (int)(timeScale*5000)); parent = formGlasovir.FindControlName("tabUcenc i"); listUcenci = parent.FindControlName("listUcenci "); listUcenci.Focus(); string file = @"D:\Faksus\diploma\ranorex_guitest\xml_test_data\t est_data_via_xml\bin\Debug\preizkusni_podatki.xls";
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 58
ExcelAdapter xmlAdapter = new ExcelAdapter(file ); StringDictionary sd; int stevec = 1; int steviloVrstic = xmlAdapter.SteviloVrstic; while ((sd = xmlAdapter.VrniNaslednjiSlovar()) != null) { try { Console.Write("Vstavljam u čenca 1 (od {0})...", steviloVrstic); Mouse.ClickControl(listUcenci, MouseButtonT ype.RightButton); Point curPos = Mouse.Position; Mouse.Click(MouseButtonType.LeftButton, cur Pos.X + 10, curPos.Y + 60); Form frmUcenec = Application.FindFormTitle( "Učenec"); // Polnjenje forme "U čenec" s podatki. vstaviUcenca.VrniKontrolnik(frmUcenec, "tbS ifra").Text = sd["šifra"]; vstaviUcenca.VrniKontrolnik(frmUcenec, "tbP riimek").Text = sd["priimek"]; vstaviUcenca.VrniKontrolnik(frmUcenec, "tbI me").Text = sd["ime"]; vstaviUcenca.VrniKontrolnik(frmUcenec, "tbU lica").Text = sd["ulica"]; vstaviUcenca.VrniKontrolnik(frmUcenec, "tbK raj").Text = sd["kraj"]; if (sd["spol"] == "Ž") ((RadioButton)vstaviUcenca.VrniKontrolnik (frmUcenec, "rbZenski")).Checked = true; if (sd["privat"] == "Da") ((RadioButton)vstaviUcenca.VrniKontrolnik (frmUcenec, "rbJePrivat")).Checked = true; ((ComboBox)vstaviUcenca.VrniKontrolnik(frmU cenec, "cbStatus")).SelectedText = sd["status"]; Mouse.ClickControl(frmUcenec.FindControlNam e("btnDodaj")); Application.Sleep(500); // Iskanje vrstice v seznamu u čencev, ki vsebuje podatke o pravkar vstaljenem u čencu. Element iskaniUcenec = listUcenci.Element.F indChild(Role.ListItem, sd["šifra"]); Mouse.ClickElement(iskaniUcenec, MouseButto nType.LeftButton); StringDictionary izhodi = vstaviUcenca.Vrni SlovarIzhodov(iskaniUcenec); ArrayList napacniKljuci = null; // Če se dejanski podatki ne ujemajo s pri čakovnimi, izpiši informacije o napaki. if (!vstaviUcenca.StaEnakaSlovarja(sd, izho di, ref napacniKljuci)) { Console.Write(" NAPAKA pri ID {0}\n", sd[ "šifra"]); foreach (string kljuc in napacniKljuci) Console.Write("\t{0}:\t{1}\t(pri čakovan {2}) {3}\n", kljuc, izhodi[kljuc], sd[kljuc], napacniKljuci.Count); napacniKljuci.Clear(); napacniKljuci = null; } else Console.Write(" V redu.\n"); }
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 59
catch (Exception) { Console.Write( "NEUSPEŠEN ZAKLJU ČEK OPERACIJE!\n"); } stevec++; } // Zapiranje aplikacije s kombinacijo Alt + F4. Application.SendKeys("%{F4}"); } /// <summary> /// Vrne kontrolnik (Ranorex.Control) za podano f ormo in ime kontrolnika. /// </summary> /// <param name="forma">Forma s kontrolnikom.</pa ram> /// <param name="imeKontrolnika">Ime kontrolnika. </param> /// <returns></returns> private Control VrniKontrolnik (Form forma, strin g imeKontrolnika) { return forma.FindControlName(imeKontrolnika); } /// <summary> /// Iz dane vrstice seznama tvori slovar. /// </summary> /// <param name="vrstica">Vrstica seznama</param> private StringDictionary VrniSlovarIzhodov(Elemen t vrstica) { StringDictionary slovarIzhodov = new StringDict ionary(); // Šifra preberemo iz lasnosti "Name", preostal e podatke pa iz "Description". slovarIzhodov.Add("šifra", vrstica.Name); // Preostali podatki so v nizu oblike "podatek_ 1: vrednost_podatka_1; podatek_2: vrednost_podatka_2; ..." // Niz najprej razdelimo pri podpi čjih. string [] niziPodpicja = vrstica.Description.Sp lit(';'); foreach (string niz in niziPodpicja) { string [] nizDvopicje = niz.Split(':'); slovarIzhodov.Add(nizDvopicje[0].Trim(), nizD vopicje[1].Trim()); } return slovarIzhodov; } /// <summary> /// Vrne logi čno vrednost true, če slovarja vsebujeta enake zapise. /// </summary> /// <param name="slovarVhodov">Slovar z vhodnimi podatki.</param> /// <param name="slovarIzhodov">Slovar s podatk i z vrstice seznama.</param> /// <param name="napacniKljuci">Polje, ki se napo lni z imeni napa čnih klju čev, če pride do neujemanja.</param> /// <returns></returns> private bool StaEnakaSlovarja(StringDictionary sl ovarVhodov, StringDictionary slovarIzhodov, ref ArrayList napacniKljuci) { if (slovarIzhodov.Count != slovarVhodov.Count) return false; bool rezultat = true; foreach ( DictionaryEntry de in slovarIzhodov ) { if (slovarVhodov[de.Key.ToString()] != de.Val ue.ToString())
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 60
{ if (napacniKljuci == null) napacniKljuci = new ArrayList(); napacniKljuci.Add(de.Key.ToString()); rezultat = false; } } return rezultat; } }
Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v okolju Windows Stran 61
Priloga 6
IZJAVA O ISTOVETNOSTI TISKANE IN ELEKTRONSKE VERZIJE ZAKLJUČNEGA DELA IN OBJAVI OSEBNIH PODATKOV AVTORJA
Ime in priimek avtorja: Gregor Zorc
Vpisna številka: 93578292
Študijski program: VS ŠP Računalništvo in informatika
Naslov zaključnega dela: Avtomatsko preizkušanje grafičnega uporabniškega vmesnika v
okolju Windows
Mentor: izr. prof. dr. Božidar POTOČNIK
Podpisani Gregor Zorc izjavljam, da sem za potrebe arhiviranja oddal elektronsko verzijo zaključnega dela v Digitalno knjižnico Univerze v Mariboru. Zaključno delo sem izdelal sam ob pomoči mentorja. V skladu s 1. odstavkom 21. člena Zakona o avtorskih in sorodnih pravicah (Ur. l. RS, št. 16/2007) dovoljujem, da se zgoraj navedeno zaključno delo objavi na portalu Digitalne knjižnice Univerze v Mariboru. Tiskana verzija zaključnega dela je istovetna elektronski verziji, ki sem jo oddal za objavo v Digitalno knjižnico Univerze v Mariboru. Podpisani izjavljam, da dovoljujem objavo osebnih podatkov, vezanih na zaključek študija (ime, priimek, leto in kraj rojstva, datum zagovora, naslov zaključnega dela) na spletnih straneh in v publikacijah UM.
Kraj in datum: Maribor, 19.1.2009
Podpis avtorja:
UNIVERZA V MARIBORU Fakulteta za elektrotehniko, računalništvo
in informatiko