Unit testy s knihovnou EasyMock

Možná jsem někde zaspal, ale knihovnu EasyMock jsem začal používat teprve nedávno u nás ve firmě. Jeho schopnosti a snadnost použití jsou tak výrazné, že rozhodně stojí za představení.

K čemu je to vlastně dobré

EasyMock je pomocník pro psaní unit testů. Unit testy slouží k otestování jedné třídy. Nezajímají nás objekty, se kterými testovaná třída spolupracuje. Buď věříme tomu, že fungují správně…a nebo tyto závislosti namockujeme.

Namocková je nahrazení skutečných spolupracujících tříd tzv mocky. Mock je proxy implementující určitý interface. U této proxy máme možnost nadefinovat její chování programově pomocí API.

Jak to funguje

  1. Vytvoříte mock objekt (1. řádek kódu)
  2. Nadefinujete jeho chování (včetně návratových typů a výjímek)
  3. Nadefinujete požadované volání metod (EasyMock kontroluje i jejich pořadí)
  4. Přepnete se do přehrávací fáze
  5. Spustíte vlastní unit test
  6. EasyMock za vás ověří, že byly splněny všechny podmínky nadefinované v bodě 2 a 3

EasyMock se velmi hodí tam, kde používáte návrhový vzor IoC a potřebujete otestovat beanu, která potřebuje mít nasetované reference na ostatní beany. Ideálně, když referencované beany jsou interfacy (EasyMock umí mockovat pomocí rozšížení i classy). Pomocí EasyMocku si tedy vytvoříte přislušné mocky, nahrajete jejich chování. Zavoláte testovanou metodu a Easymock zkontroluje, zda všechno proběhlo podle vašich požadavků.

Malá ukázka testu z příkladu (EasyMockDemo­.zip, ZIP 260 KB): .

public class TestServiceImplTest extends TestCase {
        private TestServiceImpl testServiceImpl;
        private TestDao testDao;

        public void test_getBeanById_ok() throws Exception {
                Bean bean1 = new Bean();
                bean1.setId(1);

                EasyMock.expect(testDao.getBeanById(1)).andReturn(bean1);

                replay();

                Bean bean = testServiceImpl.getBeanById(1);
                assertEquals(1, bean.getId());

                verify();
        }

        public void test_getBeanById_null_returned() throws Exception {
                EasyMock.expect(testDao.getBeanById(1)).andReturn(null);

                replay();

                Bean bean = testServiceImpl.getBeanById(1);
                assertNull(bean);

                verify();
        }

        public void test_getBeanById_exception_thrown() throws Exception {
                Bean bean1 = new Bean();
                bean1.setId(1);

                EasyMock.expect(testDao.getBeanById(1)).andThrow(new DaoException("Some DAO exception"));

                replay();

                try {
                        testServiceImpl.getBeanById(1);
                        fail();
                } catch (ServiceException e) {

                }

                verify();
        }

        protected void replay() {
                EasyMock.replay(testDao);
        }

        protected void verify() {
                EasyMock.verify(testDao);
        }

        @Override
        protected void setUp() throws Exception {
                super.setUp();
                testServiceImpl = new TestServiceImpl();
                testDao = EasyMock.createMock(TestDao.class);
                testServiceImpl.setTestDao(testDao);
        }

        @Override
        protected void tearDown() throws Exception {
                super.tearDown();
                testServiceImpl = null;
                testDao = null;
        }
}

Závěr

Bez mock testů si dnes unit testy už nedovedu představit.

Odkazy

Celý článek 4 komentářů 21. October 2008

Google Chrome

„Ten blog Ti ňák chcípá“, řekl minulý týden kamarád Abe.

Tak…veselý začátek by byl a teď ke Google Chrome :)

