Programmēšana

Pārbaudiet tīmekļa lietojumprogrammas ar HttpUnit

Parastā uzņēmuma lietojumprogrammā daudzās jomās ir jāveic pārbaude. Sākot no vienkāršākajiem komponentiem, klasēm, izstrādātājiem vai specializētiem testu izstrādātājiem jāprogrammē vienību testi, lai pārliecinātos, ka lietojumprogrammas mazākās vienības darbojas pareizi. Katrs komponents var izturēt vienības testus atsevišķi; tomēr izstrādātājiem ir jānodrošina, ka viņi strādā kopā, kā paredzēts, kā daļu no apakšsistēmas un kā daļu no visas lietojumprogrammas, tādējādi integrācijas testi jāveic. Dažos projektos ir jāizpilda veiktspējas prasības, tāpēc darbojas kvalitātes nodrošināšanas inženieri slodzes testi lai pārbaudītu un dokumentētu lietojumprogrammas veiktspēju dažādos apstākļos. Lietojumprogrammu izstrādes laikā kvalitātes nodrošināšanas inženieri veic automatizētu un manuālu darbību funkcionālie testi lai pārbaudītu lietojumprogrammas darbību no lietotāja viedokļa. Kad attīstības projekts gandrīz pabeidz noteiktu pagrieziena punktu, pieņemšanas testi var pārbaudīt, vai lietojumprogramma atbilst prasībām.

HttpUnit ir uz JUnit balstīta sistēma, kas ļauj ieviest automatizētus testa skriptus tīmekļa lietojumprogrammām. Tas ir vislabāk piemērots automatizētu funkcionālo testu vai pieņemšanas testu ieviešanai. Kā norāda nosaukums, to var izmantot vienības testēšanai; tomēr tipiski tīmekļa slāņa komponenti, piemēram, JSP (JavaServer Pages) lapas, servleti un citi veidņu komponenti, nav piemēroti vienību testēšanai. Kas attiecas uz dažādiem MVC (Model-View Controller) ietvara komponentiem, tie ir labāk piemēroti testēšanai ar citām testēšanas sistēmām. Struts darbības var pārbaudīt vienībā, izmantojot StrutsUnit, un WebWork 2 darbības var pārbaudīt, piemēram, bez tīmekļa konteinera.

Pārbaudes mērķi

Pirms mēs pievērsīsimies arhitektūras un ieviešanas detaļām, ir svarīgi precīzi noteikt, kādi testa skripti būs jāpierāda par tīmekļa lietojumprogrammu. Ir iespējams vienkārši simulēt gadījuma vietnes apmeklētāja uzvedību, vienkārši noklikšķinot uz interesantām saitēm un izlasot lapas nejaušā secībā, taču šo nejaušo skriptu rezultāts neaprakstītu lietojumprogrammas pilnīgumu un kvalitāti.

Tipiskai uzņēmuma tīmekļa lietojumprogrammai (vai sarežģītai vietnei) ir vairāki dokumenti, kas apraksta dažādu lietotāju vai lietojumprogrammu uzturētāju prasības. Tie var ietvert lietošanas gadījumu specifikācijas, nefunkcionālas prasību specifikācijas, testa gadījumu specifikācijas, kas iegūtas no citiem artefaktiem, lietotāja saskarnes noformējuma dokumentus, maketus, dalībnieku profilus un dažādus papildu artefaktus. Vienkāršai lietojumprogrammai visa specifikācija, iespējams, varētu sastāvēt no vienkārša teksta faila ar prasību sarakstu.

No šiem dokumentiem mums jāizveido organizēts testa gadījumu saraksts. Katrā testa gadījumā ir aprakstīts scenārijs, kuru tīmekļa apmeklētājs var paveikt, izmantojot tīmekļa pārlūkprogrammu. Laba prakse ir mērķēt uz līdzīga lieluma scenārijiem - lielākus scenārijus var sadalīt mazākos gabalos. Daudzās izcilās grāmatās un rakstos tiek apspriests testa gadījumu specifikāciju izveide. Pieņemsim, ka šajā rakstā jums ir vienumu kopums, kuru vēlaties pārbaudīt savai tīmekļa lietojumprogrammai, kas sakārtots testa gadījumu scenārijos.

