Monthly Archives: December 2008

Christmasing-Holidaying

Te słowotwórcze potworki w tytule tego wpisu doskonale oddają mój stan od kilku dni, a co więcej, będą dalej go uosabiać do 7 stycznia kiedy to po dłuuuuugiej przerwie pojawię się w pracy. Okazuje się, że nawał pracy przed świętami jest dobry, bo wyrobione wówczas nadgodziny można spożytkować w bardzo przyjemny sposób – na przykład mając możliwość pójścia na długi urlop. Na blogu nie piszę zasadniczo o niczym innym jak Java i pokrewne technologie, ale święta i urlopy to wyjątek.

Zatem zacznijmy od najważniejszego – życzę wszystkim czytelnikom mojego bloga (oj a naprawdę jest ich całkiem sporo, co mnie cieszy niepomiernie) spokojnych świąt i szczęśliwego nowego roku. Wiem, że podobne słowa krzyczą obecnie z każdego miejsca (nawet w lodówce :), ale pragnę zapewnić, że są to życzenia szczere i płynące z dobrego serca. Obyście mogli w spokoju wypocząć i nacieszyć się życiem, niezależnie czy uznajecie te święta czy nie. To raz.

Dwa, że znowu znikam na jakiś czas. Konkretnie – na czas urlopu. Wizyta w domu rodzinnym, a potem zapakunek do samochodu i wyprawa w kierunku Świeradowa-Zdrój, gdzie wraz z przyjaciółmi wybieram się w okresie sylwestrowo-noworocznym na narty. Czyli znowu góry, podobnie zresztą jak latem, ale kilka kilometrów na zachód od Szklarskiej Poręby. Na nartach ostatni raz jeździłem w liceum (tzw. zielone szkoły), czas zatem sobie po tych 6 latach przypomnieć o co w tym sporcie chodzi. Mam nadzieję, że nic się nie stanie, tym bardziej, że biorę żonę, która na nartach jeszcze nigdy nie jeździła 🙂 Do Warszawy wrócę 6 stycznia – i w okolicach tego dnia należy spodziewać się kolejnych wpisów.

Co do przyszłości – rysuje się ona w dość ciekawych kolorach. Jak tylko znajdę chwilkę czasu by wydać wersję 0.2 ChlebikClient zaczną się wpisy na temat J2EE, póki co głównie o JSP i servletach, z czasem pójdziemy dalej. Przy poprzednim urlopie zapowiadałem, że zacznę cykl o pisaniu systemu blogowego w JSP, ale czas i okoliczności zrewidowały te zamierzenia na rzecz Swinga i klienta do Arkadia MUD. Jednakże może to i dobrze? Zobaczymy co czas przyniesie, póki co kiełkuje u mnie powoli ciekawy pomysł na cykl artykułów, a także będący ich rezultatem portal.

Trzymajcie się ciepło.

Advertisements

Wierzchołek góry lodowej czyli Java i XML

O tym, że XML w świecie internetu odgrywa rolę fundamentalną nie muszę chyba nikogo przekonywać. O tym, że podobna sytuacja ma miejsce w przypadku Javy wiedziałem już wcześniej, choć dopiero lektura opisywanej ostatnio książki pokazała, że XML jest de facto standardem przyjętym w świecie Javy jeśli chodzi o konfigurację oraz przesyłanie danych. W kolejnej wersji ChlebikClient konfiguracja będzie w związku z tym oparta na plikach XML. Są one o tyle fajne, że ich edycja jest banalna, zaś jeśli chodzi o obsługę programową to mnogość narzędzi jest przytłaczająca.

W swojej aplikacji postanowiłem użyć powszechnie znanej biblioteki Dom4j. Umożliwia ona operowanie na plikach XML oferując API, które jest cokolwiek bardziej użyteczne niż te oferowane przez SAX, który jest niskopoziomowym API dla XMLa w Javie opartym na sterowaniu zdarzeniami. Odczyt pliku XMLa w przypadku dom4j jest banalny.

Podstawowym obiektem, na którym przyjdzie nam operować to org.dom4j.Element – jest to interfejs, który implementuje sporo klas z tego pakietu.

Załóżmy, że mamy plik XML z 2 elementami, w ktorych do tego mamy 2 potomków. Czyli np. element “wyszukiwarki” z dwoma potomkami (onet i google), a do tego też element “portale” z znów dwoma potomkami (interia i gazeta). Odczytanie tego pliku i zapisanie węzłów do LinkedHashSet można zrealizować tak (obiekt document jest instancją klasy org.dom4j.document, która reprezentuje cały wczytany plik XML):

