Software Engineering. 3. JUnit und ANT. Franz-Josef Elmer, Universität Basel, HS 2012

Ähnliche Dokumente
Software Engineering. 4. Unit Testing und Refactoring. Franz-Josef Elmer, Universität Basel, HS 2007

ANT. Kurzvortrag von Manuel Schulze.

JCoverage. Uni Kassel Projektarbeit Software Engineering Markus Pilsl & Marko Medved

Eclipse und Java Einheit 06: Building Eclipse Projete mit Ant

Testen mit JUnit. Motivation

Software-Engineering Grundlagen des Software-Engineering

Wie konfiguiriert man Eclipse (mit oder ohne Plugin) Erich Ehses

Einführung in die Informatik Tools

Das Build-Tool ANT ETIS SS05

Kurzanleitung zu XML2DB

Das Build Tool Ant. Sebastian Mancke,

Fortgeschrittenes Programmieren mit Java. Test Driven Development

Software-Engineering und Optimierungsanwendungen in der Thermodynamik

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

Einführung in Javadoc

SEP 114. Design by Contract

Web-Technologien Kick-Start

Java Einführung Collections

Programmierkurs Java

Test-Driven Design: Ein einfaches Beispiel

Einführung in die Programmierung

Software Engineering in der Praxis

Programmieren in Java

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

Softwaretests in Visual Studio 2010 Ultimate Vergleich mit Java-Testwerkzeugen. Alexander Schunk Marcel Teuber Henry Trobisch

Programmiertechnik II

Das Test-Framework JUnit ETIS SS04

Es sollte die MS-DOS Eingabeaufforderung starten. Geben Sie nun den Befehl javac ein.

Java: Vererbung. Teil 3: super()

Swp08-6 Verantwortliche: Yundensuren, Baigalmaa. Testkonzept

JUnit - Test Driven Development. Bernhard Frey, Thorsten Stratmann, Jackson Takam, Michel Müller 1

Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden.

25 Import der Beispiele

Pakete dienen dazu, die Software eines Projektes in größere inhaltlich zusammengehörige Bereiche mit eigenem Namen einzuteilen (siehe Java API).

Python SVN-Revision 12

Javakurs zu Informatik I. Henning Heitkötter

Software Engineering. Zur Architektur der Applikation Data Repository. Franz-Josef Elmer, Universität Basel, HS 2015

Große Übung Praktische Informatik 1

Unit-Test Theorie und Praxis. Stephan Seefeld, INGTES AG

Software Engineering Klassendiagramme Assoziationen

U08 Entwurfsmuster (II)

Aufgabenblatt Nr. 5 Generizität und TicTacToe

Unit Testing mit JUnit. Dr. Andreas Schroeder

Assoziation und Aggregation

Praktische Übung 'JUnit-Test'

Folge 18 - Vererbung

Innere Klassen in Java

TCP/IP Programmierung. C# TimeServer Java6 TimeClient

3 Objektorientierte Konzepte in Java

Einführung in die Java- Programmierung

Software-Engineering Software-Management

Objektorientierte Programmierung für Anfänger am Beispiel PHP

Starten Sie Eclipse: Hier tragen sie Ihr Arbeitsverzeichnis ein. Zu Hause z.b. c:\workspace.

Übung Grundlagen der Programmierung. Übung 03: Schleifen. Testplan Testergebnisse

Java Einführung Umsetzung von Beziehungen zwischen Klassen. Kapitel 7

.NET Code schützen. Projekt.NET. Version 1.0

Lösungsvorschläge. zu den Aufgaben im Kapitel 4

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Objektorientierte Programmierung. Kapitel 12: Interfaces

Übung: Verwendung von Java-Threads

Backup der Progress Datenbank

Beispiel: Methode mit einem Fehler. Diese Methode wird problematisch, wenn von außen eine Dauer von 0 Sekunden angegeben wird, etwa im Aufruf

Programmieren in Java

License Management SDK

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

am Beispiel von JUnit

Komponententest. Testen von Software Systemen. Übung 02 SS 2009 Version:

Informationen zur Verwendung von Visual Studio und cmake

Inhalt. 1 Einleitung AUTOMATISCHE DATENSICHERUNG AUF EINEN CLOUDSPEICHER

