Automatické testování odeslání emailu

Jistě jste také už mnohokrát, stejně jako já, řešili problém, jak spolehlivě automaticky otestovat, že vaše aplikace správně odeslala email s konkrétním obsahem na konkrétní emailovou adresu. Problém je to zapeklitý a dosud jsem ho dokázal řešit jen těmito způsoby:

  • udáním testovací schránky a automatickým výběrem této schránky (např. přes protokol POP3)
  • vytvořením mock objektu, který mi zastoupil třídu starající se o odeslání emailu (tzn. k žádnému emailu fyzicky v testu nedošlo)

Oba dva přístupy mají svá úskalí. Ten první velmi komplikuje běh testu - musíme naprogramovat další funkcionalitu, která nám vybere emaily jiným protokolem, musíme řešit možnost, že se email někde pozdrží, musíme fyzicky nějakou schránku mít, musíme vyřešit to, jak při opakovaném spouštění testů rozeznáme, že do schránky přišel právě ten mail, na kterém v testu čekáme. Fakticky se potom často stane, že v testu samotném je víc chyb, jak v tom jednoduchém kódu, který se snažíme otestovat.

Druhý přístup je jednodušší a test s ním obvykle po vyladění spolehlivě prochází. Nicméně tento přístup nezaručuje, že v reálném nasazení,kdy místo mock objektu, bude skutečný objekt zajišťujicí odeslání emailu nedojde k chybě (např. díky tomu, že náš mock objekt nedostatečně dobře imituje chování reálného objektu).

Do této doby jsem tedy odesílání emailů ověřoval “ručně”. Automatické testy sice odesílaly emaily, ale ty šly na moji schránku a v ní jsem zkontroloval, jestli očekávaný email v očekávané době došel. Skvělá věc, když spouštíte testy ručně, ovšem horší v případě, že vám testy spouští integrační server. To se vaše schránka pěkně plní a vy stejně nemáte šanci vyhodnotit, zda je vše jak má.

SubEthaSMTP Server

A nyní přichází rozřešení mého dlouholetého problému. SubEthaSMTP Server je SMTP server napsaný v Javě, který má integrovanou podporu pro jednoduché testování a ten můj problém vyřešil.

V celém řešení není žádná záhada, fígl nebo vychytávka. V rámci svého testu si normálně spustíte vlastní instanci SMTP Serveru, která se bindne na konkrétní port a chová se jako klasický SMTP Server. Váš kód tedy fakticky email odešle - jen máte SMTP Server pod svojí kontrolou. Z instance SMTP Serveru si maily můžete jednoduše vyzvednout a nějak je zpracovat. V testech obvykle stačí jen ověřit, že nějaké došly a případně proklepnout jejich obsah.

Krásné na tom celém je to, že nasazení je naprosto směšně jednoduché. Stačí vám k tomu jen tyto věci:

  • k projektu přilinkovat Wiser z projektu SubEthaMail - pro Maven 2 projekty stačí přidat dependency:
  • pak už stačí jen napsat test:

Prosté a funkční. Na tento způsob jsem narazil v článku Using Groovy to send email na OnJava - možná jej řada z vás k testování této funkcionality používá, ale pro mne to byla cenná novinka.

Podělte se s ostatními:
  • Digg
  • del.icio.us
  • De.lirio.us
  • Technorati
Ohodnoťte článek:
Takovéhle články už radši ne!Nic nového pod sluncem.Průměr - obsahuje zajímavé střípky informací.Hodnotný článek - lecos nového jsem se dozvěděl.Skvělý článek - informace se mi dost hodí. (1 hlasů, průměrně: 5 z 5)
Loading ... Loading ...

7 reakcí to “Automatické testování odeslání emailu”

  1. Petr Ferschmann:

    Díky za tip. Tohle je jedna z těch věcí, které kdyby člověka napadly, že jdou takto dělat, už to dávno používá. Díky za otevření očí :-)

  2. Novoj:

    JJ, měl jsem úplně stejný pocit, když jsem to na OnJava objevil ;).

  3. Roman Dagi Pichlik:

    Presne tenhle pristup ukazuje, ze kdyz vyvojar chce, tak muze automaticky testovat prakitcky jakoukoliv cast sveho kodu a to i v pripade integracniho scenare s posilanim mailu. Skoda,ze ochota vyvojaru hledat reseni pro automatcike testy, jako je treba tento, je mala. Kazdopadne diky, az mi zase nekdo bude tvrdit, jak je tezke neco podobneho testovat, tak mu tenhle clanek omplatim o hlavu ;-).

  4. Jety:

    Díky za užitečnou věcičku. Škoda, že zrovna teď nepotřebuju žádné odesílání otestovat, hned bych si to vyzkoušel. Však to časem určitě příjde :).

  5. Lukas:

    Testovat odesilani emailu je krehkou zalezitosti, jako kazda jina komunikace se singletonem. Ten samy problem muze nasta pri komunikaci pres FTP napr.

  6. Novoj:

    Ano je to tak. Nicméně tento způsob se mi zdá poměrně stabilní a přesto vypovídající. Otázka je, jestli neexistuje v Javě také nějaká lightweight in memory implementace pro FTP stejně jako SubEthaSMTP Server pro maily. Pak by i pro FTP existovala rozumná cesta pro testování.

  7. Roman Dagi Pichlik:

    to Lukas> urcite mi to prijde lepsi nez vyuziti mocku ci stubu, protoze ty mohou zvalidovat ciste jenom operaci, ale ne spravnost vysledku.

  8. benzin:

    Coz jaksi nepomuze, protoze v realnem nasazeni muze napriklad dojit k tomu, ze nastavite SMTP server u ktereho druhy den spravce omezi pristum jenom na urcite IP adresy. Nebo Vas zkusebni SMTP server nevyvolava nektere vyjimky, ktere pak realny server vyvolat muze. Atp. atd.

    A cim se vlastne podstatne lisi tento vas SMTP server od Mock objektu? Nejedna se vlastne jenom o sofistifikovany Mock objekt?

    Tim nechci rict, ze by tento clanek nebyl prinosny. Urcite je super, ze jste informoval o teto moznosti, jenom chci upozornit ze se jedna o sofistifikovany Mock objekt a v realnem nasazeni, muze vyvstat spousta dalsich problemu.

    Btw. ja takoveto problemy resim pouzitim prislusneho API, otestovani API a spoelhnutim na spravnost API. Tudiz napriklad na E-mail pouzivam springframwork, na to mam udelane testy. V aplikaci pak mockuju objekty tohoto api, ktere jsou vyrazne jednodussi.

    Protoze pouzite API sprigframeworku pozivam v stale stejne verzi, nejsem nucen delat testy na neho automatizovane, tak jak je tomu v aplikaci.

  9. Novoj:

    No především SubEthaMail reálně implementuje SMTP protokol - tudíž pokud vám test projde, znamená to, že vaše aplikace odesílá emaily validně podle SMTP protokolu. Nastavení serveru je stejně věc, kterou v testovacím provozu odchytit nemůžete.

    Wiser je defakto mock objekt - takže se od mock objektu nijak neliší. Na Wiseru vidím dvě základní výhody:

    a) je to mock, který nemusíte psát - protože je už dobře napsán
    b) testuje druhou stranu rozhraní - tzn. otestuje vám, že jste skutečně správně odeslali email SMTP protokolem
    c) je to mock, který není závislý na implementaci odesílací strany rozhraní

    Taky používám SpringFramework, ale než si psát své mocky, radši použiji tenhle.

Nechte zde svůj komentář

Opište prosím text z obrázku: