Programiranje

Preizkusite spletne aplikacije s HttpUnit

V tipični poslovni aplikaciji je treba na številnih področjih preizkusiti. Začenši z najpreprostejšimi komponentami, razredi, morajo razvijalci ali specializirani razvijalci preizkusov programirati preskuse enot, da zagotovijo pravilno delovanje najmanjših enot aplikacije. Vsaka komponenta lahko sama opravi preskus enote; vendar morajo razvijalci zagotoviti, da sodelujejo po pričakovanjih - kot del podsistema in kot del celotne aplikacije - torej, integracijski testi je treba izvesti. Pri nekaterih projektih morajo biti izpolnjene zahteve glede učinkovitosti, tako da to zagotavljajo inženirji za zagotavljanje kakovosti preskusi obremenitve preveriti in dokumentirati delovanje aplikacije pod različnimi pogoji. Med razvojem aplikacij inženirji za zagotavljanje kakovosti izvajajo avtomatizirano in ročno funkcionalni testi za testiranje vedenja aplikacije z vidika uporabnika. Ko razvojni projekt skoraj izpolni določen mejnik, sprejemni preskusi se lahko izvede, da se preveri, ali aplikacija izpolnjuje zahteve.

HttpUnit je ogrodje, ki temelji na JUnit-u in omogoča izvajanje samodejnih testnih skriptov za spletne aplikacije. Najbolj primeren je za izvajanje avtomatiziranih funkcionalnih testov ali sprejemnih testov. Kot že ime pove, se lahko uporablja za enotno testiranje; vendar pa tipične komponente spletne plasti, kot so strani JSP (JavaServer Pages), strežniški programčki in druge komponente predloge, niso primerne za enotno testiranje. Kar zadeva različne komponente, ki temeljijo na okolju MVC (Model-View Controller), so te bolj primerne za testiranje z drugimi okviri za testiranje. Dejanja Struts lahko enotno preizkusite s storitvijo StrutsUnit, dejanja WebWork 2 pa lahko na primer brez spletnega vsebnika.

Testni cilji

Preden skočimo v podrobnosti o arhitekturi in izvedbi, je treba natančno pojasniti, kaj bodo testne skripte morale dokazati o spletni aplikaciji. Obnašanje naključnega obiskovalca spletnega mesta je mogoče preprosto simulirati s klikom na zanimive povezave in branjem strani v naključnem vrstnem redu, vendar rezultat teh naključnih skript ne bi opisal popolnosti in kakovosti aplikacije.

Tipična poslovna spletna aplikacija (ali zapleteno spletno mesto) vsebuje več dokumentov, ki opisujejo zahteve različnih uporabnikov ali vzdrževalcev aplikacij. Ti lahko vključujejo specifikacije primerov uporabe, specifikacije nefunkcionalnih zahtev, specifikacije testnih primerov, ki izhajajo iz drugih artefaktov, dokumente o oblikovanju uporabniškega vmesnika, makete, profile igralcev in različne dodatne artefakte. Za preprosto aplikacijo bi lahko celotna specifikacija lahko vsebovala preprosto besedilno datoteko s seznamom zahtev.

Iz teh dokumentov moramo ustvariti organiziran seznam testnih primerov. Vsak testni primer opisuje scenarij, ki ga lahko spletni obiskovalec opravi prek spletnega brskalnika. Dobra praksa je, da si prizadevamo za podobne scenarije - večje scenarije je mogoče razčleniti na manjše dele. Veliko odličnih knjig in člankov razpravlja o oblikovanju specifikacij testnih primerov. V tem članku predpostavimo, da imate nabor elementov, ki jih želite preizkusiti za svojo spletno aplikacijo, razvrščene v sklope scenarijev testnih primerov.

Čas je za prenos stvari!

V redu, zdaj poznamo dolgočasne stvari, naložimo si nekaj kul igrač! Najprej za namestitev in izvajanje testov potrebujemo nameščen paket Java SDK 2. Nato moramo prenesti ogrodje HttpUnit - trenutno v različici 1.5.5. Binarni paket vsebuje vse zahtevane knjižnice drugih proizvajalcev. Za samodejno izvajanje testov in ustvarjanje poročil bomo potrebovali tudi orodje Ant build. Verjetno bi delovala katera koli dokaj nova različica teh orodij; Raje uporabljam najnovejšo in najboljšo različico vsega.

Če želite pisati in izvajati teste, priporočam uporabo IDE, ki ima vgrajen JUnit testni tekač. Za razvoj preizkusnih skriptov uporabljam Eclipse 3.0M7, vendar ima IntelliJ tudi podporo za JUnit, tako kot nedavno izdani IDE.

HttpUnit: simulator odjemalca HTTP