Pragmatik von Programmiersprachen

Studentische Lösung zum Übungsblatt Nr. 7

Nathan Burgener. Design by Contract. Modul SWE

Downloadfehler in DEHSt-VPSMail. Workaround zum Umgang mit einem Downloadfehler

Beispiel: DB-Mock (1/7)

Virtueller Campus. Virtueller Campus Horw mit interaktiver Steuerung. HowTo: Externe Bibliotheken

Anleitung zur Webservice Entwicklung unter Eclipse

Unit Tests und Fehlersuche

Grundlagen der Programmierung Prof. H. Mössenböck. 14. Schrittweise Verfeinerung

Installation einer C++ Entwicklungsumgebung unter Windows --- TDM-GCC und Eclipse installieren

Reflection. Arthur Zaczek. Nov 2014

MORE Profile. Pass- und Lizenzverwaltungssystem. Stand: MORE Projects GmbH

Programmierprojekt. Anne0e Bieniusa Sommersemester 2014

Programmieren I. Übersicht. Vorlesung 12. Handout S. 1. Martin Schultheiß. Hochschule Darmstadt Wintersemester 2010/2011

Gliederung Grundlagen Schlüsselworte try-catch Fehlerobjekte Fehlerklassen Schlüsselwort finally Schlüsselwort throws selbst erstellte Exceptions

Überblick. Lineares Suchen

Ant in Eclipse Starthilfe

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Besonderheiten von C#

C++ mit Eclipse & GCC unter Windows

Java Entwicklung für Embedded Devices Best & Worst Practices!

Objektorientierte Programmierung

Adminer: Installationsanleitung

Testen von graphischen Benutzeroberflächen. 26. Juni 2013

Tagesprogramm

Installation und Sicherung von AdmiCash mit airbackup

Vorkurs C++ Programmierung

Einführung in die Programmierung für Wirtschaftsinformatik

Die Programmiersprache Java. Dr. Wolfgang Süß Thorsten Schlachter

SEMINAR Modifikation für die Nutzung des Community Builders

Starthilfe für C# Inhaltsverzeichnis. Medien- und Kommunikationsinformatik (B.Sc.) Alexander Paharukov. Informatik 3 Praktikum

Transkript:

Software Engineering 3. JUnit und ANT Franz-Josef Elmer, Universität Basel, HS 2012

Software Engineering: 3. JUnit und ANT 2 Unit Testing Unit Test: Automatischer Test welcher eine Einheit (z.b. Modul, Klasse, Komponente etc.) testet. Unit Testing: Erstellen, Verwalten und Ausführen aller Unit Tests. Unit Tests werden gleichzeitig mit dem produktiven Code geschrieben. Motto: Code a little, test a little. Produktiver Code Test Code Gebrochene Unit Tests werden sofort geflickt. Zeit

Software Engineering: 3. JUnit und ANT 3 JUnit 4: Unit Testing Framework für Java Unterstützung durch alle gängigen Java IDEs wie z.b. Eclipse. Ein Test ist eine mit @Test annotierte parameterlose public void deklarierte Methode einer Testklasse. Namenskonventionen: Testmethode: test<short description>() Testklasse: <Class to be tested>test Ein Test Runner führt alle Testmethoden der Testklasse in unbestimmter Reihenfolge aus. Dabei wird jedesmal eine neue Instanz der Testklasse erzeugt. Ein Test ist erfolgreich wenn die Testmethode kein Throwable wirft. Die Klasse Assert hat statische Methoden, die mit assert beginnen. Sie prüfen einen zu erwarteten Wert mit dem aktuellen Wert und werfen ein AssertionFailedError falls beide nicht übereinstimmen. Die Methode Assert.fail wirft immer ein AssertionFailedError.