Laiks lejupielādēt sīkumus!

Labi, tagad mēs zinām garlaicīgas lietas, lejupielādēsim dažas foršas rotaļlietas! Pirmkārt, mums ir nepieciešams instalēts Java 2 SDK, lai apkopotu un izpildītu testus. Tad mums ir jālejupielādē HttpUnit ietvars - pašlaik versija 1.5.5. Binārā pakete satur visas nepieciešamās trešo pušu bibliotēkas. Mums būs nepieciešams arī Ant veidošanas rīks, lai automātiski palaistu testus un ģenerētu pārskatus. Jebkura diezgan jauna šo rīku versija, iespējams, darbotos; Es tikai gribētu izmantot visjaunāko un labāko versiju.

Lai rakstītu un veiktu testus, iesaku izmantot IDE, kurā ir iestrādāts JUnit testa skrējējs. Es izmantoju Eclipse 3.0M7, lai izstrādātu savus testa skriptus, bet IntelliJ ir arī JUnit atbalsts, tāpat kā nesen izlaistajiem IDE.

HttpUnit: HTTP klienta simulators

Tā kā mēs vēlamies pārbaudīt tīmekļa lietojumprogrammas, ideālā gadījumā testa rīkam vajadzētu rīkoties tieši tāpat kā lietotāju tīmekļa pārlūkprogrammām. Mūsu lietojumprogrammai (testa mērķim) nevajadzētu būt informētai par atšķirībām, kad lapas tiek rādītas tīmekļa pārlūkprogrammā vai testa rīkā. Tieši to nodrošina HttpUnit: tas simulē parastās pārlūkprogrammas GET un POST pieprasījumus un nodrošina jauku objekta modeli, ar kuru kodēt mūsu testus.

Pārbaudiet detalizēto API rokasgrāmatu pārējām klasēm un metodēm; 1. attēlā ir sniegts īss pārskats par klasēm, kuras es visbiežāk izmantoju. Lietotāja sesija (mijiedarbības ar tīmekļa lietojumprogrammu secība) ir iekapsulēta ar a Web saruna. Mēs konstruējam WebRequests, parasti konfigurējot vietrādi URL un parametrus, un pēc tam mēs tos nosūta, izmantojot Web saruna. Tad ietvars atgriež a WebResponse, kas satur atgriezto lapu un atribūtus no servera.

Šeit ir HttpUnit testa parauga paraugs no HttpUnit dokumentiem:

 / ** * Pārbauda, ​​vai, iesniedzot pieteikšanās veidlapu ar nosaukumu "kapteinis", tiek iegūta * lapa, kurā ir teksts "Sevišķi slepeni" ** / public void testGoodLogin () izmet izņēmumu {WebConversation conversation = new WebConversation (); WebRequest pieprasījums = new GetMethodWebRequest ("//www.meterware.com/servlet/TopSecret"); WebResponse response = saruna.getResponse (pieprasījums); WebForm loginForm = response.getForms () [0]; pieprasījums = loginForm.getRequest (); request.setParameter ("nosaukums", "kapteinis"); atbilde = saruna.getResponse (pieprasījums); assertTrue ("Pieteikšanās nav pieņemta", response.getText (). indexOf ("Jūs to izdarījāt!")! = -1); assertEquals ("Lapas nosaukums", "Ļoti slepens", response.getTitle ()); } 

Arhitektūras apsvērumi

Ievērojiet, kā iepriekš minētajā Java paraugā ir servera, kurā darbojas programma, domēna nosaukums. Izstrādājot jaunu sistēmu, lietojumprogramma dzīvo vairākos serveros, un serveros var darboties vairākas versijas. Acīmredzot ir slikta ideja saglabāt servera nosaukumu Java ieviešanā - katram jaunam serverim mums ir jāpārkompilē avoti. Citi vienumi nedrīkst atrasties avota failos, piemēram, lietotājvārdi un paroles konfigurējams konkrētai izvietošanai. No otras puses, mums nevajadzētu pārspīlēt vienkāršu izmēģinājuma gadījuma ieviešanu. Parasti testa gadījumu specifikācijā jau ir iekļauta lielākā daļa sistēmas stāvokļa un specifisku parametru aprakstu mūsu scenārijam, tāpēc tur ir nav jēgas visu parametrizēt ieviešanā.