Ker želimo preizkusiti spletne aplikacije, bi se v idealnem primeru moralo preizkusno orodje obnašati popolnoma enako kot spletni brskalniki uporabnikov. Naša aplikacija (testni cilj) se ne sme zavedati kakršne koli razlike pri serviranju strani spletnemu brskalniku ali testnemu orodju. Natanko to ponuja HttpUnit: simulira običajne zahteve GET in POST v brskalniku in nudi lep objektni model, s katerim lahko kodiramo naše teste.

Za ostale razrede in metode si oglejte podroben priročnik za API; Na sliki 1 je le kratek pregled razredov, ki jih najpogosteje uporabljam. Uporabniška seja (zaporedje interakcij s spletno aplikacijo) je zaprta z Spletni pogovor. Konstruiramo WebRequests, običajno konfiguriramo URL in parametre, nato pa jih pošljemo po Spletni pogovor. Nato ogrodje vrne a WebResponse, ki vsebuje vrnjeno stran in atribute s strežnika.

Tu je primer HttpUnit testnega primera iz dokumentov HttpUnit:

 / ** * Preveri, da oddaja prijavnega obrazca z imenom "master" povzroči * na strani, ki vsebuje besedilo "Top Secret" ** / public void testGoodLogin (), vrže izjemo {WebConversation konverzacija = new WebConversation (); Zahteva za WebRequest = nova GetMethodWebRequest ("//www.meterware.com/servlet/TopSecret"); WebResponse response = konverzacija.getResponse (zahteva); WebForm loginForm = response.getForms () [0]; request = loginForm.getRequest (); request.setParameter ("ime", "glavni"); odgovor = pogovor.getResponse (zahteva); assertTrue ("Prijava ni sprejeta", response.getText (). indexOf ("Uspelo vam je!")! = -1); assertEquals ("Naslov strani", "Strogo tajno", response.getTitle ()); } 

Arhitekturni premisleki

Opazite, kako zgornji vzorec Java vsebuje ime domene strežnika, ki izvaja aplikacijo. Med razvojem novega sistema aplikacija živi na več strežnikih in strežniki lahko izvajajo več različic. Očitno je slaba ideja, da ime strežnika ostane v izvedbi Java - za vsak nov strežnik moramo znova zbrati svoje vire. Drugi elementi ne smejo biti v izvornih datotekah, na primer uporabniška imena in gesla, kar bi moralo biti nastavljiv za določeno uvajanje. Po drugi strani pa ne smemo preveč arhitekturirati preproste izvedbe testnega primera. Specifikacija testnega primera običajno vsebuje večino stanja sistema in specifičnih opisov parametrov za naš scenarij, zato obstaja nima smisla, da bi bilo vse mogoče parameterizirati pri izvajanju.

Med kodiranjem boste ugotovili, da se veliko odsekov kode pojavi v več izvedbah testnega primera (potencialno v vseh testnih primerih). Če ste izkušen objektno usmerjen razvijalec, vas bo zamikalo, da ustvarite hierarhije razredov in pogoste razrede. V nekaterih primerih je to zelo smiselno - na primer postopek prijave bi moral biti skupna metoda, ki je na voljo za vse testne primere. Vendar se morate nekoliko odmakniti in se zavedati, da ne gradite novega produkcijskega sistema na vrhu aplikacije za preizkus - ti razredi Java niso nič drugega kot testni skripti za preverjanje izhodnih podatkov spletnega mesta. Vadite zdravo pamet in si prizadevajte za preproste, zaporedne in samostojne testne skripte.

Testni primeri so običajno krhki. Če razvijalec spremeni URL, reorganizira postavitev

strukturo ali spremeni ID elementa obrazca, obiskovalec verjetno ne bo videl nobene razlike, ampak vaše testne skripte volja pihati. Pričakujte veliko predelave in sprememb za vsako izvedbo testnega primera. Predmetno načrtovanje bi lahko zmanjšalo napor pri predelavi skupnih delov v testnih primerih, toda z vidika inženirja ali preizkuševalca za zagotavljanje kakovosti sem prepričan, da preprost, zaporedni skript ki je v interakciji s spletnim mestom, je lažje vzdrževati in popravljati.

Sledljivost je ključnega pomena za naše testne primere. Če gre kaj KA-BOOM ali je na primer rezultat izračuna napačen, je pomembno, da razvijalca usmerite k ustrezni specifikaciji testnega primera in specifikaciji primera uporabe za hitro reševanje napak. Zato svojo implementacijo označite s sklici na prvotne specifikacijske dokumente. Vključno s številko različice teh dokumentov je prav tako koristno. To je lahko zgolj preprost komentar kode ali zapleten mehanizem, pri katerem se poročila o preskusih povezujejo z dokumenti; pomembna stvar je, da je referenca v kodi in ohraniti sledljivost.

Kdaj moram napisati kodo?

Zdaj, ko ste seznanjeni z zahtevami (dokumenti uporabe in ustrezne specifikacije testnega primera), razumete osnove ogrodja in imate nabor arhitekturnih smernic, se lotimo dela.

