Theory of Unit Testing, del 2

I den siste artikkelen begynte vi å snakke om teorien om enhetstesting i WordPress. Nærmere bestemt har vi gjennomgått vårt arbeid med enhetstestingstemaer og plugins, og deretter begynte å diskutere kodeenheter, hvordan dette påvirker testingen, og vi gjennomgikk enhetstesting i den større verden av programvareutvikling.

Vi skal fortsette å diskutere teorien om enhetstesting i WordPress, men skal gjøre det gjennom perspektivet på hvordan det kan hjelpe til med å identifisere problemer, kjøre arkitektur, dokumentere prosjektet og mer.


Finne problemer, spare tid

Tilbakekall fra tidligere i denne serien, at den tradisjonelle måten å gjøre enhetstesting på er dette:

  • Skriv en test, kjør den (vet at den vil mislykkes)
  • Skriv funksjonen for å få metoden til å passere.
  • Kjør testene. Hvis testen feiler, fortsett å jobbe med funksjonen; ellers, flytt til neste.

Ja, det første trinnet er litt dogmatisk. Hvorfor kaste bort minutter kjører noe du vet, kommer til å mislykkes, ikke sant? Likevel får du ideen. Men når du begynner å bruke denne spesielle teknikken til utvikling, kommer du til å finne ut at du vil utvikle en viss rytme for å skrive koden din og det er en del av hele målet.

Men det er bare halvparten av det - enhetstesting kan faktisk hjelpe deg med å oppdage problemer tidligere i utviklingen.

For å forstå dette er det sannsynligvis best å komme tilbake til ideen.

La oss si at du jobber med en funksjon for et WordPress-basert prosjekt der du skal tillate brukere å opprette en brukerkonto uten å logge inn på WordPress-dashbordet. Dette forutsetter at du har en oppsett for sidemal for å håndtere registrering, nødvendig validering på plass, og koden for generering av passord og e-post.

Du laster opp siden i nettleseren din, prøv å lage noen få brukere - noen med samme e-postadresse, noen med feil passord, noen med ulovlige tegn osv. Du får poenget - det finnes n-nummer måter å validere å passere og å mislykkes. Dette er grovt! Dette betyr at hver gang brukerregistreringsfunksjonen endres, må du utføre samme n-nummer registreringer for å sikre at ingenting er ødelagt.

Eller du kan skrive en serie med tester for å ta vare på det og kjøre dem alle hver gang koden endres.

Så, ja, skrive enhetstester kan ta mye tid foran, men se på hvor mye tid du lagret hver gang du endrer en kodeenhet. Det er vel verdt det, og dette kan bidra til å identifisere problemer tidlig - det vil si før det slippes i produksjon - det kunne ha blitt savnet fordi noen glemte å simulere en permutasjon av testen.


Selvdokumenter

Når det gjelder å skrive enhetstester, forbedrer du ikke bare kodenes kvalitet ved å sørge for at den faktisk fungerer, men du leverer iboende utvikler-orientert dokumentasjon.

Hvis du er enhetstesting av funksjonaliteten du bygger på produktet ditt, skal du gi dokumentasjon for hvordan funksjoner skal brukes, når de skal mislykkes, og når de skal passere.

Det er noen forutsetninger som følger med dette: Spesielt at du logisk navngir og grupperer dine funksjoner og tilhørende tester, og at du tester hver funksjon riktig..

Gjennom PHPUnit gjør WordPress Unit Tests det enkelt å utføre påstander som er enkle å lese. Du oppgir bare assertTrue, assertFalse, eller andre påstander som er tilgjengelige på funksjonene som komponerer prosjektet ditt.