org.dom4j.Element root = document.getRootElement();
LinkedHashSet listaWartosci = new LinkedHashSet();

for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
DefaultElement element = (DefaultElement) i.next();
listaWartosci.add(element);
}

Proste? A pewnie, że proste. Choć to oczywiście wierzchołek góry lodowej jak mówi tytuł wpisu – o XMLu i Javie z pewnością jeszcze napiszę.

W końcu dobra książka

Ano to prawda. Nareszcie w Polsce ukazała się pozycja, która nie jest głębokim opisem języka, ale też nie jest szczegółowym opisem jednej z dostępnych technologii. Mowa o “Eclipse Web Tools Platform”, którą to dziś przez zupełny przypadek znalazłem w Empiku. Zdziwienie moje było tym większe, iż z ofertą wydawnictwa Helion staram się być w miarę na bieżąco, a o tej pozycji jakoś nic nie wiedziałem. Powód mej niewiedzy był prozaiczny – ktoś tę cenną pozycję wrzucił do działu ‘JavaScript’… Pozostawię bez komentarza.

No ale do rzeczy. Książka kosztuje jak typowa pozycja dotycząca Javy, czyli sporo (okrągłe 99 zł). Ale już po pobieżnym przejrzeniu wiedziałem, że na pewno nie będzie to chybiona inwestycja. O czym traktuje ta książeczka? Ano kilka osób tworzących WTP, czyli rozszerzenie Eclipse’a wspomagające budowanie aplikacji webowych i EE, wzięło się za napisanie na ten temat książki. I trafili w dziesiątkę (przynajmniej według mnie), gdyż do tej pory w naszym kraju nie było równie fajnej pozycji, która pokazywałaby proces tworzenia aplikacji tego typu od podstaw i z użyciem konkretnego narzędzia. Co więcej – poruszone są wszystkie zagadnienia szeroko pojętego J2EE – servlety, bazy, XML, webservices. Cud, miód i orzeszki. Wracam do lektury – mam nadzieję, że zaowocuje ona kilkoma wpisami na blogu.

TDD czyli programowanie sterowane testami

Każdy kto w programistycznych kręgach obraca się pewien czas, prędzej lub później natknął się na pojęcie Test driven development/programming. Jest to tzw. programowanie sterowane testami – metodologia (metoda?) programowania opierająca się na idei, iż przed napisaniem kodu należy utworzyć stosowne testy, które umożliwią sprawdzenie działania kodu, który dopiero zamierzamy napisać. Zatem jajko czy kura?

Po więcej szczegółów zapraszam do wikipedii. Metoda ta potrafi być naprawdę przydatna i pozwala na pisanie lepszego kodu, a także na sprawniejsze nim zarządzanie. W tym wpisie zaprezentuję wzięty z życia przykład TDD, a także mini-HOWTO szkieletu JUnit NetBeans. Zatem do dzieła.

Do napisania jest kawałek kodu, którego celem jest:

– otworzenie pliku tekstowego

– wgranie jego zawartości do zmiennej

– wyświetlenie zawartości na ekran

Rzecz prosta i zasadniczo głównie to, co może się zakończyć niepowodzeniem to pierwszy punkt, co zresztą implikuje powodzenie lub niepowodzenie działań z punktów kolejnych. Mamy taką listę rzeczy do zrobienia, zatem przed napisaniem kodu zastanówmy się co może pójść nie tak:

– plik może nie istnieć

– możemy nie mieć uprawnień do jego odczytu

– plik może okazać się po prostu pusty

– wczytanie z pliku może zakończyć się niepowodzeniem

W naszym projekcie klasy realizującej odczyt z pliku dzięki powyższej liście rysuje się wygląd poszczególnych metod, choć w zasadzie to potrzebujemy raptem jedną 🙂  Możnaby stworzyć kilka metod, które wykonywałyby się jedna po drugiej, uzależniając swe wykonanie od powodzenia poprzedniej. Czyli mielibyśmy jakieś fileExists(), potem pewnie isReadable(), zaś na końcu ReadFile() i być może jeszcze fileClose(). Kilka z tych metod zaimplementujemy.

