31 komentářů k článku Testování v PHP: tvorba testovatelného kódu II.:

  1. 5o

    Fajn článok
    Poučné, jedinú výhradu mám k metóde getLoader(), ktorá má parametre. Nie je to accessor a preto by som ju premenoval na createLoader().

  2. maryo

    Zapomenutý Dic
    V posledním bloku kódu je zapomenutý argument Dic.

    
     /**
      * @return Configuration_Loader
      * @throws InvalidArgumentException
      */
    


    public function getLoader($filename, Di $container)

    BTW. Já bych do tý factory ty Loadery registroval. Např. nějak takto.

    $factory->registerLoader('xml', new XmlLoader())

  3. maryo

    oprava
    Vlastně blbost :)… To už by nebyla žádná factory. Asi bych měl nějakej obecnej Loader a tam bych registroval jednotlivý dekodéry. A to bych naplnil třeba přes ten DIC pomocí tagů. Ale možná je to taky špatnej přístup (i když třeba v Symfony běžný), takový trochu programování v konfiguraci. Ale přijde mi to ifování trochu divný… No… to je jedno :).

  4. anti war

    logování všeho
    A jakou cestu autor preferuje pro logování korektních stavů aplikace? (často v Enterprise, např. záznam o provedené transakci, průběh interace, údaje pro ladění výkonu, přihlášení uživatele)
    Ono logovat chybové stavy je ještě snadné, ale jak nejlépe objektově a výkonově na logování všech stavů…

  5. honza

    Dependency Injection
    Díky za zajímavý seriál. Měl bych dotaz k Dependency Injection. Vyjdu z příkladu, kde je testovatelnost funkce GetLogger umožněna tím, že se Logger místo vytváření předává jako parametr. Tento krok je mi jasný, teď je možné tuto metodu lépe testovat. Neznamená to ale, že jsem problém místo vyřešení jen přesunul pomocí DI o úroveň výš? Ten Logger stejně musí někdo vyrobit, pokud to není volaná funkce, tak to bude volající, řekněme třeba nějaká funkce InitCosi, ve které chci GetLoader použit. Jak budu potom testovat tu? Nebudu mít při testování InitCosi stejný problém?

    1. Martin Mystik Jonáš

      Re: Dependency Injection
      Právě to přesunutí o úroveň výše je to na čem je DI postaveno. Jde o princip „mě je jedno jak, ale předej mi něco co můžu použít“. Odděluje vytváření objektů od jejich používání a tím separuje zodpovědnosti a snižuje provázanost a závislosti.

      Nakonec samozřejmě musí objekty někdo vytvářet. Při správném používání ale tato zodpovědnost probublá až úplně nahoru. Na nejvyšší úrovni je pak nějaký bootloader, init funkce nebo DI container, ať už to nazveme nebo uděláme jakkoliv a ta se stará o vytváření objektů.

      Protože ale jediné co toto „horní parto“ dělá je to vytváření objektů tak ho můžu mnohem snáze testovat. Jen ho požádám o vytvoření objektů a zkontroluju, že je udělala správně.

      1. honza

        Re: Dependency Injection
        Ok, to mi připadá logické. Ve složitějším systému si ale neumím moc představit, že by se nejdřív úplně všechno vyrobilo a pak se to „jen“ používalo.
        Spousta objektů musí vznikat za běhu podle aktuální situace a někdo je vytvářet musí – a takové místo pak tedy bude špatně testovatelné? Neumím si představit, že bych to dokázal omezit jen na jedno místo v aplikaci, protože to by mi pak vznikla ta (právem zavrhovaná) „univerzální factory“ na výrobu všeho.
        Nicméně zrovna v případě loggeru dává navrhovaný postup dobrý smysl.

        1. Martin Mystik Jonáš

          Re: Dependency Injection
          Pokud potřebuju objekty vytvářet za běhu tak se to řeší tak, že si injectuju továrnu, která mi ty objekty vytváří.

          Tj. na nejdříve opravdu sestavím úplně všechno včetně těch továren. A když za běhu potřebuju vyrobit nový objekt požádám o to továrnu. Na každý typ objektu můžu mít vlastní továrnu.

          Hlavní výhoda tohoto řešení je, pokud potřebuju změnit způsob jakým se objekty vytváří. Pokud používám továrnu provedu změnu jen na jednom místě – v továrně. Nebo pokud bysme chtěli držet i Open-closed priciple tak si vytvořím potomka továrny, který bude objekty vytvářet jinak. Pak jen na tom centrálním místě vyměním jednu továrnu za jinou.

          1. honza

            Re: Dependency Injection
            To zní rozumně. Akorát předpokládám, že to vede k tomu, že volání na vyšší úrovni pak mají obrovské množství parametrů, protože se jim musí dát všechny ty továrny a další singletony, aby je pak mohly injectovat postupně do dalších a dalších úrovní. Asi si to budu muset vyzkoušet, abych viděl, jestli to stojí za to, připadá mi, že to musí strašně znepřehlednit hlavičky metod.

            1. Martin Mystik Jonáš

              Re: Dependency Injection
              No to je druhá stránka věci – pokud mají jednotlivé součásti spousty parametrů tak je to často příznak nějakých chyb v návrhu. Ve výsledku nás používání DI vede i k návrhu s méně vazbami/méně parametry.

              Pak samozřejmě existují i jiný způsoby jak závislosti předávat – nejen přes konstruktor, ale i přes settery, public atributy, nějakou reflexion magic, …

              Pokročilejší DI kontejner pak zvládá i nějaký autowiring (sám ti injectuje podle nějakých podmínek zapsaných v konfiguraci/anotacích), …

              Doporučuju si nejdřív přečíst nějaké články přímo o DI než se do toho pustíš sám.

              Hezký jsou třeba články od Davida Grudla:
              http://phpfashion.com/co-je-dependency-injection

              Nebo zmiňvané články na zdrojáku od Vaška Purcharta:
              http://www.zdrojak.cz/serialy/jak-na-dependency-injection/

              1. honza

                Re: Dependency Injection
                Díky, kouknu na to. Takhle na první pohled mi to připadá, že řešením problému s předáváním příliš mnoha závislostí pomocí reflexe nebo autowiringu se dostávám tam, kde jsem byl na začátku před DI, tedy k obtížně testovatelnému kódu, ale nejdřív si přečtu odkazované články, třeba to má nějaké krásné jednoduché řešení.

                1. Yetty

                  Re: Dependency Injection
                  Ne, to nemá žádné krásné jednoduché řešení ;) Protože kdyby bylo, mohl by programovat každý. Naštěstí je nad tím potřeba ještě pořád přemýšlet. A tak je na programátorovi, jestli dokáže kód udržet *krásný* a *jednoduchý*. Metody jako DI k tomu mohou jenom pomoci. Ne jsou samospásné :)

  6. honza

    Konec?
    Ještě dotaz – tohle je konec seriálu? Nebude nějaké shrnutí nebo nějaká ukázka, jak se to použije v reálu?
    Hlavně jsem tak nějak pořád čekal na nějaké komplexnější testy, kterými dokážu opravdu pořádně otestovat, že metoda dělá to co má v různých připadech. Všechny ukázky zatím byly vždy jen „dej tenhle vstup, je výstup tohle – ok“. Předpokládal jsem, že to byly jen zjednodušené příklady a nějaký nezjednodušený příklad ještě přijde.

    1. Jan

      Re: Konec?
      Pořád hledáš nejjednodušší, nejlehčí řešení. Pořád čekáš, že ti někdo řekne, jak to máš dělat, jak máš testovat, nebo co? Pořád si něco neumíš představit něco ve složitějším případu, ale nemáš žádný příklad z praxe, protože seš nějaký teoretik, který testuje klikáním na webu, jak už víme z tvých „chytrých“ komentářů od prvního dílu, co se snažíš testování označovat za zbytečné a neužitečné. Radši si dál klikej a netestuj. Stejně univerzální návod na tvorbu testů neexistuje, ale ty tvoje komplexní testy určitě nehledej mezi unit testy (pokud dodržíš OOP návrh).

      1. honza

        Re: Konec?
        No, představoval jsem si něco jako že tomu dám sadu vstupů a sadu výstupů, nebo že to bude procházet v nějakém cyklu přes nějak definovanou množinu zadání nebo tak něco. S jedním vstupem a k němu odopvídajícím výstupem se opravdu nespokojím, protože to ve sktuečnosti nic netestuje, jak jsme viděli v jedné z ukázek v předchozích dílech. Asi jako kdybych měl funkci, na sčítání, která vždy vrací 4 a napsal si test ze vstupem 2+2. Ok, prošlo, odškrtnuto, vše funguje.

      2. pav

        Re: Konec?
        Pokud ten článek neměl za úkol pomoci čtenáři, proč tedy existuje?

        Souhlasím s předřečníkem. Tohle všechno se hezky čte, ale současně je toho na webu mraky. Nic reálně vypadajícího nebo obecného, jen silně specifické scénáře.

        Bohužel díky tomu je i pro mne seriál zklamáním. Dopadl dle očekávání: autor ukázal, že tomu rozumí, ti co to používají jásají, že proběhla osvěta, ale údajné cílové skupině to prakticky nic nedalo.

        1. arron

          Re: Konec?
          Ale jo, asi to chápu, protože podobně jsem začínal s unit testy já, ačkoliv mám torchu problém se do té doby zpětně vžít :-) Proto mám asi pocit, že bylo řečeno vše podstatné. Nicméně udělejme to jinak, pošlete mi třídu, kterou by sis představoval ukázat otestovanou a uvidíme, co se dá dělat (tomas.lembacher(at)gmail.com). :-)

        2. Honza Marek

          Re: Konec?
          Co si pamatuju, tak pro mě bylo kdysi velkým překvapením, že pokud chci mít testy, tak musím psát jinak vypadající a o dost jednodušší kód. Pak jsem se to rok učil a nakonec jsem zjistil, že to jde. Jediná cesta jak se to naučit je zkusit si to a vydržet, jen ze článků to nejde.

          1. arron

            Re: Konec?
            Jako jo. Nicméně já si vzpomínám na dobu, kdy jsem si kladl podobné otázky. „Jak to mám sakra udělat, když všude jsou jenom takový stupidní příklady???“ Takže říkám ok, pokud mi někdo pošle nějaký vhodný kus kódu, který považuje za dostatečně komplexní, tak se pokusím napsat článek. Zatím se na to každý tak maximálně vyprdnul ;-)

        3. Petr

          Re: Konec?
          Serial skoncil, uz zbyva jej jen poplivat… Jak typicky ceske… Co se namisto „hejtovani“ pokusit treba o pokracovani, hm?

    2. arron

      Re: Konec?
      Ale vždyť přece minulý a tento díl seriálu byly už docela zajímavými ukázkami ne? Ve složitějších případech se testy jenom trochu rozrostou, nic víc :-) Pak něco jiného je, když jsou někde nějaké staticky volané metody apod. (obecně těžko testovatelné věci), ale to už pak není o testování, ale o refaktorování. Chce to jistou praxi, aby člověk věděl co s tím udělat tak, aby se to vůbec dalo otestovat, ale není to zase tak těžký a nelogický. Hlavně v tom nehledat zbytečné složitosti. Stějně je to jenom o tom, že si udělám mock závislostí, připravím si nějaká data, nastavím nějaká očekávání (expect), zavolám testovanou metodu a pak si ověřím, že se stalo to, co se stát mělo. Nic složitějšího v tom není potřeba hledat :-)

  7. Rob

    Jak napsat testy pro funkci jejíž výsledek může být z velké množiny hodnot ?
    Je to asi trochu OT, ale s testováním to rozhodně souvisí.
    Jak napsat testy když správných výsledků může být celá řada? Konkrétně – chtěl jsme napsat zvýrazňovač kódu ….
    Jenže třeba již na jednoduchý vstup typu:
    echo ‚aaa‘;
    může být správným výstupem třeba:
    1. echo ‚aaa‘;
    Nebo
    2. echo ‚aaa‘
    a spousta dalších včetně variant class=“xx yy“ kontra class=“yy xx“

    Prohlížeč prostě všechny tyto HTML fragmenty zobrazí stejně – takže podle mě správný výsledek.
    Náhodně si vybrat jeden konkrétní HTML tvar správného výsledku a ten se snažit naprogramovat podle mě není zrovna šťastný přístup, protože se v průběhu programování může zjistit, že tvorba regexp zrovna pro tento tvar je 10x složitější (a on je v provozu mnohem pomalejší) než by byla nějaká jiná varianta.
    Ale přepisovat předpokládaný výsledek testu uprostřed práce, asi také není to správné.

    1. Rob

      Re: Jak napsat testy pro funkci jejíž výsledek může být z velké množiny hodnot ?
      Mělo tam být: (místo špičatých závorek dávám hranaté)
      1. [SPAN class=“phplang“][SPAN class=“phpkw“]echo[/SPAN] [SPAN class=“phpstr“]echo[/SPAN][/SPAN]
      2. [SPAN class=“phplang phpkw“]echo[/SPAN][SPAN class=“phplang“] [/SPAN][SPAN class=“phplang phpstr“]echo[/SPAN]

      Omlouvám se za chybné zadání… neuvědomil jsme si, že lze zapisovat přímo HTML kód.

  8. failer

    5 operací
    Je na čase trochu změnit přístup. Základem jsou vždy data. A základní otázka zní: Kterých 5 základních operací provádíme nad daty? Nemusí se vždy používat všechny. Osobně jsem nenarazil na případ, kdy bych nad nimi dělal něco jiného. Proč se ptám? S tímto přístupem je to strašně ukecané a začíná tím podle mne vznikat špageta. A kdo to má dokumentovat…

Napsat komentář

Tato diskuse je již příliš stará, pravděpodobně již vám nikdo neodpoví. Pokud se chcete na něco zeptat, použijte diskusní server Devel.cz

Zdroj: https://www.zdrojak.cz/?p=7247