I det siste har vi hørt og lest mer og mer om testdrevet utvikling. Dette domenet kommer imidlertid med en serie uttrykk og spesifikt sjargong som kan forveksles med nykommere. Denne artikkelen vil gå deg gjennom de vanligste definisjonene, testtyper og testdeler. Bruk saker vil bli gitt, og, så langt det er mulig, vil noen kode i PHP også bli presentert.
For noen år siden ble en ny programmerer ansatt til et utviklingslag. Som noen annen nykommer var han ganske forvirret på sin første dag. Da han lyttet til diskusjonene rundt seg på kontoret, ble det brukt mange test-spesifikke vilkår. Disse var uttrykk ukjente for vår fiktive nye programmerer.
Heldigvis for ham, dette var hans første dag på jobb, ble de to kollegaene senere tildelt for å forklare alt dette sjargonget til ham. De begynte med en liste over termer knyttet til det indre arbeidet til et testfall.
Programvare testing programvare er praktisk talt en automatisert test. Testautomatisering har eksistert siden før PCen; de første automatiserte testrammene dukket opp i tider med mainframes og konsoller. I dag er automatisert testing den åpenbare måten å gå på. Hvorfor? Fordi testing er en kjedelig og repeterende oppgave - noe ikke godt egnet for mennesker. Automatisert testing er betydelig raskere, og mer presis enn manuell testing. Og nei, det eliminerer ikke den menneskelige testeren eller et QA-team fra ordningen. Det gjør dem bare til å gjøre en mer tilpasset jobb, og la dem gjøre det bra.
Enhver test bør brytes i fire deler:
Vi utformer hver test for å ha fire forskjellige faser som utføres i rekkefølge: Monteringsoppsett, Trenings-SUT, Resultatbekreftelse og Festeutvikling. - xUnit Test Patterns: Refactoring Test Code, av Gerard Meszaros
En Fixture representerer all informasjonen som testen trenger for å bli utøvd. En fixtur kan være så enkelt som å skape en ren gjenstand, som $ testedObject = new RealObject ();, eller noe så komplisert som populasjonsdatabaser og starter brukergrensesnitt.
Alt et system under test (SUT) må ha på plass slik at vi kan utøve SUT for å verifisere sin oppførsel. - xUnit Test Patterns: Refactoring Test Code av Gerard Meszaros
Du har sikkert observert denne gjentatte sikt. Programmører vil vanligvis referere til det som SUT. Den representerer alle tingene som kreves for å bli testet. Avhengig av type test (se nedenfor for testtyper) kan SUT være mange ting fra en metode eller en klasse til hele systemet.
Uansett hva vi tester. SUT er alltid definert fra testets perspektiv. - xUnit Test Patterns: Refactoring Test Code, av Gerard Meszaros
Starter sin andre dag på jobben, skrev vår programmerer sin første test. Det var vanskeligere enn han forventet. For å skrive det, trengte han en testing rammeverk, og han måtte lage en testforsøk og kjør all den testmetoder. Det var også en håndfull merkelige avhengigheter som han trengte å finne ut. Det virket som å lære om DOC var på skjema.
Et testramme er et program som er spesielt utviklet for testing av kode på et bestemt språk. Konseptet med a testramme ble pioneret av Kent Beck tidlig på 90-tallet. Hans arbeid senere førte til et rammeverk for SmallTalk, kalt SmalltalkUnit, og deretter omdøpt til Sunit.
Smalltalk har lidd fordi det manglet en testkultur. Denne kolonnen beskriver en enkel teststrategi og et rammeverk for å støtte det. Teststrategien og rammen er ikke ment å være komplette løsninger, men snarere et utgangspunkt der industrielle styrkeverktøy og prosedyrer kan bygges. - Enkel Smalltalk Testing: Med mønstre, av Kent Beck
Det var den første xUnit rammeverk, og det definerte det grunnleggende konseptet med testing og vilkårene som er angitt ovenfor. I dag tilbyr nesten alle programmeringsspråk sin versjon av dette rammeverket: PHPUnit for PHP, JUnit for Java, ShUnit for UNIX Shell Scripts og så videre. Du vil bli overrasket over å finne ut hvor mange ting som kan testes i dag, og hvor mange tester som kan automatiseres.
Opprinnelig ble et "test case" definert som den minste testenheten av Kent Beck.
Når du snakker med en tester, er den minste testenheten de snakker om et testfall. TestCase er et brukers objekt, som representerer en enkelt test sak. - Enkel Smalltalk Testing: Med mønstre av Kent Beck
Disse dager bruker vi testmetode å definere denne minste delen og et testfall refererer i hovedsak til et sett med relaterte testmetoder. For eksempel er en typisk situasjon når vi er enhetstester vår kode, og et testfall refererer til totaliteten av testmetodene som tester en bestemt klasse, eller hva som helst som er den minste enheten i vårt programmeringsspråk. En test sak, mange ganger, er bare referert til som: "en prøve."
En testmetode er den minste delen av en testarkitektur. En testmetode er enheten som består av de ovenfor definerte delene: oppsett / øvelse / verifisering / teardown. Det er den viktigste delen av enhver test; den som gjør jobben.
En testmetode er en endelig prosedyre som gir et testresultat. - Form og stilhåndbok, ASTM, 2012
Dette var lett en av de mest forvirrende nye vilkårene for vår nye programmerer. Den representerer alle andre klasser og systemkomponenter som vår SUT trenger for å kunne kjøre. Men også DOC må gi spesifikke metoder som gjør at vi kan observere og teste den. Begrepene til gjøre narr av og testdobler er sterkt knyttet til DOC.
En individuell klasse eller en storkornet komponent som systemet under test (SUT) avhenger av. Avhengigheten er vanligvis en av delegasjonene via metodeanrop. - xUnit Test Patterns: Refactoring Test Code, av Gerard Meszaros
Snart etter at han skrev sine første tester, innså den nye mannen at han prøvde forskjellige logiske deler av applikasjonen. Noen ganger er det best å teste en liten del i isolasjon; andre ganger er det nødvendig å teste en gruppe objekter sammen og måten de snakker med hverandre på; og andre ganger må du teste hele systemet. Ting så mer komplisert enn tidligere antatt; så vår programmerer fortsatte og leste en bok, og en annen, og en annen, og til slutt forstod han.
Testpyramiden ble først definert i boken, Succeeding med Agile Software Development Bruke Scrum, av Mike Cohn, og så snart vedtatt av programvaresamfunnet.
Pyramiden representerer de tre viktigste testlagene: UI, Service og Unit.
De UI lag representerer det øverste testnivået: når systemet utøves gjennom brukergrensesnittet, og hele applikasjonen blir testet som en. Dette laget skal representere den minste mengden i vår mangfold av tester.
De Service lag inneholder flere forskjellige testtyper. Det er hovedsakelig opptatt av den interne kommunikasjonen av moduler og ved riktig bruk av det eksterne API-en (applikasjonsprogrammeringsgrensesnitt) for et program. Det bør være flere slike tester i våre suiter, men de bør ikke være en basis for testingen. Disse testene trener vanligvis flere deler av søknaden, og dermed er de ganske sakte. De bør kjøres så ofte som mulig, men ikke på alle lagre av koden. Sannsynligvis ved hver bygning av systemet eller når en forpliktelse skjer med versionssystemet.
De Enhetslag refererer til tester som utøver de minste mulige enhetene i koden vår i fullstendig isolasjon. Disse testene skal utgjøre det store flertallet av testene. De bør være veldig raske (1-4 millisekunder / test) og skal kjøre så ofte som mulig. Testdrevet utvikling (TDD) er et godt eksempel på hvordan man maksimerer bruken av enhetstester.
Basert på eksemplet ovenfor, utviklet fellesskapet flere detaljerte versjoner av testpyramiden. Den som jeg anser som den beste, kan ses på bildet nedenfor.
De tre hovedlagene kan tydelig skiller seg ut, men midtlaget er mer detaljert. Etter hvert som tiden har gått, oppdaget og oppdaget programvaresamfunnet flere nye testmetoder. Noen av dem var med på pyramiden.
Vennligst merk: Automatiserte testteknikker og -rammer endrer seg fortsatt svært raskt. Dette er grunnen til at, som du kan se nedenfor, er noen uttrykk ennå ikke klare, og det finnes flere termer for de samme definisjonene avhengig av fellesskapet som fremmet dem.
En enhetstest representerer testingen av den minste enhetens programmeringsspråk tillater. I objektorientert programmering er disse klasser / objekter. På andre språk kan de være små moduler eller til og med funksjoner / prosedyrer.
EN test i disse definisjonene refererer til det samme som et testfall representerer.
En test som verifiserer atferden til en liten del av det totale systemet. Hva som blir en test i en enhetstest er at systemet under test (SUT) er en svært liten delmengde av det overordnede systemet og kan være uigenkjenelig til noen som ikke er involvert i å bygge programvaren. - xUnit Test Patterns: Refactoring Test Code av Gerard Meszaros
Enhetstester representerer det store flertallet av testene som en programmerer skriver. Ja, det er sant: Enhetstester er mesteparten av tiden skrevet av programmerere. Enhetstest hjelper programmererne til å utvikle applikasjonen, forhindre vanlige feil, skrivefeil og regressjoner. De er tester laget av programmerere for programmerere.
Det er derfor enhetstester er mer tekniske og mer kryptiske i naturen. De er her for å hjelpe programmerere skrive bedre kode; når noe feiler på et testnivå, er det vanligvis et problem for en programmerer å fikse.
Som navnet antyder, komponent tester er skrevet for litt større biter av søknaden. En komponenttest utfører vanligvis en hel modul eller en gruppe logisk gjensidige enheter.
Komponenten er en følge av en eller flere designbeslutninger, selv om dens oppførsel også kan spores tilbake til et aspekt av kravene. - xUnit Test Patterns: Refactoring Test Code av Gerard Meszaros
Sikkert, en komponenttest utøver mer kode enn en enhetstest. Det kan også teste hvordan noen enheter jobber sammen og snakker med hverandre.
En komponent kan også spores tilbake til et krav eller en del av et krav. Dette betyr at en komponenttest ikke bare er for programmerere. Teamledere, scrum masters, arkitekter og andre teknisk involvert folk er sikkert interessert av modulene, av deres organisasjon og en gang til og med av deres indre arbeid. Disse menneskene er ikke nødvendige kjent med et bestemt programmeringsspråk. Testen må konsentrere seg mer om atferden og definere forventningene på en mer forståelig måte.
For eksempel kan en enhetstest ha en feilmelding som sier at:
TestFileAccessCanWriteToAFile: Feilet hevder at filen '/ tmp / testfile' er til stede på systemet.
En slik melding vil ikke være nyttig for en arkitekt eller en leder eller en lagleder. En komponenttest kan mislykkes med en mer beskrivende feil:
Kontoadministrasjonstest: Mislyktes da vi prøvde å spesifisere 0 (null) som summen av penger en bruker har på sin konto.
En slik test utøver en høyere funksjonalitet. Basert på feilmeldingen ovenfor, kan det være flere lag med kommunikasjon og klasser / objekter som er involvert i operasjonen av å angi et beløp som summen på enkelte konto.
Denne typen test tar flere moduler, og kontrollerer hvordan de integreres med hverandre. Det verifiserer om de interne modul-APIene er kompatible og fungerer som forventet.
Begrepet tillater imidlertid et bredt spekter av mulige anvendelser. Noen programvaresamfunn har sterkt tilknytning til integrasjonstester ved å teste hvordan applikasjonen fungerer innenfor det mediumet den må kjøre. Med andre ord, hvordan det integreres i det høyere systemet.
Andre definerer integreringstest på forskjellige nivåer: Alt som definerer kommunikasjonen mellom to elementer, kan ses som en integrering. Disse elementene kan være enheter, som klasser, moduler eller enda høyere funksjonelle deler av programvaren.
Det er ingen enstemmig akseptert definisjon for begrepet integrasjonstest.
GUI for en applikasjon snakker med programvaren av programvarens API. Testing på dette nivået utøver mye kode, og kan ha en relativt betydelig mengde tid å løpe.
API er måten som annen programvare kan påkalle noen funksjonalitet på. - xUnit Test Patterns: Refactoring Test Code av Gerard Meszaros
I objektorientert programmering defineres slike APIer av klassens offentlige metoder. Men hvis vi tar en titt på et arkitektonisk designskjema på høyt nivå, kan betydningen av API-en begrenses til de offentlige metodene i klassene som gir funksjonalitet gjennom grensen til forretningslogikken. Disse grenseklassene representerer API og vi bør teste at når vi ringer og bruker dem, oppfører systemet seg som forventet.
Vanligvis blir disse testene gjennomført regelmessig og tar lang tid å fullføre.
Det bør bare være noen få sjeldne tilfeller når du ønsker å prøve å presentere en søknad. Det er egentlig ingen logikk i GUI-laget, bare presentasjon.
Tester om en knapp er grønn eller rød, eller hvis den har 30px
i bredde er ubrukelig, og er for mye av en overhead. Så ikke hopp inn i å teste dine synspunkter. Hvis noe går veldig galt med GUI, vil det bli observert i den eksplorative manuelle testfasen.
Testing av visninger skal bare gjøre to ting: Test betinget presentasjon, og test at den forventede APIen kalles.
Hopping til å teste dine synspunkter kan være fristende. Ikke! Test bare hva du tror kan mislykkes. Test bare for verdier eller funksjonsanrop. Kontroller aldri for GUI-elementer eller deres egenskaper. Bruk REGEX når det er mulig for å matche strenger og sjekk søkeord som ikke er sannsynlige å endre.
For eksempel er følgende pseudokode et dårlig eksempel for å teste tilstedeværelsen av en streng på skjermen.
funksjon testItCanTellTheNameOfTheUser () // noen renderingskode logikk her $ renderedName = $ this-> renderName (); $ this-> assertEquals ('Bruker har navnet'. $ renderedName ['first']. ". $ renderedName ['last']. '.');
Ikke bare er denne testen vanskelig å lese, men det tester for en eksakt setning - noe som helst "Brukeren har navnet John Doe.", inkludert tegnsetting! Hvorfor er dette dårlig? Fordi noen enkelt kan endre formen på denne setningen uten å endre dens betydning.
Hva om vår klient krever Etternavn Fornavn skjema som skal presenteres? Det ville gjøre vår test mislykkes. Vi må spørre oss selv: bør testen mislykkes? Har vi endret programvarelogikk? Jeg sier nei, det burde ikke mislykkes. Navnet vil fortsatt være tilstede på skjermen; Ordren til de to delene ville ganske enkelt være annerledes. Dette er en mer hensiktsmessig test.
funksjon testItCanTellTheNameOfTheUser () // noen renderingskode logikk her $ renderedName = $ this-> renderName (); $ this-> assertRegExp ($ renderedName ['first'], $ renderedName); $ this-> assertRegExp ($ renderedName ['last'], $ renderedName);
Dette sikrer nå at navnet er til stede, men det bryr seg ikke om leksikalsk konstruksjon. Noen kunne endre det første frasen til noe, som Don, John er navnet på den nåværende brukeren. Betydningen vil forbli den samme og testen vil fortsatt passere riktig!
Etter en måned eller så arbeidet på jobben, innser vår fiktive nyprogrammerer at selv om pyramiden er ganske kul, er den ikke fullført. Noen ganger er det et par eller så annerledes test som skal utføres - og de er ganske vanskelig å plassere på pyramiden.
Dette er en av de mest kontroversielle testene. Avhengig av hva slags bøker du leser, kan aksepttester bli referert til som Funksjonsprøver
eller
eller
eller
Hvert navn kommer fra et annet samfunn eller en forfatter. Jeg foretrekker personlig Godkjenningstester eller End-to-End-test.
En godkjenningstest verifiserer oppførselen til et stykke av den synlige funksjonaliteten til det overordnede systemet. - xUnit Test Patterns: Refactoring Test Code av Gerard Meszaros
En slik test vil gjøre noe på GUI. Endringen vil skje i hele systemet. Data blir lagret i databasen eller filsystemet. Nettverkskommunikasjon vil bli gjort. Endelig blir GUI kontrollert for svaret fra systemet. Slike tester forsøker å etterligne en bruker helt.
Godkjenningstester er nært knyttet til interessentene i søknaden vår. De er vanligvis definert på språket i virksomheten, og når noe går galt, betraktes en hel funksjonalitet som defunct. Disse testene brukes også til å definere applikasjonens høyt nivå funksjonalitet.
Vanligvis er de skrevet av QA og ledelse og implementert av programmører. Opprinnelig ble de oppfunnet som en bro mellom ledelse og produksjon. For enkelte situasjoner lyktes de. Språket i testene er fleksibelt nok til å bli skrevet og forstått av personer som ikke er direkte involvert i programvareskriving.
Det finnes spesielle rammer for slike tester, som Fitness, Selen, Watir, Agurk og andre.
Dette er et mer spesielt tilfelle, og brukes ikke for ofte. Du kan bruke dem noen ganger i objektorienterte språk når grensesnitt og arv må testes. Testen sikrer i utgangspunktet at en klasse virkelig implementerer alle grensesnittene den må.
Kontraktstest forklarer hvordan en klasse skal utvide en superklasse eller implementere et grensesnitt. - J. B. Rainsberger
I noen applikasjoner er begrepet kontrakt brukes til en annen type test. Denne andre definisjonen av kontraktstesten sjekker om kontrakten mellom vår søknad og en tredjepartskomponent vi er avhengige av, blir respektert. Disse testene utøver nåværende kode og tredjepartskode, slik at resultatene er som forventet.
Etter en velfortjent ferie er vår ikke-så-junior programmerer tilbake på jobben. Det var hans første permisjon, og han føler seg full med ny kraft til å skrive tester og kode. Etter seks måneder føles han ganske bra på jobben; han har pent integrert i laget, og han skriver veldig god kode. Men fra tid til annen har han en frustrerende følelse. Kjører fem forskjellige typer testpakker i strengt definert rekkefølge hver kveld er kjedelig og feilproblemer.
Deretter er det en annen merkelig diskusjon mellom teamleder og ledelse. De snakker om C.I.. og C.D.. Hva kan de bety? Det var for kryptisk for vår nye programmerer å forstå. Et par uker senere var det et brede budskap: "Vennligst ikke kjør dine kveldstester mer. Vi har C.I.!. For å lære mer, gikk han til gruppeleder, og spurte: "Hva er CI og CD?".
Lag som er sterkt avhengige av automatisert testing, trenger en måte å kjøre alle disse tester på en organisert og effektiv måte. Et kontinuerlig integrasjonssystem hjelper med dette.
Kontinuerlig integrasjon er en programvareutviklingspraksis hvor medlemmer av et team integrerer sitt arbeid ofte, vanligvis integrerer hver person minst daglig, noe som fører til flere integrasjoner per dag. Hver integrasjon er verifisert av en automatisert bygge (inkludert test) for å oppdage integrasjonsfeil så raskt som mulig. - Martin Fowler
Basert på denne definisjonen, vil den kontinuerlige integrasjonsprosessen gjøre jobben med å kjøre tester uten menneskelig inngrep. I definisjonen er hyppig integrasjon eksemplifisert som daglig, men jeg kan fortelle deg at det er veldig kult å jobbe på en programvarebase som automatisk blir testet på hver forpliktelse. Å forpligte betyr ofte at enhver endring som er fullført må være forpliktet, slik at du kan ha tiotals forpliktelser på en enkelt dag. Hver forpliktelse vil utløse en fullstendig testing av systemet, og du får en fin e-post, grønn eller rød, avhengig av resultatet, om noen få minutter. Hvis posten er grønn, er produktet teoretisk umiddelbart overførbar.
Dette er ikke så relatert til testing, men til CI. Mens CI lar deg få et leverbart system, utgivelser er fortsatt gjort periodisk og manuelt.
Kontinuerlig levering automatiserer alle trinnene fra kode til klient.
Når alt kommer til alt på CI-nivå, tar kontinuerlig levering det et skritt videre og bygger programvareinstallasjonssettene, publiserer dem etter behov, og det kan til og med utløse fjernoppdateringsprosedyrer på klienter. Målet med et slikt system er å levere produktet så raskt som mulig til sluttbrukeren. Det er svært avhengig av automatiserte tester, og hvis alle passerer, leveres produktet. Periode.
Selv om det i noen situasjoner kan høres veldig attraktivt, er det i de fleste applikasjoner fortsatt for farlig. Vanligvis må ethvert anstendig kritisk system gå under en utprøvende manuell testingssesjon før levering.
Det er deler av en testprosedyre som bare er for vanskelig - om ikke umulig - å automatisere. Det er derfor en Utprøvende manuell testing økt er vanligvis gjort før hver programvareutgivelse. Disse testene kan gjøres av spesialiserte testere eller av programmene, avhengig av strukturen til teamet og selskapet.
Manuell testing innebærer fantasi. Mennesker pokker rundt systemet, slik at det fungerer og ser ut som ønsket.
Noen lag anser manuell testing a << Break it if you can! >> konsept.
Du kan ikke unngå testing av sjargong. Forhåpentligvis har denne artikkelen gitt litt lys på forskjellene mellom de ulike testformene. Noen spørsmål? Spør nedenfor!