Programmering Med Yii2 Automatisert Testing Med Codeception

Hva du skal skape

Hvis du spør, "Hva er Yii?" sjekk ut min tidligere opplæring, Introduksjon til Yii Framework, som vurderer fordelene med Yii og inneholder en oversikt over hva som er nytt i Yii 2.0, utgitt i oktober 2014.

I denne programmeringen med Yii2-serien, veileder jeg lesere i bruk av Yii2 Framework for PHP. I denne opplæringen vil jeg utforske automatisert testing ved hjelp av Codeception, som er integrert med Yii2-utviklingsrammen.

Ganske vist er min erfaring med å skrive tester med koden min sjelden. Jeg har ofte vært en del av solo eller små prosjekter med begrensede ressurser. I løpet av min tid hos Microsoft hadde vi forskjellige testteam som gjorde dette. Men ærlig, dette er sannsynligvis typisk for deg også, ikke sant? Programmører liker å kode, de skriver ikke tester - i hvert fall gamle skoleprogrammerte ikke.

Codeception er et innovativt bibliotek som bokstavelig talt har som mål å gjøre skriveprøver morsomt og enkelt. Og jeg vil si at de har lykkes i en rimelig grad. Da jeg dypet tåen i vannet i "Lake Codeception", var det for det meste enkelt og morsomt. Men da jeg begynte å gå dypere, løp jeg inn konfigurasjonsproblemer med Yii og de spesifikke modulene som brukes i denne serien. Det var definitivt utfordringer. Samlet sett er jeg imponert, og se fordelene med å lære mer.

Enkelt sagt, Codeception og integrasjon med Yii gjør at jeg vil skrive flere tester, en første for meg. Jeg mistenker at du får en lignende opplevelse. 

En liten påminnelse før vi kommer i gang, deltar jeg i kommentertrådene nedenfor. Jeg er spesielt interessert hvis du har flere tanker eller vil foreslå emner for fremtidige opplæringsprogrammer. Hvis du har et spørsmål eller et emneforslag, vennligst legg inn under. Du kan også nå meg på Twitter @ reifman direkte.

Starter

Installere Codeception

For å veilede meg brukte jeg Yii's Testing Environment Setup dokumentasjon. Jeg begynte med en global installasjon av koding, slik at jeg kunne bruke den fra et hvilket som helst prosjekt.

$ komponent global krever "codeception / codeception = 2.1. *" Endret gjeldende katalog til /Users/Jeff/.composer ./composer.json har blitt oppdatert Laster kompositorbeholdninger med pakkedata Oppdatere avhengigheter (inkludert krav-dev) - Installere symfony / yaml (v3.1.1) Laster fra cache ... codeception / codeception foreslår installering av symfony / phpunit-bridge (For phpunit-bridge-støtte) Skrive låsfil Generere autoload-filer

Du må også kreve codeception / spesifisere:

$ komponent globalt krever "codeception / specify = *" Endret gjeldende katalog til /Users/Jeff/.composer ./composer.json har blitt oppdatert Laster kompositorbeholdninger med pakkedata Oppdatere avhengigheter (inkludert krav-dev) komponist krever "codeception / verifisere = * "- Installere kodeception / spesifiser (0.4.3) Nedlasting: 100% Skrive låsfil Generere autoload-filer

Og codeception / bekrefte:

$ komponent krever "codeception / verifiser = *". /composer.json har blitt oppdatert Laster kompositorbeholdninger med pakkedata Oppdatere avhengigheter (inkludert krav-dev) - Installere kodeksering / verifisere (0.3.0) Last ned: 100% Skrive låsfil Generere autoload-filer

Deretter hjelper det å sette opp et alias for codecept bruker din globale komponistkatalog:

$ komponent global status Endret gjeldende katalog til /Users/Jeff/.composer Ingen lokale endringer 

Dette setter aliaset:

$ alias codecept = "/ Brukere / Jeff / .composer / vendor / bin / codecept"

Yii krever også at du installerer Faker, som genererer falske testdata for din søknad:

$ komponent krever --dev yiisoft / yii2-faker: * ./composer.json har blitt oppdatert Laster kompositorbeholdninger med pakkedata Oppdatere avhengigheter (inkludert krav-dev) Ingenting å installere eller oppdatere Generere autoload-filer

Konfigurere kodeks med søknaden din

Codecept bootstrapinitierer kodeks for din Yii-applikasjon, oppretter en rekke konfigurasjonsfiler for å bygge og løpe tester mot søknaden din. Vi bruker Hello-programmet fra denne serien for denne opplæringen. Se GitHub-lenken på denne siden for å få koden.

$ codecept bootstrap Initialisering Codeception i / Brukere / Jeff / Sites / hei File codeception.yml opprettet <- global configuration tests/unit created <- unit tests tests/unit.suite.yml written <- unit tests suite configuration tests/functional created <- functional tests tests/functional.suite.yml written <- functional tests suite configuration tests/acceptance created <- acceptance tests tests/acceptance.suite.yml written <- acceptance tests suite configuration tests/_output was added to .gitignore --- tests/_bootstrap.php written <- global bootstrap file Building initial Tester classes Building Actor classes for suites: acceptance, functional, unit -> AcceptanceTesterActions.php genereres vellykket. 0 metoder lagt til \ AcceptanceTester inkluderer moduler: PhpBrowser, \ Helper \ Acceptance AcceptanceTester.php opprettet. -> FunctionalTesterActions.php genereres vellykket. 0 metoder lagt til \ FunctionalTester inkluderer moduler: \ Helper \ Functional FunctionalTester.php opprettet. -> UnitTesterActions.php genereres vellykket. 0 metoder lagt til \ UnitTester inkluderer moduler: Asserts, \ Helper \ Unit UnitTester.php opprettet. Bootstrap er ferdig. Sjekk ut / Brukere / Jeff / Nettsteder / hei / tester katalog

Av en eller annen grunn endte jeg også med dupliserte testkataloger i hei / tester; bare å slette hei / tester / funksjonelle, hei / tester / aksept, og hei / tester / enhet rydde opp ting. Alle tester bor i hallo / tester / koding / *.

Forskjellige typer test

Codeception er fokusert på tre typer tester:

  1. Enhetstesting verifiserer at bestemte enheter fungerer, for eksempel en uttømmende test av alle modellens metoder.
  2. Funksjonell testing verifiserer vanlige applikasjonsscenarier som om en bruker var å utøve dem, men ved bruk av nettleseremulering.
  3. Godkjenningstesting er identisk med funksjonell testing, men driver faktisk tester gjennom en nettleser.

Og den støtter tre forskjellige typer testformater for testkoden din:

  1. Cept: det er den enkleste enkeltscenarestestfilen
  2. Cest: et objektorientert format for å kjøre flere tester i en enkelt fil
  3. Test: Tester skrevet på PHPUnit, et PHP testing rammeverk

La oss begynne med et eksempel på aksept tester ved hjelp av cept format:

Godkjenningstesting

Vi bruker Codeception's Velkommentest eksempel først.

$ kodecept generere: cept aksept Velkommen Test ble opprettet i /Users/Jeff/Sites/hello/tests/acceptance/WelcomeCept.php

Dette genererer tester / aksept / WelcomeCept.php, som vi vil redigere nedenfor.

Siden godkjenningstester krever nettleseren, må vi redigere /tests/acceptance.suite.yml i vårt prosjekt for å gi vår utviklingsadresse, http: // localhost: 8888 / hallo:

# Codeception Test Suite Configuration # # Suite for aksepttest. # Utfør tester i nettleseren ved hjelp av WebDriver eller PhpBrowser. # Hvis du trenger både WebDriver og PHPBrowser tester - opprett en egen suite. class_name: AcceptanceTester moduler: aktivert: - PhpBrowser: url: http: // localhost: 8888 / hei / - \ Helper \ Acceptance 

Nå er vi klare til å modifisere den første testen i tester / aksept / WelcomeCept.php. Jeg skriver en test som laster forsiden for å sikre at den fungerer som forventet. 

Codeception tester har begrepet en skuespiller, i dette tilfellet, $ I = ny AcceptanceTester ().

