Om du frågar, "Vad är Yii?" kolla in min tidigare handledning, Introduktion till Yii Framework, som granskar fördelarna med Yii och innehåller en översikt över vad som är nytt i Yii 2.0, släppt i oktober 2014.
I denna programmering med Yii2-serien guidar jag läsare som använder Yii2 Framework for PHP. I denna handledning undersöker jag automatiserad testning med Codeception, som är integrerad med Yii2-utvecklingsramen.
Givetvis är min erfarenhet av att skriva tester med min kod knappa. Jag har ofta varit en del av solo eller små projekt med begränsade resurser. Under min tid hos Microsoft hade vi olika testgrupper som gjorde det här. Men uppriktigt sagt, det här är troligen typiskt för dig också, eller hur? Programmerare gillar att koda, de skriver inte tester - åtminstone gamla skolprogrammerare gjorde det inte.
Codeception är ett innovativt bibliotek som bokstavligen syftar till att göra skrivprov roligt och enkelt. Och jag skulle säga att de lyckats i en rimlig grad. När jag döpte min tå i "Lake Codeception" -vatnet var det mest lätt och roligt. Men när jag började gå djupare, sprang jag i konfigurationsproblem med Yii och de specifika modulerna som användes i denna serie. Det var definitivt utmaningar. Sammantaget är jag dock imponerad och ser nytta av att lära mig mer.
Enkelt sagt, Codeception och dess integration med Yii gör mig vill skriva mer tester, en första för mig. Jag misstänker att du får en liknande upplevelse.
En liten påminnelse innan vi börjar, deltar jag i kommenterade trådar nedan. Jag är särskilt intresserad om du har ytterligare tankar eller vill föreslå ämnen för framtida handledning. Om du har en fråga eller ett ämne förslag, vänligen posta nedan. Du kan också nå mig på Twitter @ reifman direkt.
För att styra mig använde jag Yii Testing Environment Setup-dokumentation. Jag började med en global installation av codeception så att jag kunde använda den från något projekt.
$ composer global kräver "codeception / codeception = 2.1. *" Ändrad aktuell katalog till /Users/Jeff/.composer ./composer.json har uppdaterats Laddar kompositregister med paketinformation Uppdatering av beroenden (inklusive krav-dev) - Installera symfony / yaml (v3.1.1) Laddar från cache ... codeception / codeception föreslår installera symfony / phpunit-bridge (För phpunit-bridge support) Skriva låsfil Generera autoload-filer
Du måste också kräva codeception / specificera
:
$ composer global kräver "codeception / specify = *" Ändrad nuvarande katalog till /Users/Jeff/.composer ./composer.json har uppdaterats Laddar kompositregister med paketinformation Uppdatering av beroenden (inklusive krav-dev) kompositör kräver "codeception / verifiera = * "- Installera koduppsättning / specificera (0.4.3) Hämta: 100% Skriva låsfil Generera autoload-filer
Och codeception / kontrollera
:
$ composer kräver "codeception / verify = *". /composer.json har uppdaterats Laddar kompositregister med paketinformation Uppdatering av beroenden (inklusive krav-dev) - Installera koduppsättning / verifiera (0.3.0) Hämtning: 100% Skrivning av låsenfil Generering autoload-filer
Därefter bidrar det till att skapa ett alias för codecept
Använda din globala kompositörskatalog:
$ composer global status Ändrad nuvarande katalog till /Users/Jeff/.composer Inga lokala ändringar
Detta anger aliaset:
$ alias codecept = "/ Användare / Jeff / .composer / vendor / bin / codecept"
Yii kräver också att du installerar Faker, vilket genererar falska testdata för din applikation:
$ komponent kräver --dev yiisoft / yii2-faker: * ./composer.json har uppdaterats Laddar kompositregister med paketinformation Uppdatering av beroenden (inklusive krav-dev) Inget att installera eller uppdatera Generera autoload-filer
Codecept bootstrap
initierar codeception för din Yii-applikation, skapar en mängd olika konfigurationsfiler för att bygga och springa test mot din applikation. Vi använder Hello-programmet från den här serien för denna handledning. Se länken GitHub på den här sidan för att få koden.
$ codecept bootstrap Initialiserar Codeception i / Användare / Jeff / Sites / hej File codeception.yml skapad <- 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 genereras framgångsrikt. 0 metoder läggas till \ AcceptanceTester innehåller moduler: PhpBrowser, \ Helper \ Acceptance AcceptanceTester.php skapad. -> FunctionalTesterActions.php genereras framgångsrikt. 0 metoder läggas till \ FunctionalTester innehåller moduler: \ Helper \ Functional FunctionalTester.php skapad. -> UnitTesterActions.php genererades framgångsrikt. 0 metoder tillagda \ UnitTester innehåller moduler: Asserts, \ Helper \ Unit UnitTester.php skapad. Bootstrap är klar. Kolla in / Användare / Jeff / Sites / hej / tester katalog
Av någon anledning slutade jag också med dubbla testkataloger i hej / tester. bara raderar hej / tester / funktionell, hej / tester / acceptans och hej / tester / enhet rensade saker upp. Alla tester lever i hej / tester / koduppfattning / *.
Codeception är inriktad på tre typer av test:
Och det stöder tre olika typer av testformat för din testkod:
Låt oss börja med ett exempel på acceptanstest använder sig av cept format:
Vi använder Codeception's Välkommen
testa exempel först.
$ codecept generera: cept accept Välkommen Test skapades i /Users/Jeff/Sites/hello/tests/acceptance/WelcomeCept.php
Detta genererar test / godkännande / WelcomeCept.php
, som vi redigerar nedan.
Eftersom acceptanstest kräver webbläsaren måste vi redigera /tests/acceptance.suite.yml i vårt projekt för att tillhandahålla vår utvecklingsadress, http: // localhost: 8888 / hello:
# Codeception Test Suite Configuration # # Suite för godkännande test. # Utför test i webbläsare med WebDriver eller PhpBrowser. # Om du behöver både WebDriver- och PHPBrowser-tester - skapa en separat svit. class_name: AcceptanceTester moduler: aktiverat: - PhpBrowser: url: http: // localhost: 8888 / hej / - \ Helper \ Acceptance
Nu är vi redo att ändra det ursprungliga testet i test / acceptans / WelcomeCept.php. Jag skriver ett test som laddar framsidan för att se till att det fungerar som förväntat.
Codeception tester har begreppet en skådespelare, i det här fallet, $ I = ny AcceptanceTester ()
.
Så här beskriver den aktörer i Codeception-dokumentationen:
Vi har en UnitTester, som utför funktioner och tester koden. Vi har också en FunctionalTester, en kvalificerad tester, som testar applikationen som helhet med kunskap om sina internals. Och en AcceptanceTester, en användare som arbetar med vår applikation genom ett gränssnitt som vi tillhandahåller.
Du kan kommentera dina tester med kod, till exempel $ I-> wantTo ("utföra ett visst test")
eller "se till att frontsidan fungerar"
.
I mitt test vill jag se $ I-> se
text för 'Grattis!'
och 'Yii-drivna'
:
wantTo ("se till att frontpage fungerar"); $ I-> amOnPage ( '/'); $ I-> se (Grattis! '); $ I-> se (Yii drivna ');
Här är den nuvarande Hello-hemsidan:
Låt oss sedan köra testet, helt enkelt codecept körning
:
$ codecept kör Codeception PHP Testing Framework v2.1.11 Drivs av PHPUnit 5.3.5 av Sebastian Bergmann och bidragsgivare. Acceptanstest (1) --------------------------------------------- ------------------------------------------ Se till att frontpage fungerar (WelcomeCept) Ok -------------------------------------------------- -------------------------------------------------- -------- Funktionstester (0) ------------------------ ------------- -------------------------------- Enhetsprov (0) ------------- ----------------- --------------------------------- ------------ Tid: 554 ms, Minne: 10,25 MB OK (1 test, 2 påståenden)
Som du kan se passerade vårt test, och koden för att verifiera denna funktionalitet var ganska läsbar och enkel.
För att gå vidare började jag använda Yiis standardtester. Vid denna tidpunkt har jag stött på ett antal konfigurationsproblem, vilket är mest på grund av min användning av den anpassade yii2-användarmodulen i denna serie. Andra berodde på små buggar med Yii, vars lag har varit snabb att reagera på och fixa när rapporterats på GitHub; i vissa fall har problem upprättats i senare utgåvor av yii2-grundträdet.
Dessutom, för att jag hade uppdaterat det yii2-grundläggande trädet för denna serie, var jag tvungen att göra små förändringar i några av standardtesten.
Här är ett exempel på utgången för att köra standardantagningstesten när jag hade gjort några mindre justeringar:
$ codecept kör Codeception PHP Testing Framework v2.1.11 Drivs av PHPUnit 5.3.5 av Sebastian Bergmann och bidragsgivare. Acceptanstest (4) --------------------------------------------- -------------------------------------------------- - Säkerställ att om works (AboutCept) Ok Kontrollera att kontakten fungerar (ContactCept) Ok Kontrollera att hemsidan fungerar (HomeCept) Ok Kontrollera att inloggningen fungerar (LoginCept) Ok ----------------------------------------------------------------------------------------------------------------------
För att få funktionella tester på jobbet, behövde jag köra en instans av Yiis inbyggda server. Jag hade inte känt till denna komponent tills Yii Alex Makarov nämnde det i vår GitHub-utbyte.
$ ./yii servera
Jag gjorde små ändringar i funktionstesterna i / tester / koduppfattning / funktion, mestadels för att söka efter mina specifika uppdaterade textsträngar, dvs "Ogiltig inloggning eller lösenord" istället för Yiis standard. Här är en titt på LoginCept.php:
wantTo ('se till att inloggningen fungerar'); $ loginPage = LoginPage :: openBy ($ I); $ I-> se (in '); $ I-> amGoingTo ('försök att logga in med tomma uppgifter'); $ LoginPage-> inloggning ( ""); $ I-> expectTo ('se valideringsfel'); $ I-> see ('Logga in kan inte vara tomt.'); $ I-> se ('Lösenordet kan inte vara tomt.'); $ I-> amGoingTo ('försök att logga in med felaktiga uppgifter'); $ loginPage-> login ('admin', 'wrong'); $ I-> expectTo ('se valideringsfel'); $ I-> se ('Ogiltig inloggning eller lösenord'); $ I-> amGoingTo ('försök att logga in med rätt uppgifter'); $ loginPage-> login ('admin', 'admin11'); $ I-> expectTo ('se användarinformation'); $ I-> se (Logga ut ');
I grund och botten går åtkomst till koden Inloggningsformulär
modell och testa sina olika metoder med hjälp av Yii-tjänsten.
Här är /tests/codeception_pages/LoginPage.php-testkoden som det använder sig av (jag måste också ändra det för ändringar som vi har gjort till serien):
class LoginPage utökar BasePage public $ route = 'user / login'; / $ * @paramsträng $ användarnamn * @paramsträng $ lösenord * / allmän funktion inloggning ($ användarnamn, $ lösenord) $ this-> actor-> fillField ('input [name = "login-form [login] ] ', $ användarnamn); $ this-> actor-> fillField ('input [name = "login-form [lösenord]"]', $ lösenord); $ This-> actor-> klicka ( 'knappen [type = lämna]');
Du kan se att vi kodar skådespelaren till fillFields
och klick
knappar för våra uppdaterade formulärfält.
Medan jag felsökte min Codeception-integration med Yii fann jag det till hjälp att köra dessa tester i verbalt läge:
$ codecept run -vvv
Här är den verbala produktionen från funktionstesterna inloggning i MacOS Terminal, PASSERADE
och MISSLYCKADES
är färgkodade röda eller rosa och inverterade för synlighet:
Funktionella test (4) --------------------------------------------- -------------------------------------------------- - Moduler: Filsystem, Yii2 ... ------------------------------------------ -------------------------------------------------- -------------------------- Se till att inloggningen fungerar (LoginCept) Scenario: * Jag är på sidan "/index-test.php/user/ Logga in "[Sida] /index-test.php/user/login [Response] 200 [Begär cookies] [] [Response Headers] " content-type ": [" text / html; charset = UTF-8 "] * Jag ser "Inloggning" * Jag ska försöka logga in med tomma uppgifter * Fyll i fält "inmatning [namn =" inloggningsformulär [inloggning] "]", "" * Fyll i fält "inmatning [namn =" inloggning -form [lösenord] "]", "" * Jag klickar på "knappen [typ = skicka]" [Uri] http: //localhost/index-test.php/user/login [Metod] POST [Parametrar] "_csrf ":" VEpvcmk3bVgFH1Y9AVsmYWQQDEouTSggYXMFGStdKBEnCyQfBxo8Bw ==", "inloggning-form [inloggning]": "", "inloggning-form [lösenord]": "" [Sida] http: //localhost/index-test.php/user/login [Response] 200 [Request Cookies] "_csrf": "dd395a9e5e3c08 cfb1615dae5fc7b5ba0a2025c003e430ba0139b300f4a917ada: 2: i: 0; s: 5: "_ csrf"; i: 1; s: 32: "QU9OhlK90Zc8GzEx59jkBjEIsAKmn-Q_"; " [Response Headers] " innehållstyp ": [" text / html ; charset = UTF-8 "] * Jag förväntar mig att se valideringsfel * Jag ser" Inloggningen kan inte vara tom. "* Jag ser" Lösenordet kan inte vara tomt ". * Jag ska försöka logga in med felaktiga uppgifter * Jag fyller fält "Inloggning [namn =" Inloggningsformulär [Inloggning] "]", "Admin" * Jag fyller fält "Inmatning [namn =" Inloggningsformulär [Lösenord] "]", "Fel" * Jag klickar på " lämna] "[Uri] http: //localhost/index-test.php/user/login [Metod] POST [Parametrar] "_csrf": "QjFBRl9hMjMTZHgJNw15CnJrIn4YG3dLdwgrLR0Ld3oxcAorMUxjbA ==", "inloggning-form [inloggning]":" admin " "inloggning-form [lösenord]": "fel" [Sida] 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] " content-Type ": [" text / html; charset = UTF-8 "] * Jag förväntar mig att se valideringsfel * Jag ser" Ogiltig inloggning eller lösenord "* Jag ska försöka logga in med rätt uppgifter * Jag fyller i fält" inmatning [name = "login-form [login ] "," admin "* Jag fyller i fält" inmatning [namn = "inloggningsformulär [lösenord]"] "," admin11 "* Jag klickar på" knappen [typ = inlämna] "[Uri] http: // localhost /index-test.php/user/login [Metod] POST [Parametrar] "_csrf": "bG8uMXdPYk49Ohd.HyMpd1w1TQkwNSc2WVZEWjUlJwcfLmVcGWIzEQ ==", "inloggning-form [inloggning]": "admin", "inloggning-form [lösenord] ":" admin11 " [Headers] " location ": [" http: //localhost/index-test.php ")," innehållstyp ": [" text / html; charset = UTF-8 "] [Sida] 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] " läge ": [" http: //localhost/index-test.php "]," content-type "[" text / html; charset = UTF-8 "] [Omdirigerar till http: //localhost/index-test.php [Sida] http: //localhost/index-test.php [Svar] 200 [Begär cookies] " _csrf ": "dd395a9e5e3c08cfb1615dae5fc7b5ba0a2025c003e430ba0139b300f4a917ada: 2: i: 0; s: 5:" _ csrf "; i: 1; s: 32:" QU9OhlK90Zc8GzEx59jkBjEIsAKmn-Q_ ";" [Response Headers] "content-type" html; charset = UTF-8 "] * Jag förväntar mig att se användarinformation * Jag ser" Logga ut "PASSED
Sammantaget är det lite att lära sig att komma igång med Codeception och korrekt koda dina test. Men resultaten är imponerande och hjälpsamma.
I grund och botten är enhetstestprogrammatisk provning av vår infrastruktur och modeller. Helst skulle vi skriva tester för varje metod och användningsvariation av våra modeller.
Tyvärr kunde jag inte få enhetstester för att fungera inom vårt träd på grund av antingen små Yii-fel som ännu inte skulle släppas eller konfigurationsproblem mellan Codeception och yii2-användare som vi integrerat i hur man programmerar med Yii2: Integrerar användarregistrering.
Enhetstester (3) --------------------------------------------- -------------------------------------------------- ----- Moduler: ------------------------------------------- -------------------------------------------------- ---------------------- Försöker testa inloggning ingen användare (test \ codeception \ unit \ models \ LoginFormTest :: testLoginNoUser) ...PHP Fatal Error 'yii \ base \ ErrorException' med meddelande 'Ring till odefinierade funktionstester \ codeception \ unit \ models \ expect ()'Jag ska ta upp enhetsprovning igen i vår Startup-serie som inte använder yii2-användaren, men använder istället Yii Advanced-trädets inbyggda användarintegration.
Låt oss titta på några exempel från Yii2-app-grundläggande trädet.
Testa kontaktformulär e-post
Hej / tester / koduppsättning / enhet / modeller / ContactFormTest.php tester skickar ett mail genom programmatisk användning av modeller:
mailer-> fileTransportCallback = funktion ($ mailer, $ message) return 'test_message.eml'; ; skyddad funktion tearDown () unlink ($ this-> getMessageFile ()); förälder :: nedkoppling (); public function testContact () $ model = $ this-> createMock ('app \ models \ ContactForm', ['validera']); $ Modell-> förväntar ($ this-> en gång ()) -> metod (validera) -> kommer ($ this-> returnValue (true)); $ model-> attributes = ['name' => 'Tester', 'email' => '[email protected]', 'subject' => 'mycket viktigt brev ämne', 'body' => ' meddelande ",]; $ Modell-> kontakt ('[email protected] '); $ this-> specificera ("e-post ska skickas", funktion () förvänta ("e-postfilen borde finnas", file_exists ($ this-> getMessageFile ())) -> true ();); $ this-> specificera ('Meddelandet ska innehålla korrekta data', funktion () använd ($ modell) $ emailMessage = file_get_contents ($ this-> getMessageFile ()); förvänta ("email ska innehålla användarnamn", $ emailMessage) -> innehåller ($ modell-> namn), förvänta ("e-post ska innehålla avsender email", $ emailMessage) -> innehåller ($ modell-> email); förvänta ("email ska innehålla ämne", $ emailMessage) ($ modell-> ämne); förvänta ("email should contain body", $ emailMessage) -> innehåller ($ model-> body);); privat funktion getMessageFile () returnera Yii :: getAlias (Yii :: $ app-> mailer-> fileTransportPath). '/Testing_message.eml';Jag kunde inte lyckas med att detta test passerar på grund av en liten bugg i Yii som inte har uppdaterats än (eller åtminstone kunde jag inte hitta den uppdaterade koden). Min droppe av Yii-kodbasen namngav utgående e-post med datumfrimärken och koden ovan letade efter ett fast filnamn. Således misslyckades det alltid. Ändå är det användbart att se hur programmatisk testning kan använda modeller för att skapa en fil och sedan leta efter den filen och validera innehållet för att verifiera att koden fungerar.
Testing Login
Låt oss titta på hej / tester / koduppsättning / enhet / modeller / LoginFormTest.php. Återigen gjorde min användning av yii2-användare det alltför svårt att integrera vid skrivningstillfället. Vi kan emellertid se på det begreppsmässiga tillvägagångssättet för enhetstestning av användarmodellfunktioner.
här är
testLoginCorrect ()
, som ser ut om inloggningen lyckas med ett korrekt lösenord:allmän funktion testLoginCorrect () $ model = nytt LoginForm (['användarnamn' => 'admin', 'lösenord' => 'admin11',]); $ this-> specificera ("användaren ska kunna logga in med rätt uppgifter", funktion () använd ($ modell) förvänta ("modell ska logga in användare", $ modell-> inloggning ()) -> true (); förvänta ("felmeddelandet ska inte anges", $ modell-> fel) -> hasntKey ("lösenord"); förvänta ("användaren ska vara inloggad", Yii :: $ app-> user-> isGuest) -> false (););Den använder
Inloggningsformulär
modell för att programmera loggat in användaren, och sedan ser det programmatiskt ut om Yii nuvarande användare inte längre är gäst.förvänta ("användaren ska vara inloggad", Yii :: $ app-> user-> isGuest) -> false ();Vad kommer härnäst?
Jag hoppas att du har tyckt om att lära sig Codeception och dess integration med Yii, trots några av de vägar som jag stötte på. Standardinstallationen av yii2-basic idag borde fungera bättre.
Om du vill läsa mer om hur du bestämmer när och vad som ska testas och varför rekommenderar jag att du läser Yiis testöversikt. Det finns säkert mer att lära sig om Codeception och skriva mer kompletta tester.
Titta på kommande tutorials i vår programmering med Yii2-serien när vi fortsätter att dyka in i olika aspekter av ramen. Om du vill veta när nästa Yii2 handledning kommer, följ mig @reifman på Twitter eller kolla min instruktörssida.
Du kanske också vill kolla in vår Bygga din start med PHP-serien, som använder Yii2s avancerade mall när vi bygger en verklig applikation. Faktum är att du kan prova startprogrammet, Mötesplanerare, idag.
relaterade länkar