Google mě zase překvapil. Vypustil do světa skvělý prohlížeč. Bez chyb samozřejmě není, ale výčet kladů a věcí, které mě příjemně překvapily přebývá. Google Chrome používám necelý týden od středy 3. září 2008 kdy byl uvolněn. Zde je seznam věcí, kterých jsem si všiml (klady, zápory, poznámky):

  • Začnu záporem – chtěl jsem v Chrome napsat tento článek, ale měl jsem smůlu. Používám Wordpress (verze 2.0.2) a v administrátorské části pro psaní příspěvku jsem měl v pravé části všechny boxy zavřené. Nešla tak vybrat například rubrika a další věci.
  • Na druhou stranu – V jedné diskusi o Chrome jsem četl, že v něm nefungují Mapy.cz. Hned jsem to zkusil a fungovalo to. Vývojáři z Googlu zřejmě dostaly nahlášený bug a během několika hodin ho fixli. Takže myslím, že můj problém s Wordpressem bude během několika hodiny také vyřešen (bug jsem zareportoval).
  • Jako primárná prohlížeč jsem používal Operu. Chrome si od ní hodně vypůjčil – klávesové zkratky, náhledy s nejnavštěvo­vanějšími stránkami, chytrá adresová řádka.
  • Je to pekelně rychlý. Před několika týdny jsem si s fanfárou stáhnul Firefox 3. Ten je ve srovnání s Chrome kulhající dědeček. Rozdíl v rychlosti je asi dvojnásobný. Ne jenom v načítání stránek, ale mám pocit, ze i flash má mnohem rychlejší odezvu na pohyb myší například.
  • Přechod na Chrome je bezbolestný. Nevím jak to přesně popsat. Ale člověk v něm nic nemusí hledat všechno funguje. Stánky jako by se zobrazoly už po naťukání prvních písmen do adresního řádku. Jediné co mi trošilinku chybí jsou mouse gestures, na které jsem zvyklý z Opery.
  • Chrome není paměťžrout jako Firefox. Nebudete mi věřit – kolega z práce, který má počítač puštěný v kuse 3 týdny (nerad restartuje) má spotřebu paměti Firefoxem cca 800 MB (čtete správně). Po upgradu a používání v tom samém stylu práce spotřeba „klesla“ na 500 MB. A to má otevřeno pár záložek (max 10). Chrome běží sice ve více procesech, ale hospodaření s pamětí je efektivnější. Zavřená záložka = ukončení procesu a komplentí uvolnění paměti.
  • Ovládací prvká zabírají (stejně jako u Opery) minimální místo. Nahore najdete pruh záložek a pod ním pruh s adresovým řádkem. To je vše. Žádná menu nebo lišta bookmarků.
  • Chytnete záložku, vytáhnete kousek stranou a máte ji v samostatném okně.
  • Zavřené záložky jdou znovu zobrazit (stejně jako v Opeře) klávesovou zkratkou CRTL+SHIFT+T.

Vytahnutí záložky

A nové okno z vytažené záložky

Závěr

Určitě se podívete na komiks.

Odkazy

Celý článek 8 komentářů 9. September 2008

Reverse Ajax s DWR, Spring, iBatis

Před nějakým časem se v Avedyi rozjížděl nový projekt. Jednalo se o klasický webový chat. Vytvořil jsem tehdy jednoduchý prototyp. Použil jsem DWR a technologii reverse ajax.

Pro tento článek jsem původní prototyp trochu rozšířil a zapojil jsem Spring Framework a jako DAO vrstvu jsem vybral iBatis.

Krátce o iBatisu

I když iBatis není plnotučné ORM s klidem bych ho nasadil na většinu projektů, na které jsem v minulosti použil Hibernate. Stručný přehled vlastností a featur iBatisu:

  • Konfigurace v XML podobně jako Hibernate.
  • Veškeré SQL příkazy (insert, update, select) jsou nadefinovány přímo v XML konfigurácích. V nich definujete placeholdery, které jsou při vykonávání nahrazeny skutečnými hodnotami.
  • Umí relace (1:1, 1:n, m:n)
  • má vlastní kešování (kongurace opět v xml)

iBatis mě nadchnul a původně jsem o něm chtěl napsat krátký článek. Ale když jsem viděl kolik zdrojů na (i českém) internetu je rozmyslel jsem si to. Seznam zdrojů o iBatisu uvádím na konci článku.

Krátce o DWR

O DWR jsem z na blogu již psal. V tomto článku bych se blížeji podíval pouze na typy reverse ajaxu, které nabízí.

Full Streaming Mode

Nejrychlejší způsob reverse ajaxu. Spojení zůstává otevřeno po dobu 60 sekund. Poté je vytvořeno nové (což se nemusí podařit pokud browser již není otevřený např). Má dvě nevýhody:

  • velká zátěž serveru (při velkém počtu klientů)
  • proxy, antivirové program a různé moduly webserveru mohou držet data do doby než se spojení ukončí (k zobrazování dat by pak docházelo pouze jednou za 60 sekund)

Early Closing Mode (Long Polling)

Funguje tak, že server zavře spojení s klientem a vyžádá si spojení nové v případě, že klientovi posíláme nějaká data. Jestliže data neposíláme je chování stejné jako u Full Streaming modu. Spojení s klientem není uzavřeno ihned, ale lze jej konfigurovat pomocí parametru maxWaitAfterWri­te. Typicky napstaveno na 500 ms. Server v tomto případě pošle klientovi zprávu, počtu 500 ms a poté ukončí a znovu otevře spojení s klientem.

Výhodou je odolnost vůči držení dat na straně proxy atd. Nevýhodou je opět velká zátěž serveru.

Polling Mode

Polling Mode bych pravým reverse ajaxem ani nenazýval. Spočívá v periodickém dotazování serveru klientem. Směr volání je klient → server, což je opakem předchozích dvou možností.

Full Streaming Mode je představitelem technologie Comet – tzv. spojení mezi serverem a klientem s dlouhou délkou života.

Příklad

Příkladem je jednochuchý chat. Základní usecasy jsou:

  • nalogování uživatele
  • zjištění aktuálního uživatele ze session
  • odlogování
  • poslání nového vzkazu (buď všem v chatu nebo jednomu adresátovi)

Klient

Klientem je statická html stránka (index.html), která dělá dotazy na server pomocí js souboru. V něm je volán DWR servlet. Pro komfort při práci se stránou je použita i knihovna jQuery.

Server

Serverovou částí je javovská webové aplikace běžící v libovolném servlet kontajneru. Jediným endpointem je DWR servlet. Jako IOC kontajner je použit Spring Framework. Obsahuje jednu remotnutou servisní beanu – chatService. Jsou zde dva doménové objekty – User a Message.

Soubor dwr.xml obsahující konfiguraci remotnuté servisy a bean convertor pro doménové objekty:

<dwr>
  <allow>
    <!-- configure service -->
    <create creator="spring" javascript="ChatService" scope="application">
      <param name="beanName" value="chatService"/>
    </create>

    <!-- configuje bean converter -->
    <convert converter="bean" match="cz.vavru.test.dwr.domain.*"/>
  </allow>
</dwr>

Soubor Message.xml s iBatis mapováním:

<sqlMap namespace="Message">
  <typeAlias alias="message" type="cz.vavru.test.dwr.domain.Message"/>

  <resultMap id="result" class="message">
    <result property="messageId" column="messageId"/>
    <result property="date" column="date" />
    <result property="message" column="message"/>
    <result property="sender.userId" column="senderId"/>
    <result property="sender.nick" column="senderNick"/>
    <result property="recipient.userId" column="recipientId"/>
    <result property="recipient.nick" column="recipientNick"/>
  </resultMap>

  <select id="getMessages" resultMap="result">
    select * from Message where recipientId is null or senderId = #userId# or recipientId = #userId#
  </select>

  <insert id="insertMessage">
    insert into Message set date = #date#, senderId = #sender.userId#, senderNick = #sender.nick#, recipientId = #recipient.userId#, recipientNick = #recipient.nick#, message = #message#
        <selectKey resultClass="int" keyProperty="messageId">
      select last_insert_id() as messageId
    </selectKey>
  </insert>
</sqlMap>

Metoda getScriptSessi­onsToNotifyAbou­tNewMessage z třídy cz.vavru.test­.dwr.util.DwrWeb­ContextUtil. Úkolem metody je vrátit kolekci objektů ScriptSession, které mají být notifikovány o nově příchozí zprávě. Jak je z kódu vidět v případě, že je vybraný adresář je notifikace poslána jenom odesílateli nebo adresátovi. Proměnná webCtx je interface org.directwebre­moting.WebCon­text obsahují např odkaz na aktuální ScriptSession (obdoba HttpSession). Na rozdíl od HttpSession vzniká nová ScriptSession s každým obnovením stránky (F5 v prohlížeči). Ohromnou výhodou tohoto objektu je možnost uložit si do něj libovolný atribut. Já do něj při zalogování ukládám informace o uživateli. A tak později přesně vím, které scriptsešný mám zavolat:

@SuppressWarnings("unchecked")
public Collection<ScriptSession> getScriptSessionsToNotifyAboutNewMessage(Message message) {
        Collection<ScriptSession> pageScriptSessions = (Collection<ScriptSession>) webCtx
                        .getScriptSessionsByPage(currentPage);

        Collection<ScriptSession> scriptSessions = new ArrayList<ScriptSession>();

        if (message.getRecipient() != null) {
                for (Iterator<ScriptSession> it = pageScriptSessions.iterator(); it.hasNext();) {
                        ScriptSession scriptSession = it.next();
                        User user = (User) scriptSession.getAttribute(ChatServiceImpl.SCRIPT_CHAT_USER_SES_ATTR);
                        if(user == null) continue;

                        if (message.getSender().getUserId() == user.getUserId()
                                        || message.getRecipient().getUserId() == user.getUserId()) {
                                scriptSessions.add(scriptSession);
                        }
                }
        } else {
                scriptSessions = pageScriptSessions;
        }

        return scriptSessions;
}

Posledním fragmentem kódu je metoda addMessage z třídy cz.vavru.test­.dwr.service.Chat­ServiceImpl.

@Transactional
public void addMessage(Message message) throws ChatServiceException {
        WebContext webCtx = WebContextFactory.get();
        // zjisteni aktualniho usera ze session
        User currentUser = (User) webCtx.getHttpServletRequest().getSession(true).getAttribute(
                        CHAT_USER_SES_ATTR);

        // nastaveni odesilatele a data
        message.setSender(currentUser);
        message.setDate(new Date());

        // vlozeni message do databaze
        messageDao.insertMessage(message);

        DwrWebContextUtil dwrUtil = new DwrWebContextUtil(WebContextFactory.get());
        // zjisteni vsech scriptsession, ktere mame notifikovat o nove zprave
        Collection<ScriptSession> scriptSessions = dwrUtil
                        .getScriptSessionsToNotifyAboutNewMessage(message);

        logger.info("Sending info about new message to " + scriptSessions.size() + " users");

        Util util = new Util(scriptSessions);
        // timto zpusobem se vola primo kod na strane klienta
        // nasledujici radek tedy zavola javascriptovou funkci addMessage (viz soubor js/chat.js) s parametrem message
        // objekt message, ze samozrejme preveden do javascriptoveho sveta
        util.addFunctionCall("addMessage", message);
}

Celý příklad lze stáhnout zde – dwr-ajax.zip (zip, 9.9 MB). Archiv obsahuje:

  • zdrojové soubory (celý Eclipse projekt)
  • dwr-ajax.sql s DDL
  • war archiv

Závěr

Věřím, že se mi povedlo ukázat jak je spojení všech použitých knihoven naprosto bezbolestné a jednoduché. Při testech na mém notebooku, kdy jsem si v každém prohlížeči (IE, Opera, Mozilla) otevřel chat a vstoupil pod jiným uživatelem, byl celý chat pekelně rychlý. Zpráva byla zobrazena takřka okamžitě.

Odkazy

Celý článek Přidat komentář 6. July 2008

Poslední středa

Ani nechci hledat, kdy jsem na blogu zveřejnil nějaký článek. Uplynula už dlouhá doba. Důvod této přestávky byl jednoduchý – naše Lucy. Naší holčičce jsou už více jak dva měsíce a já se snažím být s ní každou volnou chvilku.

Dnešní den byl výjimka. Byl jsem na semináři Poslední středa, který pořádá každou poslední středu v měsíci firma H1. Tématem červnového setkání byl affiliate marketing.

Byl jsem tam jako zástupce našeho eshopu VaseCocky.cz a překvapilo mě, že ho někteří účastníci semináře již znali.

O programu

Chvíli před sedmou hodinou večerní, kdy měl seminář začít, se spustila venku doslova apokalypsa. Tak vydatný déšť jsem dlouho neviděl. Po výstupu z tramvaje na Karlově náměstí jsem byl v několika sekunách promočený na kůži. Na přechodech jsem se brodil po kotníky ve vodě (ještě, že jsem měl sandály).

To byl asi důvod proč na seminář nedorazili všichni objednaní. Odhaduji, že nás tam bylo celkem cca 20. Včetně 5 lidí z H1.

Na začátku promluvil Václav Štrupl de facto o tom, že pro dnešek není připravena žádná úvodní řeč. A tak se přešlo rovnou k volné diskusi. Nebo spíše k části „questions and answers“. Nejdříve probíhala společná diskuse na téma affiliate marketing, a pak se diskutovalo v menších skupinkách.

Občas se téma nedrželo striktně pouze affiliate marketingu, ale sklouzlo se i na jiná témate – konverzní poměr, PPC reklamy, bannerové reklamy.

Kolem 22.30 setkání skončilo.

Závěr

Rozhodně to nebyl ztracený čas. Pokud bude v budoucnosti zajímavé téma, rád seminář znovu navštívím.

Celý článek Přidat komentář 25. June 2008

Narodila se nám Lucy

V pondělí 21. dubna 2008 se nám narodila krásná holčička Lucie. Při narození měřila 50 cm a vážila 3.5 kg.

Lucy už má svojí e-mailovou schránku. Takže když ji budete chtít něco napsat použijte lucie@vavru.cz :)