Kodēšanas laikā jūs sapratīsit, ka daudzas kodu sadaļas parādās vairāk nekā vienā testa gadījuma ieviešanā (iespējams, visos testa gadījumos). Ja esat pieredzējis objektorientēts izstrādātājs, jums radīsies kārdinājums izveidot klases hierarhijas un kopīgas klases. Dažos gadījumos tam ir daudz jēgas - piemēram, pieteikšanās procedūrai jābūt parastai metodei, kas pieejama visiem testa gadījumiem. Tomēr jums mazliet jāatkāpjas un jāsaprot, ka jūs neveidojat jaunu ražošanas sistēmu virs testa lietojumprogrammas - šīs Java klases ir tikai testa skripti, lai apstiprinātu vietnes izeju. Izmantojiet veselo saprātu un tiecieties pēc vienkāršiem, secīgiem un pašpietiekamiem testa skriptiem.

Pārbaudes gadījumi parasti ir trausli. Ja izstrādātājs maina URL, pārkārtojiet izkārtojumu

struktūru vai maina formas elementa ID, apmeklētājs, iespējams, neredzēs nekādas atšķirības, bet jūsu testa skriptus būs izpūsties. Gaidiet daudz pārstrādes un izmaiņu katrā testa gadījuma ieviešanā. Uz objektu orientēts dizains varētu samazināt kopējo daļu pārstrādes centienus testa gadījumos, taču no kvalitātes nodrošināšanas inženiera vai testētāja viedokļa esmu pārliecināts, ka vienkāršs, secīgs skripts kas mijiedarbojas ar vietni, ir vieglāk uzturēt un labot.

Izsekojamībai ir izšķiroša nozīme mūsu testa gadījumos. Ja kaut kas notiek KA-BOOM vai, piemēram, aprēķinu rezultāts ir nepareizs, ir svarīgi izstrādātājam norādīt atbilstošo testa gadījumu specifikāciju un lietošanas gadījumu specifikāciju ātrai kļūdu atrisināšanai. Tādēļ anotējiet savu ieviešanu ar atsaucēm uz specifikācijas oriģināliem. Ir noderīgi iekļaut arī šo dokumentu versijas numuru. Tas varētu būt tikai vienkāršs koda komentārs vai sarežģīts mehānisms, kurā testa ziņojumos ir saites uz dokumentiem; svarīgi ir, lai kodā būtu atsauce un saglabāt izsekojamību.

Kad es varu uzrakstīt kodu?

Tagad, kad esat informēts par prasībām (lietošanas gadījumu dokumenti un atbilstošās testa gadījumu specifikācijas), saprotat ietvara pamatus un jums ir arhitektūras vadlīniju kopums, ķeramies pie darba.

Izstrādājot testpiemērus, es dodu priekšroku darbam Eclipse. Pirmkārt, tam ir jauks JUnit testa skrējējs. Jūs varat izvēlēties Java klasi, un izvēlnē Palaist varat to palaist kā JUnit vienības testu. Skrējējs parāda atzīto testa metožu sarakstu un izpildes rezultātu. Kad testa brauciena laikā viss notiek kārtībā, tas piešķir jauku zaļu līniju. Ja radās izņēmums vai apgalvojums, tas parāda satraucošu sarkanu līniju. Es domāju, ka vizuālā atgriezeniskā saite ir patiešām svarīga - tā piedāvā paveikto, it īpaši, rakstot vienības testus savam kodam. Es arī labprāt izmantoju Eclipse tā atjaunošanas iespējām. Ja es saprotu, ka testa gadījumu klasē man ir jākopē un jāielīmē koda sadaļas, es varu vienkārši izmantot Refactoring izvēlni, lai tā vietā izveidotu metodi no koda sadaļas. Ja es saprotu, ka daudzos testa gadījumos tiks izmantota viena un tā pati metode, es varu izmantot izvēlni, lai izvēlētos savu metodi savā pamatklasē.

Pamatojoties uz iepriekšējām arhitektūras prasībām, katram projektam es parasti izveidoju bāzes testa gadījumu klasi, kas paplašina JUnit TestCase klasē. Es to saucu ConfigurableTestCase. Katra testa gadījuma ieviešana paplašina šo klasi, sk. 2. attēlu.