Slik beskriver det skuespillere i Codeception-dokumentasjonen:

Vi har en UnitTester, som utfører funksjoner og tester koden. Vi har også en FunctionalTester, en kvalifisert tester, som tester applikasjonen som helhet, med kunnskap om sine internals. Og en AcceptanceTester, en bruker som jobber med vår søknad gjennom et grensesnitt som vi tilbyr.

Du kan kommentere tester med kode, for eksempel $ I-> vilTo ('utføre en bestemt test')eller 'sørg for at forsiden fungerer'.

I min test vil jeg se $ I-> se tekst for 'Gratulerer!' og 'Yii-drevne':

wantTo ('sørg for at forsiden fungerer'); $ I-> amOnPage ( '/'); $ I-> se ( 'Gratulerer!'); $ I-> se ( 'Yii-drevne'); 

Her er den nåværende Hello-hjemmesiden:

Neste, la oss kjøre testen, ganske enkelt kodeks løp:

$ codecept kjøre Codeception PHP Testing Framework v2.1.11 Drevet av PHPUnit 5.3.5 av Sebastian Bergmann og bidragsytere. Godkjenningstester (1) --------------------------------------------- ------------------------------------------ Kontroller at forsiden fungerer (WelcomeCept) Ok -------------------------------------------------- -------------------------------------------------- -------- Funksjonstester (0) ------------------------ ------------- -------------------------------- Enhetstester (0) ------------- ----------------- --------------------------------- ------------ Tid: 554 ms, Minne: 10,25MB OK (1 test, 2 påstander)

Som du kan se, passerte vår test, og koden for å bekrefte denne funksjonaliteten var ganske lesbar og enkel.

Notater om Yiis standardtester

For å gå videre, begynte jeg å bruke Yii standardtester. På dette tidspunktet løp jeg inn i en rekke konfigurasjonsproblemer, hovedsakelig på grunn av min bruk av den tilpassede yii2-brukermodulen i denne serien. Andre var på grunn av små feil med Yii, som teamet hans har vært raske til å svare på og fikse når rapportert om GitHub; i noen tilfeller har problemer blitt løst i senere utgivelser av yii2-grunnleggende treet.

Også, fordi jeg hadde oppdatert yii2-grunnleggende treet for denne serien, måtte jeg gjøre små endringer i noen av standardtester.

Her er et eksempel på utgangen for å kjøre standard aksepttester når jeg hadde gjort noen mindre justeringer:

$ codecept kjøre Codeception PHP Testing Framework v2.1.11 Drevet av PHPUnit 5.3.5 av Sebastian Bergmann og bidragsytere. Godkjenningstester (4) --------------------------------------------- -------------------------------------------------- - Forsikre deg om om arbeid (AboutCept) Ok Sørg for at kontakten fungerer (ContactCept) Ok Sørg for at hjemmesiden fungerer (HomeCept) Ok Sørg for at innloggingen virker (LoginCept) Ok ----------------------------------------------------------------------------------------------------------------------

Funksjonell testing

For å få funksjonelle tester på jobb, trengte jeg å kjøre en forekomst av Yii sin innebygde server. Jeg hadde ikke kjent om denne komponenten før Yii Alex Makarov nevnte det i vår GitHub-utveksling.

$ ./yii tjene

Jeg har gjort små endringer i funksjonstester i / tester / kodesystem / funksjonalitet, for det meste å se etter mine spesifikke oppdaterte tekststrenger, dvs. "Ugyldig pålogging eller passord" i stedet for Yii standard. Her er en titt på LoginCept.php:

wantTo ('sørg for at innlogging fungerer'); $ loginPage = LoginPage :: openBy ($ I); $ I-> se ( 'Pålogging'); $ I-> amGoingTo ('prøv å logge inn med tomme legitimasjonsbeskrivelser'); $ LoginPage-> logg ( ""); $ I-> expectTo ('se valideringsfeil'); $ I-> se ('Logg inn kan ikke være tom.'); $ I-> se ('Passordet kan ikke være tomt.'); $ I-> amGoingTo ('prøv å logge inn med feil legitimasjon'); $ loginPage-> login ('admin', 'feil'); $ I-> expectTo ('se valideringsfeil'); $ I-> se ('Ugyldig pålogging eller passord'); $ I-> amGoingTo ('prøv å logge inn med riktige legitimasjonsbeskrivelser'); $ loginPage-> login ('admin', 'admin11'); $ I-> expectTo ('se brukerinformasjon'); $ I-> se ( 'Logg ut');

