Testing blir ofte forsømt i programmering, og webutvikling er ikke annerledes. Mange utviklere har ennå ikke innsett at automatiserte tester kan gjøre deg mer produktive, mindre stressede og mer selvsikker om kodingen av den neste funksjonen. I denne artikkelen vil vi fokusere på bruk av Selen for å automatisere nettlesertesting.
Som webutviklere trenger vi tester av noe slag, fordi vi absolutt ikke vil ha feilrapporter fra brukerne av våre applikasjoner som vårt testmiddel. Vi vil at tester skal være automatisert fordi manuell testing, men noen ganger en nødvendig ondskap, er langsom, feilaktig og kjedelig. Gjentatt manuell testing av et webprogram i flere nettlesere kan være ærlig, ødelegge sjelen! Et verktøy som Selen kan få deg avhengig av automatisert testing.
Kanskje du kan forholde deg til denne opplevelsen: Du åpner opp prosjektet ditt med det formål å kode en ny funksjon eller fikse en feil, og du lurer på, "Kan endringene jeg skal gjøre har utilsiktede bivirkninger? Vil jeg ødelegge koden min ?"
Denne frykten for å gjøre endringer blir bare verre etter hvert som prosjektet utvikler seg, og det ødelegger ofte morsom koding.
Men hvis du har et godt sett med automatiserte tester og kjører dem ofte, står du en god sjanse til å vite veldig raskt hvis du har brutt koden din. Dette gir deg en følelse av selvtillit i stedet for en av frykt, noe som gjør at du bare kan fortsette med det du trenger å gjøre, enten det er å implementere nye funksjoner, feilretting eller refactoring. Det er veldig forfriskende.
Dette er lettere å forstå når du har vært i smerte ved programmering uten gode tester. Det er fristende å tenke, "Jeg vil bare fortsette å kodes neste del av søknaden min." Dette er ofte mer så tilfelle når du jobber med noe relativt enkelt. Men som enhver utvikler kan fortelle deg, kan ting raskt bli mer komplisert. Plutselig er det skummelt å endre koden, og det er da du virkelig setter pris på et omfattende sett med tester for å sikkerhetskopiere deg.
Men å redusere frykt er bare en fordel. Velskrevne tester fungerer for å dokumentere systemet under utvikling, og dette fremmer bedre forståelse blant utviklere og kunder. Ved å se på en test bør du kunne fortelle nøyaktig hvordan et bestemt aspekt av systemet skal oppføre seg. Dette er et konsept understreket av Behavior-Driven Development (diskutert senere).
En viktig ide er at vurderingen av hvordan du skal teste din søknad, er like viktig som hvordan du går om å bygge den. Det er verdt å gjenopprette: å tenke på hvordan du tester systemet er like viktig som hvordan du faktisk skriver programkoden.
Det er et stort skift i tenkning, men når du er i tankene om å se automatiserte tester som en grunnleggende del av programmeringen, og har høstet fordelene, vil du aldri se tilbake. Jeg ble hekta på testing mens jeg ble introdusert til TDD, men etter min mening å være testinfisert, kommer ikke nødvendigvis gjennom TDD eller enhetstesting. Du må bare ha opplevd den enorme verdien av automatiserte tester og føler seg rar på programmering hvis ikke i rutinen for å skrive dem.
Når du er i tankegangen og har høste fordelene, vil du aldri se tilbake
Et svar på disse argumentene kan være: "Alt dette høres ut som noe som vil ta mye tid, det kan kodes for neste funksjon." Tross alt har vi normalt begrenset tid til å bruke på et prosjekt. Og det er sant at det tar tid og krefter å sette opp og komponere automatiserte tester. Men hvor mye tid det sparer i det lange løp, og den forbedrede kvaliteten det pleier å bringe til kode, gjør en streng rutine av automatisert testing vel verdt investeringen.
Vi bruker et gratis verktøy kalt selen. Selen automatiserer nettlesere; det simulerer en bruker som samhandler med webapplikasjonen din, utfører museklikk, tekstoppføring og til og med dra og slipp (blant annet). Det kan også brukes til å sjekke hva som vises på skjermen.
Å vite hvordan du skriver gode tester er en ferdighet du utvikler over tid, men i denne opplæringen diskuterer vi å komme i gang med nettlesertesting ved hjelp av Selen.
Hvis du er ny til testing, er det nyttig å få en generell ide om hvilke typer tester som vanligvis er i bruk. Ulike typer tester brukes til forskjellige formål. Husk at terminologien rundt testing er noe inkonsekvent - forskjellige mennesker bruker det samme begrepet for å bety litt forskjellige ting.
Enhetstester brukes til å kontrollere riktigheten av individuelle klasser, metoder og funksjoner. Koden som utøves bør holdes isolert fra andre deler av systemet, og dette oppnås ved hjelp av erstatninger for ting som koden under testen avhenger av. På den måten er det enkelt å se hvor problemet oppstår når en test mislykkes. Enhetstester pleier å være de raskeste tester som skal løpe, og ingen kode involvert bør gjøre ting som å slå en database eller få tilgang til nettverket.
Enhetstester bør ikke være opptatt av å verifisere at de enkelte komponentene i systemet fungerer sammen riktig. Det er der integreringstester kommer inn.
Lavt nivå integreringstester kan håndtere samspillet mellom to eller tre klasser, mens andre kan kontrollere at koden fungerer riktig med eksterne ressurser, for eksempel en database eller en HTTP-server.
Systemtester, som er hvor denne opplæringen passer inn, kjøres mot hele det integrerte systemet for å kontrollere om kravene til hele systemet er oppfylt. Systemtester kan omhandle ting som ytelse og skalerbarhet, men typen tester vi vil fokusere på, er om systemet oppfører seg som kunden forventer og implementerer funksjonene de har spesifisert. I Agile utviklingssirkler faller disse tester inn i kategorien aksept tester.
Eksempelkoden som presenteres nedenfor gjør denne typen testing. Disse tester forteller oss om vår søknad oppfører seg slik vi ønsker det, fra brukerens synspunkt eller ikke. Vi kan bruke Selen til å automatisere tester av denne typen fordi det kan simulere en bruker som interagerer med systemet (og det kan gjøre det ved å bruke ekte nettlesere, samt hodeløse systemer som HtmlUnit).
Fordi vi bare vil være interessert i hva systemet gjør, og ikke hvordan det gjør det, vi vil være engasjert i svart boks testing. Det er også verdt å merke seg at, i motsetning til de fleste andre typer test, skal aksepttester skrives i samarbeid med kunder.
Hvilke typer tester skal du bruke?
Vi kan bruke Selen til å automatisere tester fordi det kan simulere en bruker som interagerer med systemet
Kake er en slags mat, men de fleste (ikke meg) vil råde deg mot å spise det utelukkende; det utfyller i stedet for å erstatte annen mat. Det er viktig å merke seg at de ulike prøvene utfyller hverandre i stedet for å være i konkurranse. Som nevnt ovenfor tjener de forskjellige formål. Hver av dem har fordeler og ulemper, og de er absolutt ikke hverandre eksklusive.
Systemnivå, GUI-drevne tester som eksemplene nedenfor har en tendens til å være relativt sakte å kjøre og gir derfor ikke rask tilbakemelding. Tester av denne typen har også en tendens til å være sprø, og fordi de berører så mye av applikasjonskoden, kan det være vanskelig å spore ned kilden til en feil uten et omfattende omfattende sett med enhet og integreringstester. Faktisk er det en god ide å ha mange flere enhedsnivå tester enn den type GUI-baserte, systemnivå, tester som Selen brukes til. Det er ikke å si at selenprøver ikke er nyttige! Poenget er at ingen type testing er nok alene.
Vi bruker Selen 2. Nærmere bestemt bruker vi WebDriver, en komponent av Selen 2. WebDriver erstatter Selen 1's Remote Control (RC) API, og det gir en rekke fordeler over RC. For eksempel er det bedre å teste AJAX, og det har en renere, mer objektorientert API. Det fungerer også på en helt annen måte til RC. I stedet for å bruke JavaScript for å samhandle med en side, bruker WebDriver nettleserautomatiseringsgrensesnittet som er spesielt for hver nettleser. Resultatet er at det bedre simulerer en faktisk bruker som samhandler med nettstedet under test.
En annen komponent av Selen er IDE, et rekord-og-avspillingsverktøy og Firefox-plugin. Det krever ikke kunnskap om programmering og er nyttig for utprøvende testing.
Dens tester pleier å være mer sprø enn RC og WebDriver skript og en åpenbar stor ulempe er at den bare kan brukes i Firefox. IDE er ment som et prototypingsverktøy og anbefales ikke for seriøs testing.
WebDriver støtter et bredt utvalg av nettlesere, inkludert Chrome, IE, IOS og Android. Senere ser vi på bruk av sky testingstjenester for at tester kan kjøres mot nettleser-operativsystemkombinasjoner som du ellers ikke har tilgang til.
Her vil WebDriver bli brukt med Python, men en rekke språkbinding er tilgjengelig, inkludert de for Java, C # og PHP. Hvis du ikke er kjent med Python, vær ikke redd, så bør du fortsatt følge med eksemplene, da det ligner pseudo-kode ganske mye..
Python ... leser ganske mye som pseudokode
En rekke andre grensesnitt er tilgjengelige, men de to sentrale delene av WebDriver API vi trenger er WebDriver
og WebElement
. Hvert eksempel nedenfor vil fungere med en WebDriver
objekt, som tilsvarer nettleseren, og en eller flere objekter av typen WebElement
, som representerer elementer på en side.
Metodene for å finne elementer på en side (diskutert senere) er felles mellom disse to grensesnittene. På den annen side, metoder som TAG_NAME
er bare tilgjengelig på WebElement
. På samme måte er det fornuftig for metoder som get_cookies
og forfriske
å være tilgjengelig på WebDriver
men ikke på WebElement
, og dette er faktisk tilfelle.
Det er interessant å merke seg at det er et forsøk på å gjøre WebDriver til en W3C-standard.
For tiden støtter Selen 2 Python 2.6 og Python 2.7, så installer en av disse hvis du trenger det. For å finne ut hvilken versjon du har, på kommandolinjetypen python -V
. Linux og Mac-brukere har vanligvis Python allerede, men bør passe på når de oppgraderer sin versjon av Python, ettersom operativsystemet kan avhenge av hvilken versjon operativsystemet kom med.
Når du har Python 2.6 eller 2.7, er den beste måten å installere pakker for den med pip. Når du har pip, installerer du Selenium 2-typen: pip installere -U selen
. (-U
vil oppgradere en tidligere versjon du kanskje har. Linux og Mac-brukere kan trenge sudo
).
For å få pip på Windows, se dette Stack Overflow-spørsmålet.
Vi bruker også Firefox, da det er nettleseren som jobber med WebDriver ut av boksen.
Vi trenger et webprogram for å teste, og vi bruker et enkelt nummer gjetting spill. Det er et bevisst enkelt program. En webapplikasjon testes ofte på en utviklerens maskin ved hjelp av en web-server med lokalt kjørt utvikling, da dette er praktisk for testing før distribusjon. Men i dette tilfellet løper vi tester mot en distribuert web-app: http://whats-my-number.appspot.com. Dette vil være programmet under test (AUT). (Hvis dette nettstedet er nede, kan du prøve http://whats-my-number-backup.appspot.com/).
Svaret (beklager å ødelegge moroa) er 42.
Uansett brukerens innspill, bør et hint vises. Programmet forventer hele tall fra 0 til 100 (inkluderende), og hvis brukeren oppgir en verdi som ikke passer til denne regelen, bør hinten gi råd om dette kravet. Når brukeren prøver et helt tall å gjette fra 0 til 100 som er feil, bør det viste hintet være "for lavt" eller "for høyt". Når 42 er oppgitt, bør "Gratulerer" være hintet som vises.
Noe vi berørte tidligere er ideen om at en flott måte å være eksplisitt på hvordan et system skal oppføre seg, er å skrive tester, og senere vil eksempler innebære et ganske omfattende sett av tester som vil bidra til å formidle systemets opptatte oppførsel. Vi vil ha en form for kjørbar dokumentasjon.
Vi vil ha en form for kjørbar dokumentasjon
En av de store tingene med et språk som Python er at du kan bruke en interaktiv tolk. For å kjøre den interaktive Python-tolken, skriv bare python
på kommandolinjen, og du bør se spørringen (>>>
). Alternativt, for å kjøre en skriptfil, bruk python script_name.py
Det er ikke måten testkoden vanligvis kjøres selvfølgelig, men når du bare har begynt med nettleserautomatisering, kan det være nyttig å bruke den interaktive tolken og skrive inn en linje med Python av gangen. På denne måten er det lettere å få en følelse av hvordan WebDriver styrer nettleseren og simulerer en ekte bruker. Selv om du i stedet kan kjøre en skriptfil og ligge tilbake og se mens Selen gjør ting, jobber det mye raskere enn med en menneskelig bruker, så kjører kommandoer én linje om gangen gjør det lettere å få en god forståelse for hva Kommandoene du utsteder, gjør faktisk. Det er en fin måte å lære og eksperimentere på.
Skriv følgende kodelinjer ved tolkens spørsmål, trykk Enter etter hver. Det første trinnet er å utføre en import:
fra selenimport webdriver
Deretter åpner vi et nettleservindu og besøker AUT:
browser = webdriver.Firefox () browser.get ('http://whats-my-number.appspot.com/')
Nå skal vi gjøre noe som gjør dette til en test. Python er innebygd hevde
setning kan brukes til å kontrollere at noe er sant, og i dette tilfellet bruker vi det for å bekrefte at sidetittelen er "Hva er mitt nummer". Dette kan bli referert til som en innholdstest:
antyde 'Hva er mitt nummer?' == browser.title
Siden sidetittelen er riktig, gir Python oss bare en annen ledetekst. Tittelen er feil, ville ha betydd hevde
kaster en AssertionError
. en AssertionError
mens du kjører en skriptfil, får programmet til å krasje (hvilket er nyttig).
Den neste delen av testen er hva Selen-dokumentasjonen kaller en funksjonstest. Vi ønsker å bekrefte at når 1 legges inn som et gjetning, svarer programmet med innhold som inneholder et hint om at gjetningen er for lav. Senere eksempler vil håndtere flere brukeroppføringer.
For å gjøre dette må vi fylle ut skjemaet. Hvis du ser på HTML av gjetningsspill siden, ser du at tekstfeltet har en Navn
Tilskrive med verdien av "gjetning". Dette kan brukes til å skaffe en WebElement
objekt for å representere inngangsfeltet:
guess_field = browser.find_element_by_name ('guess')
Vi kan nå skrive inn gjetningen. WebElement
har en send_keys
metode:
guess_field.send_keys ( '1')
Vi kunne finne innleveringsknappen og klikke på den, eller bruke den medfølgende sende inn
metode, men i stedet la oss trykke Retur-tasten:
fra selenium.webdriver.common.keys importere nøkler guess_field.send_keys (Keys.RETURN)
Skjemaet er sendt inn og siden oppdateres (AJAX er ikke i bruk), og siden gjetningen er for lav, "Din gjetning er for lav" skal vises et sted i dokumentets kropp. For å bekrefte dette først trenger vi en WebElement
objekt som representerer HTML kropp
:
body = browser.find_element_by_tag_name ('body')
De tekst
tilhører WebElement
vil i dette tilfellet avsløre teksten på siden. La oss gjøre bruk av det i en hevde
uttalelse:
antyde 'Ditt gjetning er for lavt' i body.text
Igjen, suksess, så Python gir oss bare en annen ledetekst. Siden dette er en feil gjetning, er "Gratulerer" ingen steder å se:
hevn "Gratulerer" ikke i body.text
Til slutt lukker vi forekomsten av Firefox vi har brukt:
browser.quit ()
Hvis du er kjent med programmering ved hjelp av JavaScript og DOM, vil du vite om behovet for å få referanser til DOM-elementer på en nettside, og som vi har sett må vi gjøre noe lignende her. De to situasjonene er ikke akkurat det samme, men fordi vi ikke får en referanse til et DOM-element, får vi en WebElement
objekt som tilsvarer et DOM-element.
Over brukte vi
find_element_by_name
, som er nyttig for formelementer, så vel somfind_element_by_tag_name
. Andre lokaliseringsmetoder inkludererfind_element_by_id
ogfind_element_by_css_selector
. Se Selen dokumentasjonen for den komplette listen.
Performance-wise, ved hjelp av en element-ID eller navneplasseringsleder (som vi gjorde ovenfor), er den beste måten å velge et element på. Selvfølgelig, når vi har en WebElement
objekt som tilsvarer det ønskede DOM-elementet, er det vanlig å ønske å interagere med det på en eller annen måte, som er hvor metoder som send_keys
og klikk
er nyttige.
Sprøyte tester er farlige fordi hvis tester noen ganger feiler når de faktisk skal passere, kommer du til å ignorere testresultatene, og hele prosessen med testing blir devaluert.
I den nedlastbare zip-filen som følger med denne opplæringen, ftests1.py
viser eksempelkoden ovenfor i form av en skriptfil. Men det er en utelatelse: det kan hende du merker at anropet til implicitly_wait
, inkludert i ftests1.py
, ble ikke oppført eller diskutert.
Hvis du kjører en test mot et system ti ganger, bør det gi deg samme resultat hver av de ti ganger. Men sprø og upålitelige tester av den typen vi gjør er ganske vanlig, og du kan godt komme over dette problemet mens du eksperimenterer med test av selen. Sprøyte tester er farlige fordi hvis tester noen ganger feiler når de faktisk skal passere, kommer du til å ignorere testresultatene, og hele prosessen med testing blir devaluert. implisittvennlig er et veldig nyttig verktøy for å bekjempe sprø tester, og fra dette punktet et anrop til implicitly_wait
vil bli brukt i alle eksempler koden.
Å være en testinfisert utvikler, vil du vite om xUnit-verktøyene. De er tilgjengelige for mange programmeringsspråk. unittest er et xUnit-verktøy som kommer som standard med Python. Det kan virke forvirrende, men selv om vi ikke skriver enhetstester, er unittest nyttig. For eksempel hjelper unittest med strukturering og kjøringstester, og testfeil resulterer i mer nyttige meldinger.
Versjonen av unittest i Python 2.7 har flere funksjoner i forhold til eldre versjoner (noen av dem vi bruker), så hvis du kjører Python 2.6, må du installere backporten: pip installere unittest2
Koden nedenfor er en unittest versjon av testkoden som ble presentert tidligere.
Som tidligere er tittelen på nettleservinduet sjekket, 1 er forsøkt som et gjetning, og programmets svar er sjekket:
prøv: importer unittest2 som unittest #for Python 2.6 unntatt ImportError: importer unittest fra selen import webdriver fra selenium.webdriver.common.keys import Nøkler klasse GuessTest (unittest.TestCase): def setUp (selv): self.browser = webdriver.Firefox () self.browser.implicitly_wait (3) def tearDown (selv): self.browser.quit () def test_should_see_page_title (selv): # Brian besøker gjetningsspillets hjemmeside self.browser.get ('http: // whats-my -number.appspot.com/ ') # Han ser at "Hva er mitt nummer?" er tittelen på siden self.assertEqual ('What's My Number?', self.browser.title) def test_should_get_correct_hint_from_guess_too_low (selv): # Brian besøker gjetningsspillets hjemmeside self.browser.get ('http: // whats-my-number.appspot.com/ ') # Han skriver gjetningen inn i skjemafeltet og treffer retur-tasten guess_field = self.browser.find_element_by_name (' guess ') guess_field.send_keys (' 1 ') guess_field.send_keys ( Keys.RETURN) # Siden er lastet opp og siden gjetningen er for lav, # 'Din gjetning er for lav' vises body = self.browser.find_element_by_tag_name ('body') self.assertIn ('Din gjetning er for lav' , body.text) # Siden dette er en feil gjetning, er "Gratulerer" ingensteds å se self.assertNotIn ('Gratulerer', body.text) hvis __name__ == '__main__': unittest.main ()
Hjernen er navnet på vår "robotbruker". Se også ftests2.py
i zip-filen som følger med denne opplæringen.
De individuelle testene er klassens metoder GuessTest
, som arver fra unittest.TestCase
. For mer av en ide om selv-
søkeord og andre objektorienterte aspekter av Python, se Nettutsessionen på Python. Testmetodenavn må begynne med bokstavene test
. Det er viktig å gjøre metodenavn beskrivende.
Selvfølgelig en hevde
er viktig for enhver test, men faktisk heller enn å bruke hevde
uttalelse som før har vi tilgang til unittest s assert metoder. I dette tilfellet assertEqual
, assertIn
og assertNotIn
er brukt.
De Setup
og rive ned
metoder utføres før og etter hver testmetode, og her bruker vi dem til å starte opp og slå av en WebDriver-nettleserversjon.
Den endelige blokken, hvis __name__ == '__main__': unittest.main ()
, lar dette unittest skriptet bli kjørt fra kommandolinjen. For å kjøre skriptet, gå til katalogen som inneholder ftests2.py
og skriv inn: python ftests2.py
. Å gjøre bør resultere i produksjon slik:
Ideelt sett må tester mislykkes "lydløst", men passere "stille", og som du kan se er det akkurat det som er uegnet: bare en periode skrives ut for hver bestått testmetode. Til slutt ser vi en velkommen "OK" (bør det ikke være "Bra gjort"?).
Som du kan se, brytes ikke "Gjenta ikke selv" -prinsippet, fordi URL-adressen til AUT er i koden to ganger. Grundig testing gjør det mulig å refactoring søknadskoden, men ikke glem å også refactor testkode.
Så langt har testene våre bare involvert en enkelt gjetning: 1, og tydelig dette er ikke veldig omfattende. Det neste skriptet vil gjøre noe med dette, se ftests3.py
i zip-filen.
De
importere
uttalelser, klassedeklarasjon,Setup
ogrive ned
metoder, oghvis __name__ == '__main__':
blokkere, er helt nøyaktig det samme som det siste eksemplet. Så la oss konsentrere oss om de tingene som er forskjellige.
Siden dette er noe vi gjør gjentatte ganger, er utfylling av skjemaet lagt inn i sin egen hjelpemetode, oppkalt _enter_guess_hit_return
:
def _enter_guess_hit_return (selv, gjetning): guess_field = self.browser.find_element_by_name ('guess') guess_field.send_keys (gjetning) guess_field.send_keys (Keys.RETURN)
En annen hjelpemetode, _unsuccessful_guess
, omhandler å besøke AUT, ringer _enter_guess_hit_return
, og kaller påstandsmetoder. Igjen, vår robot bruker kunne gjøre med et navn, denne gangen la vi referere til det som Bertie.
def _unsuccessful_guess (self, berties_guesses, expected_msg): self.browser.get ('http://whats-my-number.appspot.com/') for berties_guess i berties_guesses: self._enter_guess_hit_return (berties_guess) body = self.browser. find_element_by_tag_name ('body') self.assertIn (expected_msg, body.text) self.assertNotIn ('Gratulerer', body.text)
Det kan hende du merker det kallet _enter_guess_hit_return
og utføre påstandene skjer i en løkke. Dette er fordi vi slår over berties_guesses
, som er en liste. berties_guesses
vil bli sendt til denne metoden ved å ringe testmetoder, som også vil passere i en forventet melding, expected_msg
.
Nå for å gjøre bruk av våre hjelpere i testmetodene:
def test_should_get_correct_hint_from_guess_too_low (selv): berties_guesses = ['0', '01', '17', '23', '041'] expected_msg = 'Din gjetning er for lav' self._unsuccessful_guess (berties_guesses, expected_msg) def test_should_get_correct_hint_from_guess_too_high ): berties_guesses = ['43', '80', '100'] expected_msg = 'Din gjetning er for høy' self._unsuccessful_guess (berties_guesses, expected_msg) def test_should_get_correct_hint_from_invalid_input (selv): berties_guesses = ['a', '5a' , 'c7', '1.2', '9.9778', '-1', '-10', '101', 'hkfjdhkacoe'] expected_msg = 'Vennligst oppgi et helt tall fra 0 til 100' self._unsuccessful_guess (berties_guesses, expected_msg)
For kortfattet bruk er det ikke tillatt å sjekke sidetittelen. Selvfølgelig bør det være en metode for å verifisere at når det riktige gjettet er gitt, er "Gratulerer" faktisk vist, og du er invitert til å skrive denne metoden (det vil være morsomt, jeg lover!).
Det siste eksempelskriptet gir oss en god grad av selvtillit at AUT-funksjonen fungerer som den skal. Men anta at søknadens kode må endres nå. For eksempel ønsker kunden en ny funksjon, eller vi ønsker å refactor, eller kanskje enhet eller integrasjonstester har avdekket en feil som systemnivå tester ikke avslørte (og vi ønsker nå å fikse den feilen). Under prosessen med å endre koden, bør eksisterende tester kjøres ofte, slik at problemer oppstår før heller enn senere.
La oss simulere en endring i programkoden. En modifisert versjon av spillet er på http://whats-my-number-broken.appspot.com og hvis du kjører ftests3.py
mot denne versjonen ser du en testfeil:
test_should_get_correct_hint_from_guess_too_high
mislykkes. Testen viser at ved å modifisere programmets kode ble det innført regresjon. Vi løper tester jevnlig, og vi må bare vurdere endringene som ble gjort siden testene sist ble passert for å begrense problemet. På denne måten har skrivingstester belønnet oss med en følelse av tillit, i motsetning til en følelse av frykt.
Webapplikasjoner forventes generelt å fungere skikkelig på et bredt utvalg av nettlesere, så det er normalt best å teste med så mange nettlesere på så mange plattformer som du kan få hendene på. Når det oppdages et problem med et system, er det ikke uvanlig å høre en utvikler si: "Vel, det fungerer på min maskin". Dette betyr ofte: "Vi har ikke testet det riktig". I tilfelle av antall gjetningsspillet kan du lure på om det er nødvendig med kryss-nettlesertesting, men det er selvfølgelig et bevisst enkelt system.
Cloud-baserte tjenester som Sauce Labs kan hjelpe. Sauce Labs tilbyr et utvalg av nettleser-OS-kombinasjoner. En annen tjeneste er Testingbot, som tilbyr testing på mobile plattformer.
Som du har sett, kjører vi tester mot et offentlig tilgjengelig nettsted, men for nettsteder som fortsatt er på utviklings- og intranettsteder, tilbyr Sauce Labs Saus Connect og Testingbot tilbyr Tunnel.
Kodeprøvene så langt har vært hardkodede for å bruke Firefox. ftests3_remote.py
, Tilgjengelig i zip-filen, er en forbedret versjon av ftests3.py
som lett kan konfigureres til å kjøre ved hjelp av en gitt nettleser-OS-kombinasjon (innenfor grensene for hva som tilbys av hvilken som helst skyttestingstjeneste vi bruker). Plattformen, nettleseren og nettleserversjonen er spesifisert på kommandolinjen når skriptet kjøres.
Kodeprøvene så langt har vært hardkodede for å bruke Firefox
Du må registrere deg for en tjeneste som Sauce Labs eller TestingBot for å skaffe en API-nøkkel, og redigere Setup
metode (som vist i filen) for å inkludere denne nøkkelen. Begge tjenestene kan prøves uten kostnad.
ftests3_remote.py
Forventer at plattformen er det første kommandolinjeparametret, navnet på den nødvendige nettleseren, og nettleserversjonen forventes sist. Med henvisning til Sauce Labs tilgjengelige nettleser-OS-kombinasjoner kan vi for eksempel kjøre skriptet på følgende måte:
python ftests3_remote.py LINUX krom
I det spesielle tilfellet av Chrome bør ikke noe versjonsnummer angis. For å bruke Internet Explorer, fordi nettlesernavnet består av to ord, må anførselstegn brukes. For eksempel, la oss kjøre testene ved hjelp av vår gamle venn, IE6:
python ftests3_remote.py XP 'internet explorer' 6
Testresultatene sendes ut til terminalen, akkurat som om du kjørte testene på din egen maskin. Du kan imidlertid forvente at dette skriptet skal kjøre langsommere enn tidligere eksempler på testskript. Interessant, Sauce Labs lar deg se en video av hver test som kjører når den er fullført.
Et skallskript kan enkelt opprettes for å kjøre ftests3_remote.py
en rekke ganger, hver gang med en annen plattform-nettleser-versjon kombinasjon.
Tidligere så vi på behovet for implicitly_wait
. Det er interessant å merke seg at verdien gikk til implicitly_wait
som foreslått av Sauce Labs eget eksempelkode er 30 sekunder.
Behavior-Driven Development (BDD) utvider TDD og legger vekt på en klar forståelse av ønsket oppførsel av et system gjennom god kommunikasjon mellom utviklere og brukere. Et verktøy som oppfører seg kan støtte dette samarbeidet og bidra til å unngå feilfortolkning av utviklere. oppfører oss med et abstraksjonslag på toppen av Selen for å gjøre tester mer kundelesbare.
Et verktøy som oppfører seg kan støtte samarbeid og bidra til å unngå feilfortolkning
oppfører seg bruker Gherkinspråk, kjent for brukere av agurk i Ruby og Behat i PHP. Ordene Gitt, Når og Da brukes til å hjelpe kommunikasjonsprosessen og lage enkle tekstbeskrivelser av hva systemet skal gjøre. Vi kan tilbake disse beskrivelsene med Python, og resultatet er at tekstbeskrivelsene kan utføres som automatiserte tester.
En fullstendig forklaring på oppførsel er utenfor omfanget av denne opplæringen, og du oppfordres til å se på dokumentasjonen. For å kjøre eksempeltesten må du installere oppføre seg: pip installere oppføre seg
Zip-filen som følger med denne opplæringen, inneholder katalogen oppføre / funksjoner
, som inneholder valid_inputs.feature
, trinn / steps.py
, og environment.py
. Det er ikke plass her for å undersøke hver av dem i detalj.
valid_inputs.feature
inneholder noen enkle tekstbeskrivelser av hvordan gjetningsspillet skal fungere. Setningene som begynner "Gitt", "Når", "Da" og "Men" kart til trinn implementeringer, som er inkludert i trinn / steps.py
.
environment.py
kan definere kode for å kjøre før og etter bestemte hendelser, og i dette tilfellet brukes det til å starte og stoppe en nettlesersesjon.
For å kjøre testene byttes til oppfør deg
katalog og bare skrive oppfør deg
på kommandolinjen.
TestingBot-siden har en side om hvordan man bruker å oppføre seg med sin sky testingstjeneste.
Det er viktig å tenke på testing som en integrert del av kodingen. De ulike typer testing utfyller hverandre, og har et omfattende sett med tester gir utviklere selvtilliten til å fikse feil og utvikle nye funksjoner i kunnskap om at kvaliteten på koden kan holdes høy.
Webdriver tilbyr en API som kan brukes med flere språk, og et verktøy som oppfører seg kan være nyttig for å skrive tester i samarbeid med kunder. Vi har også sett hvordan det er mulig å teste et webprogram i en rekke nettleser-OS-kombinasjoner ved hjelp av en av de skyttestingstjenestene som tilbys.
Dette