Najbardziej popularnym szkieletem (frameworkiem) używanym do przeprowadzania testów jednostkowych, jest JUnit. Standardowo jest on dodawany do NetBeans, zatem stworzenie testów dla projektu tworzonego w tym IDE jest naprawdę szybkie i bezbolesne. W saym JUnit wszystkie klasy testujące inne klasy, muszą dziedziczyć po klasie TestCase z tegoż frameworka (to dla wersji 3.x). NetBeans umożliwia automatyczne wygenerowanie testów dla już istniejącej klasy w zaledwie kilka chwil. Tutaj mała uwaga. Istnieją różnice między kolejnymi wersjami JUnitNetBeans w wersji 6.1, na której pracuję dawał możliwość wyboru pomiędzy stylami 3.x i 4.x.  Różnica jest zasadniczo dość istotna – w wersji 3.x każda klasa testująca musi dziedziczyć swoją funkcjonalność po klasie TestUnit, a także trzymać się konwencji nazewniczych (dodawania suffixu -Test do nazwy każdej metody). W wersji 4.x wykorzystywany jest mechanizm asercji , więcej na temat różnic pomiędzy wersją 3.x, a 4.x można znaleźć tutaj.

Wiadomo już zatem o co mniej więcej się rozchodzi. Napiszmy zatem klasę, która zawiera interesujące nas metody:

public class ChlebikConfigChangelog {

private StringBuilder content = new StringBuilder();
private FileReader filereader;

public void loadFile(String fileName) throws FileNotFoundException
{
filereader = new FileReader(fileName);
}

public String readFile() throws IOException
{

String s;
BufferedReader br = new BufferedReader(filereader);

while((s = br.readLine()) != null)
{
System.out.println(s);
content.append(s + "\n");
}
filereader.close();

if( content.length() > 0 )
{
return content.toString();
}
else
{
throw new IOException();
}

}

}

Kod jest prosty jak konstrukcja gwoździa. Konstruktor ma za zadanie otworzyc plik poprzez stworzenie obiektu FileReader. Jeśli plik nie istnieje metoda fileExists wyrzuca wyjątek. Mamy też metodę ReadFile, która przechodzi po pliku i wczytuje do zmiennej jego treść, po czym zwraca ten łańcuch, albo też wyrzuca wyjątek jeśli okazało się, że plik był pusty. Oczywiście napisaliśmy wpierw kod, a dopiero teraz stworzymy dla niego testy. Powinno się to odbywać zasadniczo w drugą stronę, ale pragnę pokazać to na jaskrawym przykładzie. Samego pisania testów przed programowaniem trzeba się nauczyć samemu poprzez praktykę.

Testy w NetBeans tworzy się bardzo łatwo. Wystarczy kliknąć prawym przyciskiem na wybranej klasie, wybrać Tools i Create JUnit Test. Wypada zapoznać się z możliwymi opcjami generowania klasy testującej. U mnie takowa wygląda po utworzeniu następująco:

public class ChlebikConfigChangelogTest {

public ChlebikConfigChangelogTest() {
}

@BeforeClass
public static void setUpClass() throws Exception {
}

@AfterClass
public static void tearDownClass() throws Exception {
}

@Test
public void testLoadFile() throws Exception {
System.out.println("loadFile");
String fileName = "";
ChlebikConfigChangelog instance = new ChlebikConfigChangelog();
instance.loadFile(fileName);
fail("The test case is a prototype.");
}

@Test
public void testReadFile() throws Exception {
System.out.println("readFile");
ChlebikConfigChangelog instance = new ChlebikConfigChangelog();
String expResult = "";
String result = instance.readFile();
assertEquals(expResult, result);
fail("The test case is a prototype.");
}

}

I teraz do ciała każdej z metod testujących należy wrzucić kod, który przetestuje metodę. By należycie przetestować metodę readFile można zaproponować taki oto kod (modyfikując ten wygenerowany automatycznie):

@Test
public void testReadFile() throws Exception {

ChlebikConfigChangelog instance = new ChlebikConfigChangelog();

// Jesli tresc pliku to 'test'
instance.loadFile("test.txt");
String result = instance.readFile();
assertEquals("test", result);

}

@Test(expected=IOException.class)
public void testEmptyReadFile() throws IOException {

// Jesli tresc pliku nie istnieje (jest pusta)
System.out.println("readFile");
ChlebikConfigChangelog instance = new ChlebikConfigChangelog();
instance.loadFile("/test2.txt");
String result = instance.readFile();
}

Ta druga metoda służy do badania wyrzucanych wyjątków. Zastosowanie asercji @Test(excepcted=tunazwaklasywyjatku.class) buduje test (metodę), której wywołanie niezakończone wyrzuceniem wyjątku będzie uznawane za porażkę testu. Jest to bardzo użyteczny sposób na ich testowanie.

Mam nadzieję, że ten krótki przykład da podstawowe pojęcie o testach jednostkowych i TDD. Jak już wcześniej wspomniałem by w pełni wykorzystać zalety tego podejścia należy robić jedną rzecz – testować, testować, testować, a wówczas TDD stanie się naturalną drogą tworzenia oprogramowania.