Kačenka s Lucy poprvé

Kačenka s Lucy podruhé

Já s Lucy

Celý článek 10 komentářů 22. April 2008

Google Chart API

Chcete mít ve své webové aplikaci základní (a dokonce krásné) grafy? S Google Chart API a návodem v tomto článku je to skutečně otázka několika minut.

Jak Google Chart API funguje

Jako všechny věci od Googlu jsou i Chart API extrémně jednoduché na používání. Graf na stránce je obrázek. Jediné co musíte udělat je sestavit URL grafu. V něm schováte všechny parametry grafu:

  • jeho typ
  • rozměry
  • titulek
  • pole hodnot

Vše je výborně popsáno v dokumentaci i jinde (dokonce na českém webu) – Vylepšené Google Chart API nabízí nové grafy a žádné limity, Google Chart API: Jak jednoduše na grafy?, Grafy od Googlu snadno a rychle, Google Chart API – dynamické grafy na webu.

S PHP knihovnou gchart grafy za pár minut

Důvodem proč píšů tenhle článek je PHP knihovny gchart. Vznešené slovo knihovna v praxi znamená jeden PHP soubor. V něm naleznete API umožňující používat Google Chart API bez jakéhokoliv studování jeho dokumentace.

A to byl zrovna můj případ – potřeboval jsem si udělat pro náš eshop grafy tržeb – abysme viděli jak úžasně rosteme :). Přičemž jsem nechtěl strávit na tvorbou grafů a studováním Google Chart API více než 10 minut.

Podařilo se. Knihovna gchart není sice závratně úžasný kousek kódu, ale čas šetří…a o to v naší branži také jde.

Celý článek 4 komentářů 20. April 2008

Kterak se krade design

Při projíždění refererů našeho eshopu www.vasecocky.cz jsem zjistil přístup z domény, jejíž jméno neuvedu, není důležité jim dělat reklamu.

Jdu tam a hádejte co – vidím náš eshop, přesněji náš design. Mám unikátní příležitost vidět chování zlodějů designu v praxi. Stránka byla totiž nedokončená. I neváhal jsem a udělal si první screenshot. Za pár dní jsem se vrátil, abych pořídil design další – kucí (takhle domácky jim s kolegou říkáme) totiž ve své práci pokročili. První screenshot jsem pořídil 13. března. Následující pak 17. března.

Bohužel s tím od té doby kucí :) nepohnuli a mně se nechce čekat. Takže tady ty dva screenshoty máte. Schválně zkuste porovnat a naším eshopem.

A jak že jsem na to přišel – no kucí nechali v HTML kódu stránky naše počítadla z toplistu a Google Analytics.

Závěr

Bude to asi znít divně. Měl bych asi nadávat jak moc špatní ty kucí jsou. Neučiníím tak. Názor si udělejte sami. Mně osobně to tak nějak těší – to je převládající pocit. Je to přece poklona pro nás – hlavně pro našeho grafika Aba (čti Ejba). Fuj to ale samozřejmě je.

Celý článek 10 komentářů 19. April 2008

Jak jsem (ne)pochopil REST

S křížkem po funusu ale přece! V tomto článku bych chtěl několika větami okomentovat :lednovou přednášku":http://www­.java.cz/deta­il.do?… Jakuba Podlešáka Java API pro RESTful web services. Po obyčejném blogování se mi už pekelně stýskalo. Od půlky prosince totiž nedělám nic jiného než že se snažím přivést k životu naše kontaktní čočky.

REST

REST chápu jako soubor pravidel pro manipulaci s daty po síti (zpravidla pomocí HTTP protokolu). V RESTu se pracuje se resourci – zdroji. Každý zdroj má svoji unikátní adresu. Pomocí volání adresy zdroje s ním lze provádět operace. Od prostého načtení po vytvoření, modifikaci až po smazání. Kromě zavolání zdroje pomocí adresy (URL) lze do těla požadavku zabalit další data – například pro vytvoření nového zdroje. Data mohou být v různé formě – např XML, JSON, plain text…

REST naopak nedefinuje autentizaci a autorizaci uživatelů. REST je bezstavový.

Jak je to s tou stavovostí RESTu?

A právě o stavovosti RESTu bych se chtěl zamyslet. Na přednášce proběhla vášnivá debata na téma stavovost RESTu. Padly zde názory, že když pracuju s webovou aplikací používající REST a uložím nový zdroj, tak se přece musí jednat o stavové chování. Vždyť se přece změnil stav aplikace.