I utgangspunktet får koden tilgang til Innloggingsskjema modell og tester sine ulike metoder ved å bruke Yii server.

Her er /tests/codeception_pages/LoginPage.php-testkoden det er brukbar (jeg måtte også endre den for endringer vi har gjort i serien):

class LoginPage utvider BasePage public $ route = 'user / login'; / ** * @param streng $ brukernavn * @param streng $ passord * / offentlig funksjon login ($ brukernavn, $ passord) $ this-> actor-> fillField ('input [name = "login-form [login] ] ', $ brukernavn); $ this-> actor-> fillField ('input [name = "login-form [passord]"]', $ passord); $ Dette-> actor-> klikk (knappen [type = Send] ');  

Du kan se at vi kodler skuespilleren til fillFieldsog klikk knapper for våre oppdaterte skjemafelter. 

Mens jeg feilsøker min Codeception-integrasjon med Yii, fant jeg det nyttig å kjøre disse testene i verbose modus:

$ codecept run -vvv

Her er den utrolige utgangen fra funksjonene for pålogging pålogging i MacOS Terminal, PASSERT og FEILET er fargekodede rød eller rosa og invertert for synlighet:

Funksjonstester (4) --------------------------------------------- -------------------------------------------------- - Moduler: Filsystem, Yii2 ... ------------------------------------------ -------------------------------------------------- -------------------------- Forsikre deg om at innlogging fungerer (LoginCept) Scenario: * Jeg er på side "/index-test.php/user/ logg inn "[Side] /index-test.php/user/login [Response] 200 [Be om cookies] [] [Response Headers] " innholdstype ": [" text / html; charset = UTF-8 "] * Jeg ser på "Innlogging" * Jeg skal prøve å logge inn med tomme legitimasjonsbeskrivelser * Jeg fyller felt "input [name =" login-form [login] "" "," * Jeg fyller felt "input [name =" login -form [passord] "]", "" * Jeg klikker "knappen [type = send]" [Uri] http: //localhost/index-test.php/user/login [Metode] POST [Parameters] "_csrf ":" VEpvcmk3bVgFH1Y9AVsmYWQQDEouTSggYXMFGStdKBEnCyQfBxo8Bw == "," login-skjema [login] ":" "," login-skjema [passord] ":" " [Side] http: //localhost/index-test.php/user/login [Svar] 200 [Be om cookies] "_csrf": "dd395a9e5e3c08 cfb1615dae5fc7b5ba0a2025c003e430ba0139b300f4a917ada: 2: i: 0; s: 5: "_ csrf"; i: 1; s: 32: "QU9OhlK90Zc8GzEx59jkBjEIsAKmn-Q_"; " [Response Headers] " innholdstype ": [" tekst / html ; charset = UTF-8 "] * Jeg forventer å se valideringsfeil * Jeg ser" Logg inn kan ikke være tom. "* Jeg ser" Passordet kan ikke være tomt. "* Jeg skal prøve å logge inn med feil legitimasjon * Jeg fyller felt "Input [name =" login-form [login] "]", "admin" * Jeg fyller felt "input [name =" login-form [passord] "]", "feil" * Jeg klikker " sende] "[Uri] http: //localhost/index-test.php/user/login [Metode] POST [Parametre] " _csrf ":" QjFBRl9hMjMTZHgJNw15CnJrIn4YG3dLdwgrLR0Ld3oxcAorMUxjbA == "," login-skjema [login] ":" admin "," påloggingsskjema [passord] ":" feil " [Side] http: //localhost/index-test.php/user/login [Response] 200 [Request Cookies] " _csrf ":" dd395a9e5e3c08cfb1615dae5fc7b5ba0a2025c003e430ba0139b300f4a917ada: 2 : i: 0; s: 5: "_ csrf"; i: 1; s: 32: "QU9OhlK90Zc8GzEx59jkBjEIsAKmn-Q_"; " [Response Headers] " innholdstype ": [" text / html; charset = UTF-8 "] * Jeg forventer å se valideringsfeil * Jeg ser" Ugyldig påloggning eller passord "* Jeg skal prøve å logge inn med riktige legitimasjonsbeskrivelser * Jeg fyller felt" input [name = "login-form [login ] "," admin "* Jeg fyller felt" input [name = "login-form [passord]"] "," admin11 "* Jeg klikker" knappen [type = send] "[Uri] http: // localhost /index-test.php/user/login [Metode] POST [Parametre] "_csrf": "bG8uMXdPYk49Ohd.HyMpd1w1TQkwNSc2WVZEWjUlJwcfLmVcGWIzEQ ==", "login-skjema [login]": "admin", "påloggingsskjema [passord] ":" admin11 " [Headers] " location ": [" http: //localhost/index-test.php "]," innholdstype ": [" text / html; charset = UTF-8 "] [Side] http: //localhost/index-test.php/user/login [Response] 302 [Request Cookies] " _csrf ":" dd395a9e5e3c08cfb1615dae5fc7b5ba0a2025c003e430ba0139b300f4a917ada: 2: i: 0; s : 5: "_ csrf"; i: 1; s: 32: "QU9OhlK90Zc8GzEx59jkBjEIsAKmn-Q_"; " [Response Headers] " location ": [" http: //localhost/index-test.php "]," content-type ": [" text / html; charset = UTF-8 "] [Viderekobling til http: //localhost/index-test.php [Side] http: //localhost/index-test.php [Response] 200 [Request Cookies] " _csrf ": "dd395a9e5e3c08cfb1615dae5fc7b5ba0a2025c003e430ba0139b300f4a917ada: 2: i: 0; s: 5:" _ csrf "; i: 1; s: 32:" QU9OhlK90Zc8GzEx59jkBjEIsAKmn-Q_ ";" [Response Headers] "innholdstype": [ html; charset = UTF-8 "] * Jeg forventer å se brukerinformasjon * Jeg ser" Logout "PASSED 

Samlet sett er det litt å lære å komme i gang med Codeception og korrekt kode tester. Men resultatene er imponerende og hjelpsomme.

Enhetstesting

I utgangspunktet er enhetstester programmatisk testing av infrastruktur og modeller. Ideelt sett vil vi skrive tester for hver metode og bruksvariasjon av modellene våre.

Dessverre var jeg ikke i stand til å få enhetstester til å fungere i treet vårt på grunn av enten små Yii-feil, men likevel å bli utgitt eller konfigurasjonsproblemer mellom Codeception og yii2-brukeren som vi integrerte i Hvordan Programmer Med Yii2: Integrerer Brukerregistrering. 

Enhetstester (3) --------------------------------------------- -------------------------------------------------- ----- Moduler: ------------------------------------------- -------------------------------------------------- ---------------------- Prøver å teste innlogging ingen bruker (tester \ kodeoppsett \ enhet \ modeller \ LoginFormTest :: testLoginNoUser) ... 
PHP Fatal Error 'yii \ base \ ErrorException' med melding 'Ring til udefinerte funksjonstester \ codeception \ unit \ models \ expect ()' 

Jeg skal adressere enhetstesting igjen i vår oppstartsserie som ikke bruker yii2-bruker, men bruker i stedet Yii Advanced-treets integrerte brukerintegrasjon.

La oss se på et par eksempler fra Yii2-app-grunnleggende treet.

Testing Contact Form Emails

Hei / tester / kodeks / enhet / modeller / ContactFormTest.php tester sender en e-post gjennom programmatisk bruk av modeller:

mailer-> fileTransportCallback = funksjon ($ mailer, $ melding) return 'testing_message.eml'; ;  beskyttet funksjon tearDown () unlink ($ this-> getMessageFile ()); ordnede :: Teardown ();  offentlig funksjon testContact () $ model = $ this-> createMock ('app \ models \ ContactForm', ['validere']); $ Modell> forventer ($ dette-> en gang til ()) -> metode ( 'validere') -> vil ($ dette-> return (true)); $ model-> attributes = ['name' => 'Tester', 'email' => '[email protected]', 'subject' => 'veldig viktig brev emne', 'body' => ' budskap', ]; $ Modell> kontakt ('[email protected] '); $ this-> spesifiser ('e-post skal sendes', funksjon () forvente ('e-postfilen skal eksistere', file_exists ($ this-> getMessageFile ())) -> true ();); $ this-> spesifiser ('beskjed skal inneholde riktige data', funksjon () bruk ($ modell) $ emailMessage = file_get_contents ($ this-> getMessageFile ()); forvent ('email skal inneholde brukernavn', $ emailMessage) -> inneholder ($ modell-> navn); forvent ('e-post skal inneholde avsender e-post', $ emailMessage) -> inneholder ($ modell-> e-post); ($ modell-> emne); forvent ('e-post skal inneholde kropp', $ emailMessage) -> inneholder ($ modell-> kropp););  privat funksjon getMessageFile () return Yii :: getAlias ​​(Yii :: $ app-> mailer-> fileTransportPath). '/Testing_message.eml';  

Jeg klarte ikke å få denne testen til å passere på grunn av en liten feil i Yii som ikke har blitt oppdatert ennå (eller i det minste kunne jeg ikke finne den oppdaterte koden). Min dråpe i Yii kodebase var navngi utgående e-post med datostempler, og koden ovenfor var på jakt etter et fast filnavn. Dermed mislyktes det alltid. Likevel er det nyttig å se hvordan programmatisk testing kan bruke modeller til å generere en fil og deretter lete etter den filen og validere innholdet for å bekrefte at koden fungerer.

Testing Login

La oss se på hallo / tester / kodeks / enhet / modeller / LoginFormTest.php. Igjen gjorde min bruk av yii2-bruker det altfor vanskelig å integrere ved skriving av denne opplæringen; Vi kan imidlertid se på den konseptuelle tilnærmingen til enhetstesting av brukermodellfunksjoner.

her er testLoginCorrect (), som ser ut til å se om innloggingen lykkes med et riktig passord:

offentlig funksjon testLoginCorrect () $ model = ny LoginForm (['brukernavn' => 'admin', 'passord' => 'admin11',]); $ this-> spesifiser ('brukeren skal kunne logge inn med riktig legitimasjon', funksjon () bruk ($ modell) forvente ('modell skal logge inn bruker', $ modell-> logg inn ()) -> true (); Forvent ('feilmeldingen skal ikke settes', $ model-> feil) -> hasntKey ('passord'); forvente ('brukeren skal logges inn', Yii :: $ app-> user-> isGuest) -> falsk(); ); 

Den bruker Innloggingsskjema modell for å logge inn brukeren, og deretter ser det programmatisk ut for å se om Yii nåværende bruker ikke lenger er gjest.

Forvent ('brukeren skal være logget inn', Yii :: $ app-> user-> isGuest) -> false ();

Hva blir det neste?

Jeg håper at du har likt å lære om Codeception og dets integrasjon med Yii, til tross for noen av veisperrene jeg kjørte inn i. Standardinstallasjon av yii2-basic i dag skal fungere bedre.

Hvis du vil lese mer om hvordan du bestemmer når og hva du skal teste og hvorfor, anbefaler jeg at du leser Yii Testing Oversikt. Det er sikkert mer å lære om Codeception og skrive mer komplette tester.

Se etter kommende opplæringsprogrammer i Programmering med Yii2-serien når vi fortsetter å dykke inn i ulike aspekter av rammen. Hvis du vil vite når neste Yii2 opplæring kommer, følg meg @ reifman på Twitter eller sjekk min instruktørside. 

Du vil kanskje også sjekke ut vårt Bygg din oppstart med PHP-serien, som bruker Yii2s avanserte mal, da vi bygger en applikasjon i verden. Faktisk kan du prøve ut oppstartsprogrammet, møteplanlegger, i dag.

Relaterte linker

  • Codeception
  • Yii2 Developer Exchange, min Yii2 ressurs side
  • Yii2 Testing Environment Setup