ConfigurableTestCase parasti satur testa gadījumam parastās metodes un inicializācijas kodu. Es izmantoju rekvizītu failu, lai saglabātu servera nosaukumu, lietojumprogrammas kontekstu, dažādus pieteikšanās vārdus katrai lomai un dažus papildu iestatījumus.

Konkrētajā testa gadījuma ieviešanā ir viena testa metode katram testa gadījuma scenārijam (no testa gadījumu specifikācijas dokumenta). Katra metode parasti piesakās ar noteiktu lomu un pēc tam veic mijiedarbību ar tīmekļa lietojumprogrammu. Vairumam testa gadījumu darbību veikšanai nav nepieciešams noteikts lietotājs; viņiem parasti ir nepieciešams lietotājs noteiktā lomā, piemēram, administrators vai apmeklētājs vai reģistrēts lietotājs. Es vienmēr izveidoju LoginMode enum, kas satur pieejamās lomas. Es izmantoju paketi Jakarta Commons ValuedEnum, lai izveidotu lomas. Kad tiek pierakstīta īpaša testa metode testa gadījuma ieviešanā, tai jānorāda, kura pieteikšanās loma ir nepieciešama konkrētajam testa scenārijam. Protams, jābūt iespējai arī pieteikties ar konkrētu lietotāju, piemēram, lai pārbaudītu reģistrētā lietotāja lietošanas gadījumu.

Pēc katra pieprasījuma un atbildes cikla mums parasti ir jāpārbauda, ​​vai atgrieztajā lapā ir kļūda, un mums ir jāpārbauda mūsu apgalvojumi par to, kāda satura atbildei vajadzētu būt. Arī šeit mums jābūt uzmanīgiem; mums jāpārbauda tikai vienumi, kas lietojumprogrammā nav mainīgi un nav pārāk trausli. Piemēram, ja mēs apgalvojam konkrētus lapu nosaukumus, mūsu testi, visticamāk, netiks veikti, ja lietojumprogrammā var izvēlēties valodu un mēs vēlamies pārbaudīt citas valodas izvietošanu. Tāpat ir maz jēgas pārbaudīt vienumu lapā, pamatojoties uz tā pozīciju tabulas izkārtojumā; Galdu dizains bieži mainās, tāpēc mums jācenšas identificēt elementus, pamatojoties uz to ID. Gadījumā, ja dažiem svarīgiem lapas elementiem nav ID vai vārdu, mums vienkārši jālūdz izstrādātājiem tos pievienot, nevis mēģināt tos apiet.

JUnit apgalvojumi piedāvā sliktu pieeju, lai pārbaudītu, vai izskats un izkārtojums, izkārtojums un lapas dizains atbilst prasībām. Tas ir iespējams, ņemot vērā bezgalīgi daudz laika testa izstrādei, taču labs cilvēka testeris var efektīvāk novērtēt šīs lietas. Tāpēc koncentrējieties uz tīmekļa lietojumprogrammas funkcionalitātes pārbaudi, nevis pārbaudiet visu iespējamo lapā.

Šeit ir atjaunināts testa scenārijs, kas balstīts uz mūsu testa gadījumu arhitektūru. Klase paplašinās ConfigurableTestCase, un pieteikšanās dati tiek apstrādāti pamata klasē:

 / ** * Pārbauda, ​​vai, iesniedzot pieteikšanās veidlapu ar nosaukumu "kapteinis", tiek iegūta * lapa, kurā ir teksts "Sevišķi slepeni" ** / public void testGoodLogin () izmet izņēmumu {WebConversation conversation = new WebConversation (); WebResponse response = pieteikšanās (saruna, LoginMode.ADMIN_MODE); assertTrue ("Pieteikšanās nav pieņemta", response.getText (). indexOf ("Jūs to izdarījāt!")! = -1); assertEquals ("Lapas nosaukums", "Ļoti slepens", response.getTitle ()); } 

Padomi un triki

Lielāko daļu scenāriju var viegli apstrādāt, iestatot WebForm parametrus un pēc tam meklēt konkrētus elementus ar rezultātiem WebResponse lapas, taču vienmēr ir daži izaicinoši testa gadījumi.

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