Testowanie i logowanie. 1. Testowanie aplikacji JUnit. 2. Tworzenie logów: pakiet java.util.logging.

Podobne dokumenty
LABARATORIUM 9 TESTY JEDNOSTKOWE JUNIT 3.8

Java. Wykład. Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ

Współbieżność i równoległość w środowiskach obiektowych. Krzysztof Banaś Obliczenia równoległe 1

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Programowanie poprzez testy z wykorzystaniem JUnit

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

Testowanie jednostkowe. Jacek Starzyński, ZETiIS PW

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Programowanie obiektowe

Zaawansowane aplikacje WWW - laboratorium

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

Wątki. Definiowanie wątków jako klas potomnych Thread. Nadpisanie metody run().

Instrukcja 10 Laboratorium 13 Testy akceptacyjne z wykorzystaniem narzędzia FitNesse

Programowanie w języku Java - Wyjątki, obsługa wyjątków, generowanie wyjątków

Programowanie obiektowe

Języki i metody programowania Java. Wykład 2 (część 2)

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut.

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Aplikacje w Javie- wykład 11 Wątki-podstawy

Aplikacje Internetowe. Najprostsza aplikacja. Komponenty Javy. Podstawy języka Java

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

Wielowątkowość. Programowanie w środowisku rozproszonym. Wykład 1.

Dokumentacja do API Javy.

Katedra Architektury Systemów Komputerowych Wydział Elektroniki, Telekomunikacji i Informatyki Politechniki Gdańskiej

1 Atrybuty i metody klasowe

Ćwiczenie 1. Kolejki IBM Message Queue (MQ)

Język JAVA podstawy. wykład 2, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Multimedia JAVA. Historia

Metody dostępu do danych

Programowanie obiektowe

Obiektowe programowanie rozproszone Java RMI. Krzysztof Banaś Systemy rozproszone 1

Zad.30. Czy można utworzyć klasę, która implementuje oba interfejsy?

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

Programowanie w Javie

Polimorfizm, metody wirtualne i klasy abstrakcyjne

Testowanie. Ryszard Beczek & Piotr Miłkowski 1 04/11/07

Dziedziczenie. dr Jarosław Skaruz

Badania poziomu bezpieczeństwa portalu dostępowego do infrastruktury projektu PL-Grid

Wykład 7: Pakiety i Interfejsy

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Wykład 2: Podstawy Języka

Programowanie obiektowe

Programowanie obiektowe

1 Wątki 1. 2 Tworzenie wątków 1. 3 Synchronizacja 3. 4 Dodatki 3. 5 Algorytmy sortowania 4

SWING c.d. przydatne narzędzia: JFileChooser, JOptionPane. drag'n drop, menu kontekstowe.

Wzorce logiki dziedziny

Programowanie równoległe i rozproszone. Monitory i zmienne warunku. Krzysztof Banaś Programowanie równoległe i rozproszone 1

Kurs programowania. Wykład 13. Wojciech Macyna. 14 czerwiec 2017

Klasy. dr Anna Łazińska, WMiI UŁ Podstawy języka Java 1 / 13

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Programowanie obiektowe zastosowanie języka Java SE

Db4o obiektowa baza danych wersja.net

Wywoływanie metod zdalnych

Wykład 8: Obsługa Wyjątków

Java Zadanie 1. Aby poprawnie uruchomić aplikację desktopową, należy zaimplementować główną metodę zapewniającą punkt wejścia do programu.

Fragmenty są wspierane od Androida 1.6

Java: interfejsy i klasy wewnętrzne

WYKORZYSTANIE JĘZYKA GROOVY W TESTACH JEDNOSTKOWYCH, INTEGRACYJNYCH I AUTOMATYCZNYCH. Mirosław Gołda, Programista Java

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Testowanie II. Celem zajęć jest zapoznanie studentów z oceną jakości testów przy wykorzystaniu metryk pokrycia kodu testami (ang. code coverage).

Dawid Gierszewski Adam Hanasko

Platformy Programistyczne Podstawy języka Java

Język JAVA podstawy. wykład 2, część 2. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Marcin Luckner Politechnika Warszawska Wydział Matematyki i Nauk Informacyjnych

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Laboratorium z przedmiotu: Inżynieria Oprogramowania INP002017_ Laboratorium 11 Testy akceptacyjne z wykorzystaniem narzędzia FitNesse

Aplikacje RMI

Język JAVA podstawy. wykład 1, część 2. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Programowanie obiektowe

Katalog książek cz. 2

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut.

Wykład 6: Dziedziczenie

Programowanie obiektowe

1. Co można powiedzieć o poniższym kodzie (zakładając, że zaimportowano wszystkie niezbędne klasy)?

Platformy Technologiczne