Software Engineering: 3. JUnit und ANT 4 Beispiel TemperaturConverterTest /** * Temperature converter between Fahrenheit and Celcius. Conversion is based on * the formula * * <pre> * Fahrenheit = 9 * Celcius / 5 + 32 * </pre> */ public class TemperatureConverter { /** Converts the specified temperature from Celsius to Fahrenheit. */ public double converttofahrenheit(double temperature) { return 1.8 * temperature + 32; /** Converts the specified temperature from Fahrenheit to Celsius. */ public double converttocelcius(double temperature) { return (temperature - 32) / 1.8;

Software Engineering: 3. JUnit und ANT 5 TemperatureConverterTest import org.junit.assert; import org.junit.test; public class TemperatureConverterTest { private static final double TOL = 1e-6; @Test public void testconverttofahrenheit() { TemperatureConverter converter = new TemperatureConverter(); Assert.assertEquals(32, converter.converttofahrenheit(0), TOL); Assert.assertEquals(86, converter.converttofahrenheit(30), TOL); @Test public void testconverttocelcius() { TemperatureConverter converter = new TemperatureConverter(); Assert.assertEquals(0, converter.converttocelcius(32), TOL); Assert.assertEquals(30, converter.converttocelcius(86), TOL);

Software Engineering: 3. JUnit und ANT 6 Erwartete Exceptions testen Es sollten auch Tests geschrieben werden, die das korrekte Verhalten auf Verletzung der Vorbedingungen (z.b. keine null als Methodenargument) überprüfen. Test Code: Die zuerwartende Exception Klasse in Testannotation deklarieren. Beispiel: @Test(expected = NumberFormatException.class) public void testparseinvalidinteger() { Integer.parseInt("blabla");

Software Engineering: 3. JUnit und ANT 7 Beispiel: Stack import java.util.arraylist; import java.util.list; public class Stack<E> { private final List<E> _stack = new ArrayList<E>(); /** * Pushes the specified element onto the stack. * @param element Any object of type E. <code>null</code> is allowed. */ public void push(e element) { _stack.add(element); /** Returns <code>true</code> if the stack is empty. */ public boolean isempty() { return _stack.isempty(); /** * Removes and returns the element on the top of the stack. * @throws IllegalStateException if the stack is empty. */ public E pop() { if (isempty()) throw new IllegalStateException("Can not pop from an empty stack."); return _stack.remove(_stack.size() - 1);

Software Engineering: 3. JUnit und ANT 8 StackTest import org.junit.assert; import org.junit.test; public class StackTest { @Test public void testisempty() { Stack<String> stack = new Stack<String>(); Assert.assertTrue(stack.isEmpty()); stack.push("hello"); Assert.assertFalse(stack.isEmpty()); stack.pop(); Assert.assertTrue(stack.isEmpty()); @Test public void testpushpop() { Stack<String> stack = new Stack<String>(); stack.push("hello"); stack.push(null); stack.push("world"); Assert.assertEquals("world", stack.pop()); Assert.assertNull(stack.pop()); Assert.assertEquals("hello", stack.pop()); @Test(expected = IllegalStateException.class) public void testpopfromemptystack() { new Stack<String>().pop();

Software Engineering: 3. JUnit und ANT 9 Unit Testing Konventionen für Java Die Testklasse ist im selben Paket wie die zu testende Klasse: Vorteil: Testklasse hat Zugriff auf packageprotected Attribute und Methoden. Produktiver Code und Testcode sind in verschiedenen Verzeichnissen. Grund: Beim Build wird in der Regel nur der produktive Code benötigt.

Software Engineering: 3. JUnit und ANT 10 Vorurteile Tests schreiben ist minderwertiges Programmieren, dass kann man ruhig den Testern oder Junior-Programmierern überlassen. Unit Tests schreiben ist so anspruchsvoll wie produktiven Code schreiben. Auch Testcode sollte qualitative guter Code sein. D.h. insbesondere seine Wartbarkeit sollte hoch sein. Tests schreiben ist eine langweilige und stupide Tätigkeit. Unit Tests programmieren ist genau so kreative und macht genauso viel Spass wie produktiven Code schreiben. Unit Tests sind Zeitverschwendung. Unit Tests bilden ein Sicherheitsnetz, welches hilft älteren Code vor Fehlern zu schützen, die unbeabsichtigt durch neuen Code entstehen. Unit Tests verbessern das Design des produktiven Codes.

Software Engineering: 3. JUnit und ANT 11 Die Kunst des Unit Testing I Falls ein Test fehl schlägt, sollte zur Fehlersuche so viel Informationen gegeben werden, wie möglich. Unit Testing hat Einfluss auf das Design. Der zu testende Code muss testbar sein, d.h. es ist möglich automatische Tests zu schreiben. Wenn ein Bug gefunden wurde: 1.Finde die Ursache. 2.Schreibe einen Unit Test, der wegen des Bugs scheitert. 3.Fixe den Bug bis der Unit Test nicht mehr fehlschlägt. Unit Tests sind Test Cases und sollten deshalb so leicht lesbar sein wie manuelle Test Cases. Bespiel: Statt Assert.assertEquals(expectedList, actuallist) besser Assert.assertEquals(expectedList.toString(), actuallist.tostring()). Keine Verzweigungen in der Test Methode. Klare Trennung von Testdaten und Testcode. Komplexere Überprüfungen in eigene assert Methoden auslagern. Beispiel: CommandLineTest

Software Engineering: 3. JUnit und ANT 12 Beispiel CommandLineTest import java.util.*; public class CommandLine { private final Set<String> _options; private final List<String> _arguments; public CommandLine(String[] args) { Set<String> options = new HashSet<String>(); List<String> arguments = new ArrayList<String>(); for (String arg : args) { if (arg.startswith("-")) { options.add(arg.substring(1)); else { arguments.add(arg); _options = Collections.unmodifiableSet(options); _arguments = Collections.unmodifiableList(arguments); public List<String> getarguments() { return _arguments; public Set<String> getoptions() { return _options;

Software Engineering: 3. JUnit und ANT 13 CommandLineTest import java.util.arrays; import java.util.list; import org.junit.assert; import org.junit.test; public class CommandLineTest { @Test public void testwithoutoptions() { assertnooptions("hello", "world"); @Test public void testwithoptions() { assertoptionsandarguments(arrays.aslist("b", "c"), Arrays.asList("hi"), "-b", "hi", "-c" ); private void assertnooptions(string... args) { assertoptionsandarguments(arrays.<string>aslist(), Arrays.asList(args), args); private void assertoptionsandarguments(list<string> expectedoptions, List<String> expectedarguments, String... args) { CommandLine commandline = new CommandLine(args); Assert.assertEquals(expectedOptions.toString(), commandline.getoptions().tostring()); Assert.assertEquals(expectedArguments.toString(), commandline.getarguments().tostring());

Software Engineering: 3. JUnit und ANT 14 Die Kunst des Unit Testing II Unit Tests müssen reproduzierbar sein. Dazu braucht es eine wohldefinierte Testumgebung (Testfixture). Ein Unit Test sollte den Zustand seiner Umgebung vor dem Test wieder herstellen. Vermeidet Seiteneffekte. Tests sind reproduzierbar unabhängig der Reihenfolge ihrer Ausführung. Problem: Statische Attribute von Klassen, die ihren Zustand ändern.

Software Engineering: 3. JUnit und ANT 15 JUnit 4: Die Annotationen @Before und @After Parameterlose public void Methoden einer Testklasse werden vor/nach jeder Ausführung einer Testmethode ausgeführt, falls sie mit @Before bzw. @After annotiert wurden. Traditionelle Name dieser Methoden sind: setup() bzw. teardown(). Zweck dieser Annotationen: Bereitstellung bzw. Freigabe von externen Resourcen. Z.B.: Temporäre Dateien, Datenbankverbindungen. Erzeugung bzw. Entfernung von Testfixtures. Z.B.: setup() spielt Testdaten in eine Datenbank ein und teardown() löscht diese wieder. Beispiel: LineCounterTest

Software Engineering: 3. JUnit und ANT 16 Beispiel LineCounterTest Die Klasse LineCounter zählt die Zeilen einer Textdatei: import java.io.bufferedreader; import java.io.file; import java.io.filereader; import java.io.ioexception; public class LineCounter { public int countnumberoflines(file file) throws IOException { FileReader reader = null; try { reader = new FileReader(file); BufferedReader bufferedreader = new BufferedReader(reader); int count = 0; while (bufferedreader.readline()!= null) { count++; return count; finally { if (reader!= null) { reader.close();

Software Engineering: 3. JUnit und ANT 17 LineCounterTest Die Testklasse muss eine Beispieldatei erzeugen und wieder wegräumen: import java.io.*; import org.junit.*; public class LineCounterTest { private static final File TEMP_FILE = new File("temp.txt"); @Before public void setup() throws Exception { FileWriter writer = null; try { writer = new FileWriter(TEMP_FILE); writer.write("hello\nworld"); finally { writer.close(); @After public void teardown() throws Exception { TEMP_FILE.delete(); @Test public void test() throws IOException { Assert.assertEquals(2, new LineCounter().countNumberOfLines(TEMP_FILE));

Software Engineering: 3. JUnit und ANT 18 ANT = Another Neat Tool ANT ist Build Tool Kompilieren des Quellcodes Erzeugung einer lauffähigen Software Erzeugung einer Distribution (lauffähige Software, Dokumentation, Installationsanleitung oder -programm, etc.) Platformunabhängig da in Java geschrieben Skriptsprache in XML Unterstützung durch alle gängigen Java IDEs wie z.b. Eclipse Aufruf: prompt> ant <target> oder (wenn das Build File nicht 'build.xml' heisst) prompt> ant -f <build-file> <target>

Software Engineering: 3. JUnit und ANT 19 Build Skript: Beispiel <project name="my Project" default="dist" basedir="."> <property name="src" location="src"/> <property name="srctest" location="srctest"/> <property name="classes" location="classes"/> <property name="dist" location="dist"/> <path id="junitlib"> <pathelement location="lib/junit.jar"/> </path> <target name="init" description="init" > <delete dir="${classes"/> <mkdir dir="${classes"/> <mkdir dir="${dist"/> <tstamp/> </target> <target name="compile" depends="init" description="compile sources"> <javac srcdir="${src" destdir="${classes"/> </target> <target name="jar" depends="compile" description="generate JAR"> <jar jarfile="${dist/myproject-${dstamp.jar" basedir="${classes"/> </target> <target name="compile-test" depends="compile" description="compile test sources."> <javac srcdir="${srctest" destdir="${classes" classpathref="junitlib"/> </target> <target name="test" depends="compile-test" description="run all tests"> <junit haltonfailure="true" > <classpath refid="junitlib"/> <classpath path="${classes"/> <formatter type="brief" usefile="false"/> <batchtest> <fileset dir="${srctest"> <include name="**/*"/> </fileset> </batchtest> </junit> </target> <target name="dist" depends="jar, test"/> </project>

Software Engineering: 3. JUnit und ANT 20 ANT: Targets und Properties Targets werden durch das <target> Element definiert Wichtigste Attribute: name: Name des Targets. (pflicht) depends: Kommaseparierte Liste aller Targets, die vor diesem Target auszuführen sind. (optional) description: Kurze Beschreibung. (optional) Kindelemente: Tasks wie z.b. <javac>, <mkdir> Beispiel: Properties werden durch <property> Elemente definiert. <target name="compile" depends="init" description="compile sources"> <javac srcdir="${src" destdir="${classes"/> </target> Können nur einmal definiert werden. Wichtigste Attribute: name: Name der Property. Eine Property wird durch ${<name> referenziert wobei <name> der Wert des Attributs name ist. value: Wert der Property. location: Wert definiert durch absoluten Pfad einer Datei. Beispiel: <property name="dist" location="dist"/>

Software Engineering: 3. JUnit und ANT 21 ANT: Abhängigkeiten der Targets Regeln: Bevor die Tasks eines Targets ausgeführt werden, werden die abhängigen Targets in der angegebenen Reihenfolge ausgeführt. Jedes Target wird höchstens einmal ausgeführt. Beispiel: Bei der Ausführung von Target A wird D vor B ausgeführt <project name="example" default="a" basedir="."> <target name="a" depends="b, D"> <echo message="target A executed"/> </target> <target name="b" depends="c, D"> <echo message="target B executed"/> </target> <target name="c"> <echo message="target C executed"/> </target> <target name="d"> <echo message="target D executed"/> </target> </project> prompt> ant Buildfile: build.xml C: [echo] Target C executed D: [echo] Target D executed B: [echo] Target B executed A: [echo] Target A executed BUILD SUCCESSFUL Total time: 0 seconds

Software Engineering: 3. JUnit und ANT 22 Links JUnit Home Page: http://www.junit.org/ ANT Home Page http://ant.apache.org