Výše uvedený názor je nesmysl. Se stavovostí RESTu je to stejně jako se stavostí HTTP protokolu – je nestavový. Uvedu na jednoduchém příkladu. Tím příkladem jsou sessions.

Příklad se sessions

Sessions fungují tak, že server přibalí do odpovědi klienta unikátní idenfikátor, který označuje session id. Toto cookies se pak přenáší při další komunikaci mezi serverem a klientem. Klient session id přibaluje buď do:

  • URL
  • POST dat
  • cookies

A naprosto stejně to funguje i s RESTem. Když budeme mít resource na adrese http://vavru.cz/eshop/vyt­vorit-kosik/, může odpověď vypada například takto – http://vavru.cz/eshop/ko­sik/wsdei9012309a­/. Dostali jsme zpět adresu na nově vytvořený košík. Když pak klient chce s tím to košíkem (každý klient má svůj košík) musí uvést celou adresu košíku. Takže pro přidání nové položky bychom mohli použít například takovýhle odkaz – http://vavru.cz/eshop/ko­sik/wsdei9012309a­/pridat-produkt/ a v těle požadavku specifikovat o jaký produkt se jedná a například počet kusů.

Zdá se vám to jednoduché?

Mně taky. Proto nechápu tolik případů nepochopení ze strany posluchačů. Možná jsem to celé jenom špatně pochopil a chyba je na mé straně. V tom případě prosím nějakého zkušeného RESTovače, aby mě například pomocí komentáře přivedl na správnou cestu.

Celý článek 12 komentářů 28. February 2008

Jak jsme rozjeli VašeČočky.cz

Snad nikdy v životě jsem nestrávil tolik času prací u počítače jako poslední tři týdny. V tomto krátkém čase jsem vdechnul život eshopu VaseCocky.cz – najdete ho na adrese www.vasecocky.cz.

Nemějte strach, že tohle bude nějaký PR článek. Žádné vyjmenovávání úžasných vlastností eshopu, velkých slev apod. Pouze chci popsat jaké ty poslední tři týdny byly. Jednoduše co obnášelo vytvoření a zprovoznění našeho ehopu.

Myslím, že lze těžko nalézt článek, který se by se více hodil na osobní blog, než je právě tento.

Proč kontaktní čočky?

Nikdy v životě jsem nebyl klasickým zaměstnancem. Jako kontaktor jsem posledních 6 let pracoval převážně pro dvě firmy, ale měl jsem i svoje menší soukromé projekty. Nemám rád nedostatek motivace. Životní styl, kdy člověk chodí do nějaké práce, tam 8 hodin něco dělá, a poté se sebere a jede domů. Vidím to všude kolem sebe. Je tu hodně lidí, kteří svoji práci nemají rádi. Píšu to, protože když jste někde zaměstnaný často časem zjistíte, že vlastně stačí, když toho budete dělat o mnoho méně – že to vlastně stačí. A když je nějaký problém, tak jej stačí vhodně okomentovat a poslat odpovědnost za problém o dům dál. Opět jsou to věci, které jsem viděl kolem sebe.

Léta jsem se snažil pracovat nejlépe jak jsem uměl. Snad jsem se za tu dobu i něco naučil. A teď od 1. ledna 2008 přišel přelom. V nové práci teď používám jenom Javu – všechny ostatní moje stávající znalosti zde přímo neuplatním. Mluvím např. o – PHP, ActionScript, AJAX, XHTML, CSS, C#. Nechtělo se mi tyhle znalosti zahodit. Chtěl jsem je dále využívat. A nejlépe tak, že tentokrát nebudu nic programovat pro zákazníky, nýbrž pro sebe.

Již velmi záhy co jsem začal programovat, jsem chtěl mít svojí firmu – software faktory. Dělat weby na zakázku. Postupně jsem tuto myšlenku opustil. Jedna věc je totiž dělat skvělé weby, a zcela jiná (důležitější), je nalézt zákazníky. A právě kvůli tomu jsem si na konec rozmyslel risk v podobě založení firmy, najmutí alespoň jednoho zaměstnance, kanceláří.

Na podzim jsem na setkání spolužáků ze střední školy vedl debatu s Martinem Bláhou na téma založení vlastní firmy. Martin už sice vlastní firmu na vedení účetnictví, ale rád by se vrhnul i do nečeho jiného.

Netrvalo to ani tři týdny a už jsme měli založenou firmu – její jméno je Maternia (webová prezentace se připravuje). V tuto chvíli jsme ještě vůbec netušili co vlastně budeme dělat. Pouze jsme věřili svým schopnostem. Věřili jsme tomu, že jsme schopni se v téhle republice v něčem prosadit. No vlastně naše slova byla ještě mnohem odvážnější :)