Testowanie II. Cel zajęć. Pokrycie kodu

Instrukcja 2 Laboratorium z Podstaw Inżynierii Oprogramowania

Wykład 6 Dziedziczenie cd., pliki

Java. Programowanie Obiektowe Mateusz Cicheński

Języki Programowania II Wykład 3. Java podstawy. Przypomnienie

Współbieżność w środowisku Java

Programowanie obiektowe

JUnit TESTY JEDNOSTKOWE. Waldemar Korłub. Platformy Technologiczne KASK ETI Politechnika Gdańska

Języki i techniki programowania Ćwiczenia 2

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

Programowane refleksyjne i serializacja

Klasy abstrakcyjne, interfejsy i polimorfizm

Metody Metody, parametry, zwracanie wartości

Język Java wątki (streszczenie)

Git, Bitbucket, IntelliJ IDEA

Wykład 4 Delegat (delegate), właściwości indeksowane, zdarzenie (event) Zofia Kruczkiewicz

Java jako język programowania

UML a kod w C++ i Javie. Przypadki użycia. Diagramy klas. Klasy użytkowników i wykorzystywane funkcje. Związki pomiędzy przypadkami.

Java Język programowania

Programowanie w Internecie. Java

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

namespace HostedReceiver { public class Receiver: IConfigureThisEndpoint, AsA_Server {

KLASY, INTERFEJSY, ITP

Transkrypt:

1 Testowanie i logowanie 1. Testowanie aplikacji JUnit. 2. Tworzenie logów: pakiet java.util.logging.

2 JUnit JUnit jest platformą umożliwiającą tworzenie testów i testowanie programów napisanych w Javie. JUnit jest projektem Open Source, rozpowszechnianym na licencji Common Public License Version 1.0. Strona domowa projektu to http://www.junit.org. JUnit jest rozprowadzany w postaci archiwum zawierającego odpowiednią bibliotekę, przykłady wykorzystania pakietu oraz kod źródłowy. JUnit jest także dołączony do środowiska deweloperskiego Eclipse.

3 Przykładowa testowana klasa class Money { private int famount; private String fcurrency; public Money(int amount, String currency) { famount = amount; fcurrency = currency; public int getamount() { return famount; public String getcurrency() { return fcurrency;

4 Piszemy metody testujące public class MoneyTest extends TestCase { private Money f12chf; private Money f14chf; // inicjacja pakietu testów protected void setup() { f12chf= new Money(12, "CHF"); f14chf= new Money(14, "CHF"); // pierwsza z metod testujących public void testgetters() { Assert.assertEquals(this.f12CHF.getAmount(), 12); Assert.assertEquals(this.f12CHF.getCurrency(), "CHF");

Metody publiczne z klasy Assert public static void asserttrue(string message, boolean condition) Sprawdza czy condition jest równe true. Jeśli nie zgłaszany jest wyjątek AssertionFailedError zawierający message. public static void asserttrue(boolean condition) public static void assertfalse(...) public static void fail(...) public static void assertequals(...) public static void assertnotnull(...) public static void assertnull(...) public static void assertsame(...) Sprawdza czy podane referencje to te same obiekty public static void assertnotsame(...) 5

6 Piszemy metody testujące cd. Chcemy żeby była możliwość dodawania dwóch obiektów typu Money. Zanim napiszemy metodę add() w klasie Money określimy jej własności dopisując do zestawu MoneyTest odpowiedni test. public void testadd() { Money expected = new Money(26, "CHF"); Money result = this.f12chf.add(f14chf); Assert.assertTrue(expected.equals(result)); Ale jak powinna działać metoda equals() wywołana na rzecz instancji klasy Money?

7 Piszemy metody testujące cd. Metoda equals() powinna działać tak, aby między innymi spełnić poniższy test. public void testequals() { Money m12chf= new Money(12, "CHF"); Money m14chf= new Money(14, "CHF"); Assert.assertTrue(!m12CHF.equals(null)); Assert.assertEquals(m12CHF, m12chf); Assert.assertEquals(m12CHF, new Money(12, "CHF")); Assert.assertTrue(!m12CHF.equals(m14CHF)); Dwie instancje Money są uważane za równe gdy równa jest waluta i kwota.

8 Dopisujemy kod do testowanej klasy W klasie Money dodajemy następujące metody: // dodawanie dwóch instancji klasy Money public Money add(money m) { return new Money(getAmount()+m.getAmount(), getcurrency()); // porównanie dwóch instancji klasy Money public boolean equals(object anobject) { if (anobject instanceof Money) { Money amoney = (Money)anObject; return amoney.getcurrency().equals(getcurrency()) && (getamount() == amoney.getamount()); return false;

Aby uruchomić zestaw testów należy: określić sposób uruchomienia testu, Zanim uruchomimy test określić sposób uruchomienia zestawu testów. JUnit umożliwia uruchamianie poszczególnych testów na dwa sposoby: statyczny i dynamiczny. Statyczne wywołanie testu następuje poprzez nadpisanie metody runtest dziedziczonej po klasie TestCase i uruchomienie w niej określonego testu. Przykład: TestCase test = new MoneyTest("test dodawania"){ public void runtest() { testadd(); ; Każdy test musi posiadać nazwę! 9

10 Zanim uruchomimy test Dynamiczne wywołanie testu polega na skorzystaniu z mechanizmu Java Reflection w celu uruchomienia danego testu. Nazwa testu jest tożsama z nazwą metody realizującej test. Aby wywołać metodę testadd() konstruujemy test następująco: TestCase test = new MoneyTest("testAdd"); Wywołanie dynamiczne jest prostsze, jednak mniej bezpieczne jeśli chodzi o kontrole typów. W przypadku braku podanej metody zwracany jest wyjątek NoSuchMethodException.

Zestawy testów Aby zdefiniować zbiór testów należy zdefiniować publiczną statyczną metodę suite(): public static Test suite() { TestSuite suite= new TestSuite(); suite.addtest(new MoneyTest("testEquals")); suite.addtest(new MoneyTest("testAdd")); return suite; Wewnątrz tej metody tworzymy obiekt TestSuite zawierający metody obsługujące przeprowadzenie testu. TestSuite i TestCase implementują interfejs Test zawierający metody obsługujące przeprowadzenie testu. Istnieje także (od wersji 2.0) możliwość dynamicznego stworzenia zestawu w oparciu o klasę zawierającą testy: public static Test suite() { return new TestSuite(MoneyTest.class); 11

Zestawy testów Statyczna wersja kodu tworząca zestaw: public static Test suite() { TestSuite suite = new TestSuite(); suite.addtest( new MoneyTest("money equals") { protected void runtest() { testequals(); ); suite.addtest( new MoneyTest("simple add") { protected void runtest(){ testadd(); ); return suite; 12

13 Uruchomienie testów Aby uruchomić testy wpisujemy komende: java -cp junit.jar:money.jar junit.swingui.testrunner MoneyTest

JUnit i Eclipse 14

JUnit i Eclipse 15

Java Logging API Logowanie przede wszystkim stosuje się aby umożliwić zdiagnozowanie problemu przez: użytkownika końcowego lub lokalnego administratora, pomoc techniczną, producenta oprogramowania, programistów w trakcie tworzenia i rozwoju oprogramowania. Kolejne grupy użytkowników zwykle potrzebują coraz więcej informacji. Nie należy zastępować zwykłego debugowania przez logowanie ponieważ prowadzi to do znacznego rozrostu kodu programu. Ma to szczególnie istotne znaczenie w przypadku oprogramowania rozprowadzanego przez sieć. Klasy obsługujące logowanie są zgrupowane w pakiecie java.util.logging. http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/overview.html. Inne popularne rozwiązanie log4j: http://logging.apache.org/log4j/docs/. 16

Java Logging API Najważniejsze z klas obsługujących logowanie to: Logger klasa używana przez aplikacje do wywoływania żądań logowania. LogRecord zawiera dane określające pojedynczy wpis w logu. Dane zapisywane w obiekcie LogRecord dostępne przez metody publiczne: poziom Level getlevel() (np. Level.SEVERE), nazwa użytego obiektu typu Logger String getloggername(), wiadomość do zalogowania (przed ew. formatowaniem i lokalizacją) String getmessage(), czas: liczba milisekund od 01.01.1970 long getmillis(), dodatkowe parametry Object[] getparameters(), numer kolejny long getsequencenumber(), nazwa klasy, w której wywołano logger'a String getsourceclassname(), 17

18 Java Logging API nazwa metody, w której wywołano logger'a String getsourcemethodname(), identyfikator wątku, w którym wywołano logger'a int getthreadid(), wyjątek związany z logowaną wiadomością Throwable getthrown(). Handler eksportuje obiekty LogRecord do różnych miejsc docelowych np: pamięci, strumieni wyjścia, konsoli, plików, gniazd sieciowych. Standardowo dostępne są następujące typy handler'ow:

Java Logging API Level - określa zbiór standardowych poziomów logowania. Program może mieć przypisane różne poziomy dla różnych urządzeń odbierających komunikaty. Poziomy zdefiniowane w klasie Level: SEVERE - 1000 WARNING- 900 INFO - 800 CONFIG - 700 FINE - 500 FINER - 400 FINEST - 300 Dodatkowo zostały zdefiniowane dwa poziomy: OFF (Integer.MAX_VALUE) i ALL (Integer.MIN_VALUE), który pozwalają wyłączyć logowanie lub logować wszystkie komunikaty. Można tworzyć własne poziomy pisząc podklasy java.util.logging.levels. 19

20 Java Logging API Filter umożliwia dodatkową, precyzyjniejszą kontrolę logowanych wiadomości niż ta zapewniona przez klase Level. Formatter wspiera formatowanie informacji zapisanych w obiekcie LogRecord. Standardowodostępne są dwie klasy formatujące: SimpleFormatter - zapisuje informacje w typowej formie tekstowej XMLFormatter umożliwia tworzenie logów w formacie XML.

Prosty przykład public class LoggingSample{ private static Logger logger = Logger.getLogger("LoggingSample"); public static void inner(){ logger.info("jestem w srodku"); public static void main(string argv[]){ logger.info("zaczynam"); logger.fine("jestem gadatliwy"); try { Thread.sleep(1000); inner(); Thread.sleep(1000); catch (InterruptedException e) { logger.log(level.warning, "sleep", e); logger.warning("programista sie pomylil"); logger.finer("jestem bardziej gadatliwy"); logger.info("zrobione"); 21

22 Prosty przykład Efekt działania tekst w konsoli: 2006-02-28 16:27:47 LoggingSample main INFO: zaczynam 2006-02-28 16:27:48 LoggingSample inner INFO: jestem w srodku 2006-02-28 16:27:49 LoggingSample main WARNING: programista sie pomylil 2006-02-28 16:27:49 LoggingSample main INFO: zrobione Brak logowania wiadomości na poziomie FINE! Sposób działania logowania jest określony w pliku logging.properties, znajdującym się w podkatalogu lib środowiska JRE.

logging.properties # Global properties handlers= java.util.logging.consolehandler.level= INFO # Handler specific properties. java.util.logging.filehandler.pattern = %h/java%u.log java.util.logging.filehandler.limit = 50000 java.util.logging.filehandler.count = 1 java.util.logging.filehandler.formatter = java.util.logging.xmlformatter java.util.logging.consolehandler.level = INFO java.util.logging.consolehandler.formatter = java.util.logging.simpleformatter # Facility specific properties. # Provides extra control for each logger. com.xyz.foo.level = SEVERE Podmiana pliku jest możliwa poprzez podanie odpowiedniego argumentu dla polecenia java: -Djava.util.logging.config.file=myfile 23

24 Konfiguracja dynamiczna public class LoggingHandlerSample extends LoggingSample{ public static void main(string[] args){ try { Handler fh1 = new FileHandler("log.txt"); fh1.setlevel(level.warning); Handler fh2 = new FileHandler("logSimple.txt"); fh2.setformatter(new SimpleFormatter()); fh2.setlevel(level.all); Handler fh3 = new FileHandler("logXML.txt"); fh3.setlevel(level.info); fh3.setformatter(new XMLFormatter()); logger.addhandler(fh1); logger.addhandler(fh2); logger.addhandler(fh3); logger.setlevel(level.finest);

Konfiguracja dynamiczna catch (SecurityException e) { logger.log(level.warning, "problem", e); catch (IOException e) { logger.log(level.warning, "problem", e); LoggingSample.main(args); W konsoli wynik ten sam. W pliku logsimple.txt: 2006-02-28 16:33:37 LoggingSample main INFO: zaczynam 2006-02-28 16:33:37 LoggingSample main FINE: jestem gadatliwy 2006-02-28 16:33:38 LoggingSample inner INFO: jestem w srodku 2006-02-28 16:33:39 LoggingSample main WARNING: programista sie pomylil 2006-02-28 16:33:39 LoggingSample main FINER: jestem bardziej gadatliwy 2006-02-28 16:33:39 LoggingSample main INFO: zrobione 25

Fragment log.txt: Konfiguracja dynamiczna <?xml version="1.0" encoding="windows-1250" standalone="no"?> <!DOCTYPE log SYSTEM "logger.dtd"> <?xml version="1.0" encoding="windows-1250" standalone="no"?> <!DOCTYPE log SYSTEM "logger.dtd"> <log> <record> <date>2006-02-28t16:33:39</date> <millis>1141140819377</millis> <sequence>3</sequence> <logger>loggingsample</logger> <level>warning</level> <class>loggingsample</class> <method>main</method> <thread>10</thread> <message>programista sie pomylil</message> </record> </log> W pliku logxml.txt: jest więcej wpisów związanych z niższym poziomem logowania. 26

27 Podsumowanie Korzystanie z narzędzi służących testowaniu oprogramowania pozwala znacznie skrócić czas potrzebny na przygotowanie rozbudowanych aplikacji. Logowanie umożliwia śledzenie pracy programu i łatwiejszą lokalizacje przyczyn ewentualnych błędów.