pátek 10. srpna 2007

Implicitní versus Explicitní propagování kontextových informací v API

Článek jsem věnoval možnostem propagování kontextových informaci v API. Kontextové informace jsou většinou potřebné skrze všechny vrstvy aplikaci, jedná se například o identitu a role přihlášeného uživatele, vybraný locale apod. Pokud aplikace potřebuje kontextové informace, pak stojíme před otázkou jak je v API propagovat. V Jave máme dvě možnosti v podobě explicitního a implicitního propagování. Cílem článku je zrekapitulovat obě možnosti a poukázat na jejich výhody a nevýhody.

Protože je článek rozsáhlejší než bývá obvyklé pro formát tohoto blogu, zvolil jsem jeho publikaci v rámci aplikace Google Docs & Spreadsheets.

úterý 7. srpna 2007

OT: zvyšte si sebevědomí

Víte, jak se v programátorské branži honí sebevědomí? Čas od času reaktivujete váš životopis u personální agentury anebo na serveru s nabídkou práce. A většinou do jednoho až dvou dnů se vám někddo ozve s konkrétní nabídkou. Oblečete sako po dědečkovi, nazujete zánovní boty značky Prestige, nasosáte pár buzz words z profláknutých blogů a vyrazíte na pohovor.

Na pohovoru si vás nedjříve vezme do parády asistentka personálního oddělení, která vám vyjmenuje užásné benefity, které spolehlivě předčí ty vaše současné. Potom přijde nějaký šášula z developmentu a vy přehodíte pokec na buzz words, které jste viděli maximálně na papíře, který jste prolistovali během cesty přeplněnou sockou.

Ve většině případů je úspěch zaručen již před tímto pohovorem, protože akutní nedostatek lidí vede k tomu, že firmy berou každého vývojáře, který pozná rozdíl mezi anotací a konstruktorem. Hádankou typu Proč je poklop od kanálu kulatý? už vás dneska nikdo nezaskočí snad z obavy, aby vás to neodradilo.

Po absolvování pohovoru přichází toužebné očekávání nabídky, která skoro pokaždé dorazí. Sebevědomí je pohlazeno a chytře utrousená poznámka během oběda o vašem odchodu je dost pádný argument pro vašeho šéfa, aby přehodnotil přístup (finanční, karierní, dosaďte si co potřebujete) k vaší osobě.

Je pravda, že tenhle business funguje ve vztahu zaměstnanec-zaměstanvatel trochu obrácěně než býva zvykem, ale to vůbec není důvod, proč toho nevyužít.

Pokud potřebujete:

  • pohladit sebevědomí
  • pořádné argumenty na šéfa
  • získat dobrou nabídku a zkušenosti

Pak pošlete vaše CV na roman.pichlik zavináč hp.com, však my už si to tady v HP SOA Center nějak přebereme. A nebojte, nemorální jsou daleko horší věci ;-)...

pondělí 6. srpna 2007

CZ podcast volume #13 - novinky, Ruby a Ruby on Rails

A je to tu. Čekali jste dlouho, ale ne marně, podcast s pořadovým číslem třináct je venku. Doufejme, že stahovanost nesloží media server Sunu, kam jsme museli zmigrovat hosting, protože 400GB (měsíčně předplacených na Roumenově hostingu) přestávalo stačit.

JUnit 4.4 kladivo na testy

Kam až rozšiřovat možnosti testovacích frameworků? Tuhle otázka jsem si položil během zkoumání nedávno uvolněné verze 4.4 populárního frameworku pro psaní testů JUnit. Tato verze přináší dvě celkem zásadní novinky, první je assertThat a tou druhou, po mém soudu zajímavější, jsou předpoklady a teorie (assumptions and theories).

Obě novinky nejsou původně z dílny JUnit, ale jsou převzaté (absorbované se tomu teď říká ;-) z testovacího udělátka jMock resp. z Popper

assertThat

Nově připravená metoda assertThat dostává jako první argument aktuální hodnotu a jako druhý matcher (vyhodnocovač?), podle kterého se assert vyhodnotí. Pokud vám tahle definice zamotala hlavu, nevadí následující kód vše vrátí do správných kolejí.


assertThat(something, eq("Hello"));
assertThat(something, eq(true));
assertThat(something, isA(Color.class));
assertThat(something, contains("World"));
assertThat(myList, hasItem("3"));
    

Kromě toho, že je možné definovat si vlastní matchery, tak je lze také řetězit.

assertThat(something, not(contains("Cheese")));    
assertThat(responseString, either(containsString("color")).or(containsString("colour")));
    

Hlavní výhodou assertThat oproti původním assert metodám je lepší čitelnost, alespoň tedy v některý případech. Dalším plusem jsou implicitní zprávy při selhání testu.

assertThat(responseString, anyOf(containsString("color"), containsString("colour")));
// ==> failure message:
// java.lang.AssertionError: 
// Expected: (a string containing "color" or a string containing "colour")
//      got: "Please choose a font"    
    

Předpoklady a teorie

Předpoklady slouží k explicitnímu vyjádření podmínek, za jakých test musí projít. Takovou podmínkou může být například rozsah vstupních dat testu, dostupnost databázového připojení, nastavení určité systémové property. Tedy obecně závislostí mimo rozsah vlastního testu. Teorie se skládá s ze vstupních testovacích dat, předpokladu za kterého je schopen test s daty pracovat a vlastního testu.

Díky teorii může vývojář říci, za těchto a těchto vstupních podmínek se testovaný kód musí chovat takto. Právě díky podmínkám je možné nechat automatizované nástroje generovat vstupní data, která jdou za rozsah toho, jak by očekával vývojář případně toho, co by bylo pracné vyjádřit.

Malá citace z práce Davida Saffa a Marata Boshernitsana The Practice of Theories: Adding “For-all” Statements to “There-Exists” Tests.

Traditional unit tests in test-driven development compare a few concrete example executions against the developer’s definition of correct behavior. However, a developer knows more about how a program should behave than can be expressed through concrete examples. These general insights can be captured as theories, which precisely express software properties over potentially infinite sets of values. Combining tests with theories allows developers to say what they mean, and guarantee that their code is intuitively correct, with less effort. The consistent format of theories enables automatic tools to generate or discover values that violate these properties, discovering bugs that developers didn’t think to test for.

Jak taková teorie vypadá, ukazuje následující kód z dokumentace JUnit 4.4.


@RunWith(Theories.class)
public class UserTest {
  @DataPoint public static String GOOD_USERNAME = "optimus";
  @DataPoint public static String USERNAME_WITH_SLASH = "optimus/prime";

  @Theory public void filenameIncludesUsername(String username) {
    assumeThat(username, not(containsString("/")));
    assertThat(new User(username).configFileName(), containsString(username));
  }
}    
    

Anotace DataPoint definuje vstupní data teorie. Spouštěč testu krmí testovací metodu filenameIncludesUsername všemi kompatibilními (souhlasí datový typ proměnné a parametru testovací metody) veřejnými proměnnými, které jsou označeny anotací DataPoint. Předpoklad je vyjádřený pomocí assumeThat.

Celá teorie by se dala převyprávět asi takhle:Za předpokladu, že username neobsahuje /, musí platit, že jméno konfiguračního souboru uživatele obsahuje jméno daného uživatele.

Pokud je test spuštěn a nějaká vstupní data porušují definovaný předpoklad, jsou tiše ignorována. Takhle to sice stojí v dokumentaci, ale mě osobně to vždycky způsobilo, že test neprošel. Samozřejmě anotace DataPoint by nemusela být úplně vhodná pro generování vstupních dat a tak je možné naimplementovat potomka třídy ParameterSupplier.

Ač jsou třídy vztahující se k předpokladům a teoriím v package obsahujícím slovo experimental, přijde mi tento koncept jako v užitečný. Nebude sice automaticky aplikovatelný na všechny testy, ale pro některé typy testů bude představovat velký přínos. Typickým případem budou testy, kde potřebujeme větší rozsah a rozmanitost vstupních dat.