V říjnu, listopadu a prosinci jsme učinili několik schůzek, abychom vymysleli, co vlastně bude Maternia dělat. Během prvních schůzek jsme si ujasnili hrubý záměr firmy – chceme něco prodávat na internetu. Toto rozhodnutí mělo tyto základní důvody:

  • Já umím udělat internetový obchod na míru (což považujeme za velkou konkurenční výhodu proti polovičatým univerzálním shopům)
  • Umím zajistit všechno ostatní co s tím souvicí – domény, hosting, reklama…
  • Martin a jeho účetní firma nám může hravě vést účetnictví

Ohromnou výhodou je, že základní věci si umíme udělat sami.

Dostali jsme se do momentu, kdy jsme už jistě věděli, že chceme něco prodávat na internetu, ale ještě jsme něvědeli co.

Padlo spousta nápadů (ty jsou součástí firemního knowhow a nemůžu je prozrazovat :)). Vítězem se nakonec staly kontaktní čočky. Po analýze internetového trhu s kontaktními čočkami jsme jednoduše věřili, že jsme schopni udělat internetový obchod, který bude mít spoustu předností oproti stávajícím eshopům.

V podstatě se dá říci, že zde nebyl žádný internetový obchod s kontaktními čočkami, který by vytvořili profesionálové. Kdyby jsme byly v jiném článku, tak bych uvedl výčet chyb, které mám na mysli. Ale v tomto kontextu by to nebylo fair.

Proč Vaše kontaktní čočky?

Název Vaše kontaktní čočky se nám zdál jako nejlepší z ještě volných domén. To byste nevěřili pro jaké všechny varianty slovního spojení kontaktní čočky jsou obsazené domény. Úplně pro všechny varianty :). Koupili jsme tedy www.vasecocky.cz, variantu s pomlčkou www.vase-cocky.cz a také dvě delší varianty www.vase-kontaktni-cocky.cz a www.vasekontak­tnicocky.cz.

Pár slov o našem eshopu

Chtěli jsme vytvořit eshop, kde by skvěle nakupovalo. Soustředili jsme se zejména na:

Jednoduchý a přehledný design stránek
Méně je často více. Proto na stránky nedáváme zbytečné prvky. Při procesu odeslání objednávky dokonce není zobrazen ani sloupec menu s kategoriemi, protože v té chvílí je nepodstatný. Design má na svědomí skvělý grafik Abe.
Jasnou navigaci a ovládání
Přehledné hlavní a pomocné menu, vhodné nadpisy, vhodné titulky stránek, vhodné url – to všechno jsou věci, kterým jsme věnovali velkou pozornost.
Intuitivní práci s nákupním košíkem
Košík jsme navrhovali s ohledem na intuitivnost ovládání. Proto jsme použili stejně velké písmo jako v ostatním textu (stávající eshopy často používají nečitelné pidipísmo). V košíku lze přidávat (klonovat produkty), odebírat produkty, měnit parametry a množství produktu pomocí AJAXu. Je to velmi rychlé. O výsledku všech těchto akcích je nakupující upozorněn barevnou hláškou.
Citlivé použití AJAXu
Doufáme, že dobrým příkladem je právě popsaná funkce košíku. Dále na stránkách máme Srovnání produktů. Poslední AJAXovou featurou, o které se chci zmínit, je zjišťování aktuálního stavu dané varianty produktu na skladě. Lze ji nalézt na stránce s detailem produktu (např zde – Precision UV (6 čoček)).
Co nejpříjemnější proces odeslání objednávky
Proč by se měl zákazník před odesláním objednávky zaregistrovat? Tuto povinnou registraci najdete na většině eshopů. V našem eshopu nic jako registrace neexistuje. Během objednávky je nutno zadat jenom údaje, které jsou skutečně potřeba. Při osobním odběru zboží je to pouze jméno zákazníka a jeho telefonní číslo (abychom ho mohli upozornit že si může objednávku vyzvednout). I pokud se jedná o jiný druh doručení, při kterém je potřeba vyplnit adresu. Například nevyžadujeme vyplnění e-mailu. Pouze zákazníka upozorníme, že když ho vyplní bude mu zřízen přístup do klientské sekce, kde bude moci sledovat aktuální stav svých objednávek.

Co mi zabralo nejvíce času

Není nad to, když si člověk může projít naprosto všemi cykly tvorby webu:

  • analýza trhu a zvolení podnikatelského záměru
  • návrh fungování webu
  • implementace webu
  • testování webu
  • provoz webu a reklama

