čtvrtek 20. dubna 2017

How to join strings with separator

import com.google.common.base.Joiner;
 
public static void main(final String[] args) {
  final String output = Joiner.on(", ").join("white", "blue", "red", "black");
  System.out.println("output = " + output);        
}
output = white, blue, red, black

pondělí 21. listopadu 2016

Peníze v Javě


Tentokrát bych chtěl rozebrat možnosti a moje zkušenosti, jak v kódu nakládat s penězi.

Datový typ - BigDecimal


Pro ukládání částky je rozhodně nutné používat datový typ BigDecimal  Jedině ten zaručuje, že nebude docházet k nečekanému zaokrouhlování za desetinou čárkou. BigDecimal snese v podstatě libovolnou přesnost a velikost čísla. Rozhodně nepoužívejte datové typy typu Float nebo Double.

Setkal jsem se i s aplikací, kde částky byly uchovávány jako celé číslo. Pro zobrazení se pak musela desetinná čárka uměle posouvat, tak aby dávala obsahově smysl. Fungovalo to dobře, ale myslím, že už je to přežité. Použil bych tento přístup jen v programovacím jazyku, který nemá BigDecimal alternativu.

Třída BigDecimal je immutable, takže se s instancemi ve vícevláknovém běhu pracuje bezpečně. Poskytuje všechny základní operace jako je sčítání, násobení a zaokrouhlování.

Identifikace měny


Peníze jsou ale ve skutečnosti dvojicí částky a měny.  Třídu, která by ale skládala dohromady částku a měnu přímo v JDK nemáme. Pokud máte částku a víte že jde o nějaké peníze, ale nevíte v jaké měně, tak je to docela problém.

public class Product {
    private final Long productId;
    private final String name;
    private final BigDecimal price; // What currency is it ?

    public Product(final Long productId, 
                   final String name, 
                   final BigDecimal price) {

        this.productId = productId;
        this.name = name;
        this.price = price;
    }
    // geters …
}

Třídu pro měnu máme v Javě už od verze 1.4 -  Currency. Rozšířit entitu o další atribut by neměl být problém.

public class Product {
    private final Long productId;
    private final String name;
    private final BigDecimal price;
    private final Currency currency;

    public Product(final Long productId, 
                   final String name, 
                   final BigDecimal price, 
                   final Currency currency) {

        this.productId = productId;
        this.name = name;
        this.price = price;
        this.currency = currency;
    }

    // geters …
}

Pokud v jedné entitě máte více cen - např. prodejní, nákupní, apod. Duplikují se vám dvojice částka a měna a poměrně snadno při použití může dojít k tomu, že částky a měny poplete. Musíte také ohlídat, aby byla vždy zadaná celá dvojice. Pokud dovolíte zadat částku bez měny, opět je to problém.

Joda Money

Problém neexistence třídy pro peníze vyřešil Stephen Colebourne, mimochodem autor populární knihovny JodaTime. Naimplementoval knihovnou pod názvem Joda-Money. Ta obsahuje třídu jak pro měnu - CurrencyUnit tak pro magickou dvojici částka, měna - a to hned ve dvou různých třídách Money a BigMoney

Money je třída, která agreguje  dvojici částka (jako BigDecimal) a měna (jako CurrencyUnit). Navíc hlídá počet desetinných míst pro danou měnu. Třída BigMoney poskytuje vše co Money, ale nehlídá počet míst za desetinou čárkou pro danou měnu. To se hodí, pokud vám částky přicházejí ze zdroje, který nemáte úplně pod kontrolou. Konverze mezi oběma typy je samozřejmě přímočará.  Obě třídy jsou immutable, takže opět bezpečné pro práci ve vícevláknovém prostředí. 

Upravený příklad vypadá takto.

public class Product {
    private final Long productId;
    private final String name;
    private final Money price;
    
    public Product(final Long productId, 
                   final String name, 
                   final Money price) {

        this.productId = productId;
        this.name = name;
        this.price = price;
    }

    // geters ... 
}

Závěr

Pokud pracujete v rámci programu s penězi, doporučuji určitě zahrnout do projektu o jednu závislost navíc a důsledně používat datový typ Money resp. BigMoney, místo dvou nezávislých atributů pro částku a pro měnu. Předcházíte tak riziku, že atributy prohodíte. Navíc je kód mírně přehlednější. Líbí se mi i že místo obecného typu pro číslo použit naprosto konkrétní pro peníze.


čtvrtek 18. srpna 2016

Mockování emailové komunikace v integračních testech

Na projektu JdemeNaTo jsme narazili na problém, jak v selenium integračních testech pracovat s emaily.

Testovaná aplikace posílá emaily přes SMTP protokol. Test je pak musí přečíst a zpracovat. Samozřejmě, že email jako takový se nesmí dostat ven z integračního prostředí.

Poměrně dlouhou dobu jsme používali jednoduché řešení Dumbster. To spočívalo v tom, že si test vytvořil při svém spuštění mock SMTP server na dohodnutém portu, a test si pak přímo přečetl příchozí mail. Po skončení testu se port zase uzavřel.

Toto řešení jsme museli ale opustit v době, kdy máme celé integrační prostředí postavené na dockeru. Testy pouštíme stále pomocí mavenu na TeamCity proti testovanému serveru hostovaném v docker kontejneru. Každý docker kontejner má svoji ip adresu a namá ponětí o tom, kdo ho volá.

Hledali jsme vhodnou náhradu za Dumbster a našli jsme překvapivě robustní implementaci v javě GreenMail, který je určený právě pro testovací účely. Sympatická je i velká variabilita nasazení - poskytují docker image, tak i standalone aplikaci či jako war do Tomcatu. Na straně posílání mailů jsme nemuseli udělat žádnou úpravu. Na straně čtení jsme si napsali jednoduchou rutinu založenou na POP3 protokolu.

Pokud hledáte řešení, jak mockovat email server v interačních testech, mohu GreenMail určitě doporučit.

sobota 17. ledna 2015

Code coverage of Selenium tests in TeamCity

There are couples of tools, which measure code coverage in java - cobertura, emma, jacoco.
They work pretty well for regular unit tests.

But how to measure code coverage of integration tests?

Here is my solution

All integration tests are written in Java - jUnit and Selenium WebDriver API - run by standard maven-failsafe-plugin. Application is deployed on Tomcat by TeamCity. Integration tests are run by TeamCity also.

If you run Tomcat with JaCoCo agent, you can measure code coverage on the Tomcat side.

This is part of Tomcat setenv.sh file

CATALINA_OPTS="-Xms512m -Xmx8g -XX:MaxPermSize=1024m -server -javaagent:/opt/tomcat1/org.jacoco.agent-0.7.2.201409121644-runtime.jar=output=tcpserver,address=localhost,port=6300"

After run all integration tests may TeamCity ask for results by jacoco-maven-plugin. It connects to Tomcat by TCP and saves result localy to jaacoco.exec file.

mvn jacoco:dump

TeamCity supports import javacoco result file by service massages. I added a regular command line build step. Service message should be printed into a standard output stream of the build; hence I used linux echo command. Unfortunately, single quote must by surround by double quote.

echo \##teamcity[jacocoReport dataPath="'"target/jacoco.exec"'" includes="'"com.jpower8.*"'" excludes="'"com.jpower8.*.*Test"'"]

Additional tab with coverage results appears in build detail.

neděle 23. listopadu 2014

DevFest 2014

Po letech v dejvickém kampusu. Padla na mě nostalgie. Národní technická knihovna z venku super. Fakulta stavební byla pro mě ale premiéra.

1. Rachel Simpson - Unboxing UX: Design prototyping for Engineers 

Výborná přednáška o UX designu pro vývojáře. Doporučovala k prostudování Steve Krug - Rocket Surgery Made EasyPro rychlé prototypování používá tužku a papír. To pak vyfotí a rozpohybuje v aplikaci POP. Přímo na přednášce jsem zkoušel a vypadá to super. Ohledně UX testování pouštěla vtipné video - The scrollwheel.  Doporučuji projít si i portfolio autorky. 

2. Mirek Černý - How to become a world-class startup

Mluvil o své firmě futurelytics. O té jsem nic nevěděl. Dostali se přes seedcamp do ameriky, kde dostali investici. Doporučoval naučit se prezentovat svůj nápad během 30s - elevator pitch. V česku doporučoval Credo Ventures a v Americe Index Ventures. Podíl investorů prý běžně bývá kolem 10%. U odměňování spolupracovníků a zaměstnanců preferuje opční plán.

3. Filip Hráček - Plymer.dart

Prezentoval použití google technologií na datech z městské knihovny, s cílem doporučit knihu z vypůjčení. Troufl si na živé demo, které se povedlo. Inspiraci bral z amazonu a z knížky Programming Collective Intelligence. Programování v Polymer.dart mi hodně připomínalo Tapestry

4. Firma

Dva bloky přednášek, kde Mirek Černý z futurelytics, Marie Chytilová se slevomatu, Ondřej Krátký z Liftago a Daniel Franc z googlu radili se zakládáním a provozem firmy. Účastníci si představili v hlavě svoji firmu a odpovídali na otázky. Některé odpovědi pak panelisti rozebírali.
Celkově bych tento blok hodnotil kladně, i když zůstalo jen u naprostých základů.

Po přednášce panelisti nabízeli krátkou individuální konzultaci, čehož jsem využil. 

5. Vojtěch Bárta - Kvalita jako odpovědnost celého týmu

Vojta pracuje jako QA ve firmě Vendavo. Ukazoval, jaké jsou problémy s kvalitou ve vodopádu i v agilním světě. Pro mě to bylo spíš jen opáčko toho, co už jsem věděl. 

6. Věrka Koukalová - Monetizace aplikace

Přednášející prezentovala, jaké jsou možnosti vydělat na aplikaci umístěnou v google play nebo app store. Přednáška byla celkem vtipná, ale mě posloužila hlavně pro utříbení myšlenek, kudy se nevydávat. 

7. Tomáš Holas - Firemní kultura

Definoval co to je firemní kultura jako
Systém psaných i nepsanách konvencí které ovlivňují jakým způsobem se lidé staví k řešení probéml a jak se k sobě navzájem chovají. 
 Porovnával zkušenosti z korporací, ze startupu a svobodné firmy. Přednáška byla překvapivě vtipná.