Za razvoj implementacij testnih primerov raje delam v Eclipseu. Najprej ima prijetnega JUnit testnega tekača. Izberete lahko razred Java, v meniju Zaženi pa ga lahko zaženete kot preskus enote JUnit. Tekač prikaže seznam prepoznanih testnih metod in rezultat izvedbe. Ko se med preizkusom vse popravi, se prikaže lepa zelena črta. Če je prišlo do napake izjeme ali trditve, se prikaže rdeča črta v stiski. Menim, da je vizualna povratna informacija res pomembna - ponuja občutek dosežka, še posebej pri pisanju enotnih testov za svojo kodo. Prav tako rad uporabljam Eclipse zaradi njegovih zmožnosti refaktoringa. Če se zavedam, da moram v razredu testnega primera kopirati in prilepiti odseke kode, lahko preprosto uporabim meni Refactoring, da namesto tega ustvarim metodo iz odseka kode. Če se zavedam, da bodo številni testni primeri uporabili isto metodo, lahko z uporabo menija povlečem svojo metodo v svoj osnovni razred.

Na podlagi zgornjih arhitekturnih zahtev za vsak projekt običajno izdelam osnovni razred testnega primera, ki razširja JUnit TestCase razred. Jaz temu rečem ConfigurableTestCase. Vsaka izvedba testnega primera ta razred razširi, glejte sliko 2.

ConfigurableTestCase običajno vsebuje običajne metode in inicializacijsko kodo za testni primer. Datoteko lastnosti uporabljam za shranjevanje imena strežnika, konteksta aplikacije, različnih prijavnih imen za vsako vlogo in nekaterih dodatnih nastavitev.

Posebne izvedbe testnih primerov vsebujejo eno preskusno metodo na scenarij testnega primera (iz dokumenta o specifikaciji testnega primera). Vsaka metoda se običajno prijavi z določeno vlogo in nato izvede interakcijo s spletno aplikacijo. Večina testnih primerov za izvajanje dejavnosti ne potrebuje določenega uporabnika; običajno zahtevajo uporabnika v določeni vlogi, na primer skrbnika, obiskovalca ali registriranega uporabnika. Vedno ustvarim a LoginMode enum, ki vsebuje razpoložljive vloge. S paketom Jakarta Commons ValuedEnum ustvarjam naštevanje vlog. Ko se prijavi določena preskusna metoda v implementaciji testnega primera, mora določiti, katera vloga za prijavo je potrebna za določen preskusni scenarij. Seveda mora biti mogoča tudi prijava z določenim uporabnikom, na primer za preverjanje primera uporabe registriranega uporabnika.

Po vsakem ciklu zahteve in odziva moramo običajno preveriti, ali vrnjena stran vsebuje napako, in preveriti trditve o vsebini odgovora. Tudi tu moramo biti previdni; preverjati bi morali samo elemente, ki v aplikaciji niso spremenljivi in ​​niso preveč občutljivi. Na primer, če uveljavljamo določene naslove strani, se naši preizkusi verjetno ne bodo izvajali, če je jezik mogoče izbrati v aplikaciji in želimo preveriti uvajanje drugega jezika. Podobno je malo smisla preverjati element na strani glede na njegov položaj v postavitvi tabele; zasnove na osnovi tabel se pogosto spreminjajo, zato bi si morali prizadevati za prepoznavanje elementov na podlagi njihovih ID-jev. V primeru, da nekateri pomembni elementi na strani nimajo ID-jev ali imen, bi morali razvijalce preprosto prositi, naj jih dodajo, namesto da bi jih poskušali zaobiti.

Trditve JUnit ponujajo slab pristop za preverjanje, ali videz, postavitev in oblikovanje strani ustrezajo zahtevam. Glede na neskončno veliko časa za razvoj testa je možno, vendar lahko dober človeški tester te stvari oceni bolj učinkovito. Zato se osredotočite na preverjanje funkcionalnosti spletne aplikacije, namesto da bi preverili vse, kar je na strani mogoče.

Tu je posodobljen testni scenarij, ki temelji na naši arhitekturi testnega primera. Razred se razširi ConfigurableTestCase, in podatki za prijavo so obdelani v osnovnem razredu:

 / ** * Preveri, da oddaja prijavnega obrazca z imenom "master" povzroči * na strani, ki vsebuje besedilo "Top Secret" ** / public void testGoodLogin (), vrže izjemo {WebConversation pogovora = new WebConversation (); WebResponse response = prijava (pogovor, LoginMode.ADMIN_MODE); assertTrue ("Prijava ni sprejeta", response.getText (). indexOf ("Uspelo vam je!")! = -1); assertEquals ("Naslov strani", "Strogo tajno", response.getTitle ()); } 

Namigi in triki

Z nastavitvijo lahko večino scenarijev enostavno obdelate Spletni obrazec parametrov in nato poiščite posebne elemente z rezultati v WebResponse strani, vendar je vedno nekaj zahtevnih testnih primerov.

$config[zx-auto] not found$config[zx-overlay] not found