Nejvíce času mi zabral druhý bod – návrh fungování webu. Pročetl jsem snad desítky článků na téma přístupnosti. Například i bakalářskou práci Martina Snížka Postup tvorby obchodně úspěšného webu.

Samotná implementace byla ta nejzábavnější část práce na projektu. S dnešními nástroji (Eclipse IDE počínaje a Zend Frameworkem konče) je to opravdu radost.

Pečlivě jsme se věnovali i uživatelskému testování. Měli jsme asi 10 testerů. Byly to lidé z rodiny nebo přátelé. Hodně z nich jsou potencionální zákazníci (nosí kontaktní čočky).

Web je nyní již v provozu a všechen svůj volný čas teď věnuju propagaci. Seznamuju se s reklamními systémy, registruju web do katalogů, do agregátorů zboží.

Na čem je to celé postavené

Eshop je postaven od nuly. Použili jsme:

Závěr

Těžko v souvislosti s naším webem hovořit o nějakém závěru. Ty bude možné udělat až po nějaké větší době provozu. V tuto chvílí nejsme ani týden po releasu.

PS: Objednávky už chodí :)

Celý článek 18 komentářů 10. February 2008

Zajímavé linky 14 - Boulder2ME, obchodně úspěšný web, Czech PHP User Group, Proč ZF

Po delší době se ozývám s dalším článkem. Možná jste si všimli menší frekvence nových článku na blogu. Rozhodně to nebude tím, že bych zlenivěl nebo že by mě to prostě přestalo bavit. Důvodů je několik:

  • Nástup do Avedye je pro mě pořádný kotrmelec. Poprvé v životě jsem javista „na plný úvazek“ a dává mi to teď na začátku hodně zabrat. V Avedyi jsou skvělí kolegové a práce je náročná – a proto ji mám rád.
  • Věc, která mi zabírá poslední měsíc všechen volný čas je internetový business, který se chystáme s kolegou z naší firmy rozjet již za pár dní. Jak jste si mohli všimnout v CV založil jsem s kamarádem firmičku s názvem Maternia. Rád bych se rozepsal o našem podnikání, ale nechci to dělat v tomhle článku. Tato naše nová „zábava“ stála už tým o velikosti 5 lidí měsíc života.

Zajímavé odkazy

Už jsem toho o sobě navykládal dost. A teď už ke slibovaným linkům, které jsou tentokrát vyjíměčně zajímavé:

  • Kolega Honza Šmuk spustil nový web Boulder2ME. Web umožňuje pomocí appletu nadefinovat vlastní mapy do této hry a pak si je stáhnout přímo do mobilního telefonu jako JAD a případně JAR soubor.
  • Velezajímavým dílem je bakalářská práce Martina Snížka s názvem TVORBA OBCHODNĚ ÚSPĚŠNÉHO WEBU, na kterou můžete najít odkaz ke stažení v článku Postup tvorby obchodně úspěšného webu. I když není obsah práce z mého mateřské oboru s velkým zájmem jsem si ji na jeden zátah přečetl. Nezabere to ani dvě hodinky. Při jejím čtení jsem zjistil, že jsem při rozjíždění našeho nového internetového businessu nepostupoval uplně špatně. Našel jsem tam i spoustu užitečných rad. Pokud jste v situaci že přemýšlíte o rozjetí webové stránky a pro vás z nějakého důvodu důležitý její obchodní výsledek je tato práce z rodiny MUST READ.
  • Proběhla druhá akce pod hlavičkou Czech PHP User Group Shrnutí konference zima 2008. Navíc se připravuje akce třetí – Třetí a poslední konference php frameworky.
  • Pěknou úvahu napsal Ronnie v článku Proč si vybrat Zend Framework a proč nevytvářet vlastní framework.

Závěr

Podle analýzy návštěvnosti jsem si všimnul že jste si všimli obráceného pořadí zobrazených článků. Nejstarší články jednoduše byly zobrazeny jako první. I jal jsem se vyzkoumat příčinu…Používám snad nejrozšířenější bloggerský CMS WordPress a nechtělo se mi věřit v nějaký bug na jeho straně. Spíš jsem věřil v útok hackera :) Jaké je rozuzlení? Český hosting nasadil do produkce novou verzi MySQL, která správně nepracovala s klauzulí GROUP BY.

Celý článek Přidat komentář 3. February 2008

Novější články Starší články


Kategorie

Odkazy

Zdroje

Locations of visitors to this page