Følgende med vårt eksempel ovenfor betyr at du kan skrive en funksjon for å sikre at brukerregistreringsfunksjonen mislykkes når du prøver å registrere deg med en tom e-postadresse:

 $ this-> assertFalse (registerNewUser ("));

Et enkelt eksempel, kanskje, men poenget gjenstår: Koden din blir selvdokumenterende, og det krever bare at du skriver klare enhetstester.


Arkitektur

Kanskje en av de mest undervurderte fordelene med enhetstesting er at den kan bidra til å drive arkitekturen til prosjektet ditt. Vanligvis kan tema- eller pluginutvikling starte på to måter:

  1. Oppgi funksjoner, skissere brukergrensesnittet, og skriv kode
  2. Tegn et diagram over hvordan filene skal fungere sammen, og skriv deretter kode

Dette er ikke iboende dårlig, men jeg tror de er svake (og jeg blir den første til å innrømme at jeg har gjort begge deler mer enn jeg vil dele!). Men "skrivekode" -trinnet antar mye, gjør det ikke?

For alle som har skrevet kode i god tid, er du altfor kjent at du ender opp med å treffe det punktet hvor du skjønner, "Åh ... jeg tenkte ikke på det."

Hvis du er heldig, betyr dette vanligvis at du kan skrive en hjelpemetode eller en annen betinget for å håndtere saken du forsømte, men i verste fall betyr det at du må omarbeide hele klassen eller hele settet av funksjoner til imøtekomme dette problemet.

Enhetstesting, men ikke perfekt, kan bidra til å redusere dette.

Tenk på det faktum at du fra begynnelsen lister ut all funksjonalitet som du vil at temaet eller pluginet skal tilby. Du har ennå ikke skrevet noen kode, men kanskje du har en slags skisse av brukergrensesnittet og / eller et sett med klassediagrammer.

Deretter begynner du å skrive ut testene du skal skrive for å teste prosjektet ditt. Husk at en del av enhetstesting er å bryte ned koden til den største atomenheten, og du har derfor til oppgave å skrive enhetstester for hver av disse, ahem, enheter.

På grunn av enhetstestingens art, tenker du på egen måte din kode forskjellig: i stedet for "skrivekode", tenker du på "skrive tester", og fordi du må tenke på et mer atomnivå, kan du Det hjelper ikke, men vurderer frynser som er så ofte klumpet i "skrivekode".


Språket i koden din

Som utviklere er vi altfor komfortable med å bruke konvensjoner som kontinuerlig forsterker at vi skriver kode. Dermed mener jeg at vi har en tendens til å gi forkortede variabelnavn, kryptiske funksjonsnavn og klassenavn som kanskje ikke betyr noe for noen utenfor deg selv eller laget som jobber med prosjektet ditt.

Enhetstesting er ikke nødvendigvis nøkkelen til å skrive kode som er lettere å lese, men det kan gå litt lenger for å bidra til å gi renere funksjonenavn.

Husk fra den første programmeringsboken du leser, den første datavitenskapsklassen du tok, eller den første delen av åpen kildekode du så, metodenavn er vanligvis verb. Hvorfor burde de ikke være? Metoder er måter å inkapslere kode som gjør ting. Men når vi jobber med prosjekter i lengre tid, blir vi lazier og lazier og vår kode går fra "register_user_and_email_password ()" til "ny konto()".

Selvfølgelig er den tidligere renere enn sistnevnte, men hvis vi strever etter kvalitetsenhetstesting, og vi vil sørge for at enhetstestene våre er enkle å lese og for at de skal være enkle å lese, må våre funksjonsnavn være lett å lese.

Er det ikke lett å lese:

 $ this-> assertFalse (register_user_and_email_password ("));

Istedenfor dette?

 $ this-> assertFalse (new_account ("));

Igjen, kanskje dette er et enkelt eksempel, men prinsippet er fortsatt: Skrive gode enhetstester for å hjelpe selv dokumentere koden som driver språket til dine funksjoner.


Konklusjon

Vi har snakket om grunnleggende om enhetstesting, samt de viktigste fordelene, men vi har ennå ikke diskutert ulempene som følger med enhetstesting, og vi har ikke engang tatt en titt på hvordan å innlemme den i arbeidsflyten vår.

Så i neste artikkel vil vi forsøke å gjøre nettopp det.