vierseitig

Werbung
2. Unit - Tests
•
•
•
•
•
Testfall
• Vor dem Testen müssen Testfälle spezifiziert werden
• Vorbedingungen
– Zu testende Software in klar definierte Ausgangslage bringen
(z. B. Objekte mit zu testenden Methoden erzeugen)
– Angeschlossene Systeme in definierten Zustand bringen
– Weitere Rahmenbedingungen sichern (z. B. HW)
• Ausführung
– Was muss wann gemacht werden (einfachster Fall:
Methodenaufruf)
• Nachbedingungen
– Welche Ergebnisse sollen vorliegen (einfachster Fall:
Rückgabewerte)
– Zustände anderer Objekte / angeschlossener Systeme
Annotationen
Varianten von JUnit
Testfälle mit JUnit
Testsuite mit JUnit
Parametrisierte Tests
• Warnung für dieses und die weiteren Kapitel:
Der Programmcode ist meist ein Beispiel für schlechte
Formatierung; hier erlaubt, um möglichst viele Details auf
einer Folie mit Ihnen zu diskutieren
Software-Qualität
Stephan Kleuker
32
JUnit
Stephan Kleuker
33
JUnit - zwei Varianten
• Framework, um den Unit-Test eines Java-Programms zu
automatisieren
• einfacher Aufbau
• leicht erlernbar
JUnit 3.8.x
• entwickelt für „klassisches“ Java vor Java 5
• Testklassen müssen von einer Klasse TestCase erben
• Tests müssen in Testklassen stehen
• gibt einige weitere QS-Werkzeuge, die solche Tests nutzen
bzw. selbst erstellen (gehen nicht mit JUnit 4)
• Ideen leichter auf XUnit-Varianten übertragbar
JUnit 4.x
• nutzt Annotationen
• Tests können in zu testenden Klassen stehen
• etwas flexibler als Junit 3.8.x
• geht auf SUnit
(Smalltalk) zurück
• mittlerweile für
viele Sprachen
verfügbar (NUnit,
CPPUnit)
Software-Qualität
Software-Qualität
Stephan Kleuker
34
Software-Qualität
Stephan Kleuker
35
Einsatz von Annotationen: Weiterverarbeitung
Syntax von Annotationen
// HelloWorldService.java
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public class HelloWorldService {
@WebMethod
public String helloWorld() {
return "Hello World!";
}
}
• Annotationen können Parameter haben
• ohne Parameter: @EinfacheAnnotation
• mit einem Parameter @EinAnno(par="Hallo") oder
@EinAnno("Hallo") (bei nur einem Parameter kann der
Parametername weggelassen werden, woher par kommt,
sehen wir später)
• mit mehreren Parametern werden Wertepaare
(Parametername, Wert) angegeben
@KomplexAnno(par1="Hi", par2=42, par3={41,43})
• Annotationen beginnen mit einem @ und können, z. B. von
anderen Programmen zur Weiterverarbeitung genutzt werden
• hier z. B. soll die Erzeugung eines Web-Services durch die
Kennzeichnung relevanter Teile durch Annotationen erfolgen
• Java besitzt seit Version 5 Annotationen, man kann selbst
weitere definieren
Software-Qualität
Stephan Kleuker
36
Beispiel: Nutzung vordefinierter Annotation
• Annotationen können bei/vor anderen Modifiern (z.B.
public, abstract) bei folgenden Elementen stehen:
– package
− Exemplar- und Klassenvariable
– class, interface, enum − lokale Variablen
– Methode
− Parameter
• Man kann einschränken, wo welche Annotation erlaubt ist
Software-Qualität
Stephan Kleuker
37
Konstruktiver Ansatz
public class Oben {
public void supertolleSpezialmethode(){
System.out.println("Ich bin oben");
}
}
public class Unten extends Oben{
@Override public void superTolleSpezialmethode(){
System.out.println("Ich bin unten");
}
public static void main(String[] s){
Unten u= new Unten();
u.supertolleSpezialmethode();
}
ohne Annotation in Java 1.4:
}
Ich bin oben
• Testfälle werden in Java programmiert, keine spezielle
Skriptsprache notwendig
• Idee ist inkrementeller Aufbau der Testfälle parallel zur
Entwicklung
– Pro Klasse wird mindestens eine Test-Klasse
implementiert (oder in Klasse ergänzt)
• JUnit ist in Eclipse integriert, sonst muss das Paket junit.jar
zu CLASSPATH hinzugefügt werden.
Compilermeldung:
..\..\netbeans\Annotationen\src\Unten.java:2: method does not
override a method from its superclass
@Override public void superTolleSpezialmethode(){
1 error
Software-Qualität
Stephan Kleuker
38
Software-Qualität
Stephan Kleuker
39
Spezifikationsausschnitt
Klasse Mitarbeiter (1/4) - fast korrekt
package verwaltung.mitarbeiter;
import java.util.HashSet;
import java.util.Set;
public class Mitarbeiter {
private int id;
private static int idGenerator=100;
private String vorname;
private String nachname;
private Set<Fachgebiet> fachgebiete;
• Gegeben sei eine Aufzählung mit den folgenden Werten
package verwaltung.mitarbeiter;
public enum Fachgebiet {
ANALYSE, DESIGN, JAVA, C, TEST
}
• Zu entwickeln ist eine Klasse Mitarbeiter, wobei jedes
Mitarbeiterobjekt
– eine eindeutige Kennzeichnung (id) hat
– einen änderbaren Vornamen haben kann
– einen änderbaren Nachnamen mit mindestens zwei
Zeichen hat
– eine Informationssammlung mit maximal vier
Fachgebieten hat, die ergänzt und gelöscht werden
können
Software-Qualität
Stephan Kleuker
40
Klasse Mitarbeiter (2/4)
public Mitarbeiter(String vorname, String nachname) {
if (nachname==null || nachname.length()<2)
throw new IllegalArgumentException(
"Nachname mit mindestens zwei Zeichen");
this.vorname = vorname;
this.nachname = nachname;
this.id = idGenerator++;
this.fachgebiete = new HashSet<Fachgebiet>();
} Software-Qualität
Stephan Kleuker
Klasse Mitarbeiter (3/4)
public int getId() { return id; }
public void addFachgebiet(Fachgebiet f){
fachgebiete.add(f);
if(fachgebiete.size()>3){
fachgebiete.remove(f);
throw new IllegalArgumentException(
"Maximal 3 Fachgebiete");
}
}
public void setId(int id) { this.id = id; }
public String getVorname() { return vorname; }
public void setVorname(String vorname) {
this.vorname = vorname; }
public String getNachname() { return nachname; }
public void setNachname(String nachname) {
this.nachname = nachname;}
public Set<Fachgebiet> getFachgebiete() {
return fachgebiete;}
public void removeFachgebiet(Fachgebiet f){
fachgebiete.remove(f);
}
public void setFachgebiete(Set<Fachgebiet> fachgebiete) {
this.fachgebiete = fachgebiete;
}
public boolean hatFachgebiet(Fachgebiet f){
return fachgebiete.contains(f);
}
Software-Qualität
41
Stephan Kleuker
42
Software-Qualität
Stephan Kleuker
43
Klasse Mitarbeiter (4/4)
Testen von Hand
@Override
public int hashCode() { return id; }
public static void main(String... s){
Mitarbeiter m = new Mitarbeiter("Uwe","Mey");
m.addFachgebiet(Fachgebiet.ANALYSE);
m.addFachgebiet(Fachgebiet.C);
m.addFachgebiet(Fachgebiet.JAVA);
System.out.println(m);
m.addFachgebiet(Fachgebiet.TEST);
}
Uwe Mey (100)[ C JAVA ANALYSE ]
Exception in thread "main"
java.lang.IllegalArgumentException: Maximal 3 Fachgebiete
at
verwaltung.mitarbeiter.Mitarbeiter.addFachgebiet(Mitarbei
ter.java:58) at
verwaltung.mitarbeiter.Mitarbeiter.main(Mitarbeiter.java:
99)
@Override
public boolean equals(Object obj) {
if (obj == null || getClass() != obj.getClass())
return false;
Mitarbeiter other = (Mitarbeiter) obj;
return (id == other.id);
}
@Override
public String toString(){
StringBuffer erg= new StringBuffer(vorname+
" "+nachname+" ("+id+")[ ");
for(Fachgebiet f:fachgebiete)
erg.append(f+" ");
erg.append("]");
return erg.toString();
Stephan Kleuker
} Software-Qualität
44
Anlegen einer Testklasse (1/2)
Software-Qualität
Stephan Kleuker
Software-Qualität
Stephan Kleuker
45
Anlegen einer Testklasse (2/2)
46
Software-Qualität
Stephan Kleuker
47
Testen mit JUnit
Test des Konstruktors und der eindeutigen Id
• Tests werden mit Methoden durchgeführt, die mit
Annotation @Test markiert sind
• Testmethoden haben typischerweise keinen Rückgabewert
(nicht verboten)
• Tests stehen typischerweise in eigener Klasse; für Klasse X
eine Testklasse XTest (können auch in zu testender Klasse
stehen)
• Mit Klassenmethoden der Klasse Assert werden gewünschte
Eigenschaften geprüft
Assert.assertTrue("korrekter Vorname"
,m.getVorname().equals("Ute"));
• JUnit steuert Testausführung, Verstöße bei Prüfungen
werden protokolliert
Software-Qualität
Stephan Kleuker
48
Anmerkungen
@Test
public void testEindeutigeId(){
Assert.assertTrue("unterschiedliche ID"
, new Mitarbeiter("Ute","Mai").getId()
!= new Mitarbeiter("Ute","Mai").getId());
}
Software-Qualität
Stephan Kleuker
49
Ausschnitt: Klassenmethoden von Assert
• keine gute Idee: mehrere Asserts hintereinander (scheitert
das Erste, wird Zweite nicht betrachtet -> Tests trennen)
• Assert-Methoden haben optionalen ersten String-Parameter
• String kann genauere Informationen über erwartete Werte
enthalten, z. B. über toString-Methoden der beteiligten
Objekte
• generell reicht Assert.assertTrue() aus, gibt viele weitere
Methoden
• Um nicht immer die Klasse Assert angeben zu müssen, kann
man auch (persönlich unschön) folgendes nutzen:
import static org.junit.Assert.*;
Software-Qualität
package verwaltung.mitarbeiter;
import org.junit.Assert;
import org.junit.Test;
public class MitarbeiterTest {
@Test
public void testKonstruktor(){
Mitarbeiter m = new Mitarbeiter("Ute","Mai");
Assert.assertTrue("korrekter Vorname"
,m.getVorname().equals("Ute"));
Assert.assertTrue("korrekter Nachname"
,m.getNachname().equals("Mai"));
}
Stephan Kleuker
50
assertArrayEquals(java.lang.Object[] expecteds,
java.lang.Object[] actuals)
Asserts that two object arrays are equal.
assertEquals(double expected, double actual, double delta)
Asserts that two doubles or floats are equal to within
a positive delta.
assertFalse(boolean condition)
assertNotNull(java.lang.Object object)
assertNull(java.lang.Object object)
assertSame(java.lang.Object expected,
java.lang.Object actual)
Asserts that two objects refer to the same object.
assertThat(T actual, org.hamcrest.Matcher<T> matcher)
Asserts that actual satisfies the condition specified
by matcher.
assertTrue(boolean condition)
fail()
Fails a test with no message.
Software-Qualität
Stephan Kleuker
51
Test-Fixture
Tests von hatFähigkeit
• Testfall sieht in der Regel so aus, dass eine bestimmte
Konfiguration von Objekten aufgebaut wird, gegen die der
Test läuft
• Menge von Testobjekten wird als Test-Fixture bezeichnet
• Damit fehlerhafte Testfälle nicht andere Testfälle
beeinflussen können, wird die Test-Fixture für jeden Testfall
neu initialisiert
• In der mit @Before annotierten Methode werden
Exemplarvariablen initialisiert
• In der mit @After annotierten Methode werden wertvolle
Testressourcen wie zum Beispiel Datenbank- oder
Netzwerkverbindungen wieder freigegeben
Software-Qualität
Stephan Kleuker
52
Testen von Exceptions (1/3)
@Test
public void testHatFaehigkeit1(){
Assert.assertTrue("vorhandene Faehigkeit"
,m1.hatFachgebiet(Fachgebiet.C));
}
@Test
public void testHatFaehigkeit2(){
Assert.assertTrue("nicht vorhandene Faehigkeit"
,!m1.hatFachgebiet(Fachgebiet.TEST));
} Software-Qualität
Stephan Kleuker
53
• Variante 2: „klassisch“ man markiert Stellen, von denen man
erwartet, dass sie nicht ausgeführt werden
@Test
public void testAddFaehigkeit1a(){
try{
m1.addFachgebiet(Fachgebiet.TEST);
Assert.fail("fehlende Exception");
}catch(IllegalArgumentException e){
Assert.assertNotNull(e.getMessage());
}catch(Exception e){
Assert.fail("unerwartet "+e);
}
}
@Test(expected=IllegalArgumentException.class)
public void testAddFaehigkeit1(){
m1.addFachgebiet(Fachgebiet.TEST);
}
• Falls Exception nicht geworfen wird:
• Vorteil: sehr kompakte Beschreibung
• Nachteil: keine detaillierte Analyse der Exception möglich
Stephan Kleuker
@Before
public void setUp() throws Exception {
m1 = new Mitarbeiter("Uwe","Mey");
m1.addFachgebiet(Fachgebiet.ANALYSE);
m1.addFachgebiet(Fachgebiet.C);
m1.addFachgebiet(Fachgebiet.JAVA);
}
Testen von Exceptions (2/3)
• Erinnerung: Exception bei vierter Fähigkeit
• Variante 1: Exception in @Test-Annotation festhalten
Software-Qualität
public class MitarbeiterTest {
Mitarbeiter m1;
54
Software-Qualität
Stephan Kleuker
55
Testen von Exceptions (3/3)
Ausblick: langfristige Testnutzung
• Bisher geschriebene Tests werden typischerweise von
Entwicklern geschrieben
• Tests müssen archiviert und bei jedem Release neu
ausführbar sein
• Beispiel: unerfahrener Neuling ersetzt
• wenn keine Exception auftreten soll
@Test
public void testAddFaehigkeit2(){
m1.addFachgebiet(Fachgebiet.C);
}
private List<Fachgebiet> fachgebiete
= new ArrayList<Fachgebiet>();
@Test
public void testAddFaehigkeit2a(){
try{
m1.addFachgebiet(Fachgebiet.C);
}catch(Exception e){
Assert.fail("unerwartet "+e);
}
}
Software-Qualität
Stephan Kleuker
56
Test weiterer Anforderung (1/2)
Stephan Kleuker
57
Test weiterer Anforderung (2/2)
• Anforderung „einen änderbaren Nachnamen mit
mindestens zwei Zeichen hat“
• fehlt noch: Nachnamenänderung prüfen
@Test
public void testSetNachname1(){
m1.setNachname("Mai");
Assert.assertEquals(m1.getNachname(), "Mai");
}
@Test
public void testAddKonstruktor2(){
try{
new Mitarbeiter(null,null);
Assert.fail("fehlt Exception ");
}catch(IllegalArgumentException e){
}
}
@Test
public void testAddKonstruktor3(){
try{
new Mitarbeiter(null,"X");
Assert.fail("fehlt Exception ");
}catch(IllegalArgumentException e){
}
Stephan Kleuker
} Software-Qualität
Software-Qualität
@Test
public void testSetNachname2(){
try{
m1.setNachname("X");
Assert.fail("fehlt Exception ");
}catch(IllegalArgumentException e){
}
}
58
Software-Qualität
Stephan Kleuker
59
Test von equals
Was wann testen?
@Test
public void testEquals1(){
Assert.assertTrue(m1.toString(),m1.equals(m1));
}
• Beispiel zeigt bereits, dass man sehr viele sinnvolle Tests
schreiben kann
• Frage: Wieviele Tests sollen geschrieben werden?
– jede Methode testen
– doppelte Tests vermeiden
– je kritischer eine SW, desto mehr Tests
– Suche nach Kompromissen: Testkosten vs Kosten von
Folgefehlern
– ein Kompromiss: kein Test generierter Methoden
(Konstruktoren, get, set, equals, hashCode)
@Test
public void testEquals2(){
Assert.assertFalse(m1
.equals(new Mitarbeiter("Ute","Mey")));
}
@Test
public void testEquals3(){
Mitarbeiter m2 = new Mitarbeiter("Ufo","Hai");
m2.setId(m1.getId());
Assert.assertTrue(m1.equals(m2));
}
Software-Qualität
Stephan Kleuker
• (nächste Veranstaltungen, sinnvolle Testerstellung)
60
Tests ein/und ausschalten
@Ignore("im nächsten Release lauffähig")
@Test
public void testChefIstNummer1(){
Mitarbeiter chef= new Mitarbeiter("Ego","Ich");
Assert.assertEquals("Nr.1", chef.getId(),1);
}
Stephan Kleuker
Stephan Kleuker
61
Gefahr von Endlostests
• verschiedene Ansätze, Stellen zu markieren, die noch
entwickelt werden (//TODO)
• häufiger kann man Tests schreiben, bevor Implementierung
vorliegt (-> Design by Concept durch Interfaces)
• Tests können auch sonst so inaktiv geschaltet werden
Software-Qualität
Software-Qualität
62
• Tests laufen nacheinander, endet einer nicht, werden andere
nicht ausgeführt
@Test(timeout=2000)
public void testGodot(){
while (!m1.getFachgebiete().isEmpty())
Assert.assertFalse(m1.hatFachgebiet(Fachgebiet.TEST));
}
Software-Qualität
Stephan Kleuker
63
Testablaufsteuerung (1/3)
Testablaufsteuerung (2/3)
public class AblaufAnalyse {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("setUpBeforeClass");
}
@After
public void tearDown() throws Exception {
System.out.println("tearDown");
}
@Test
public void test1(){
System.out.println("test1");
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("tearDownAfterClass");
}
@Test
public void test2(){
System.out.println("test2");
}
@Before
public void setUp() throws Exception {
System.out.println("setUp");
}
Software-Qualität
Stephan Kleuker
}
64
Testablaufsteuerung (3/3)
Stephan Kleuker
Stephan Kleuker
65
Testorganisation
Für große Projekte sind folgende Wünsche bzgl. der Tests
typisch:
a) mehrere Testklassen sollen zusammen laufen können
b) man möchte Tests flexibel kombinieren können;
Testwiederholung soll davon abhängen, welche Klassen
betroffen sein können [schwierige Weissagung]
c) man möchte Tests automatisiert ablaufen lassen können
möglich z. B.:
– JUnit hat Klassen zum einfachen Start von der Konsole
aus
– Nutzung eines cron-Jobs
zu a) und b) folgende Folien: Tests zusammenfassen zu
TestSuites
setUpBeforeClass
setUp
test1
tearDown
setUp
test2
tearDown
tearDownAfterClass
Software-Qualität
Software-Qualität
66
Software-Qualität
Stephan Kleuker
67
Tests zusammenfassen (1/3) - weitere Testklasse
Tests zusammenfassen (2/3) - einzelne TestSuite
package verwaltung.mitarbeiter;
• Anmerkung: Aufbau nicht ganz intuitiv
package verwaltung.mitarbeiter;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;;
public class Mitarbeiter2Test {
@Test
public void testHinzuUndWeg(){
Mitarbeiter m = new Mitarbeiter("Hu","Go");
m.addFachgebiet(Fachgebiet.C);
m.addFachgebiet(Fachgebiet.C);
m.removeFachgebiet(Fachgebiet.C);
Assert.assertFalse(m.hatFachgebiet(Fachgebiet.C));
}
@RunWith(Suite.class)
@SuiteClasses({Mitarbeiter2Test.class,
MitarbeiterTest.class})
public class MitarbeiterAllTest {
// hier stehen keine Tests !
}
}
Software-Qualität
Stephan Kleuker
68
Tests zusammenfassen (3/3) - Suite in Suite
Software-Qualität
Stephan Kleuker
69
Parametrisierte Tests
package verwaltung;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
• bereits gesehen: häufig wird eine Methode mit
verschiedenen Parametern getestet
• das Schreiben gleichartiger Tests mit ähnlichen Parametern
ist langweilig und zeitaufwändig
• Ansatz: Testdaten irgendwo kompakt speichern und für
Testfälle einlesen
import verwaltung.mitarbeiter.MitarbeiterAllTest;
@RunWith(Suite.class)
@SuiteClasses({MitarbeiterAllTest.class})
public class VerwaltungAllTest {}
• Lösung in JUnit über mit @Parameter annotierte Methode,
die eine Sammlung von Daten liefert
Software-Qualität
Stephan Kleuker
70
Software-Qualität
Stephan Kleuker
71
Beispiel: Parametrisierte Tests (1/2)
Beispiel: Parametrisierte Tests (2/2)
package verwaltung.mitarbeiter;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
private Mitarbeiter m1;
private Fachgebiet hat;
public Mitarbeiter3Test(Fachgebiet f1, Fachgebiet f2,
Fachgebiet f3) {
m1 = new Mitarbeiter("Oh", "Ha");
m1.addFachgebiet(f1);
m1.addFachgebiet(f2);
hat = f3;
}
@RunWith(value = Parameterized.class)
public class Mitarbeiter3Test {
@Parameters
public static Collection<Object[]> daten() {
Object[][] testdaten = {
{Fachgebiet.ANALYSE, Fachgebiet.C, Fachgebiet.C}
,{Fachgebiet.ANALYSE, Fachgebiet.C, Fachgebiet.ANALYSE}
,{Fachgebiet.C, Fachgebiet.C, Fachgebiet.C} };
return Arrays.asList(testdaten);
}
Software-Qualität
Stephan Kleuker
72
Einschränkungen bei Parametrisierung
@Test
public void testHat() {
Assert.assertTrue(m1.hatFachgebiet(hat));
}
}
Software-Qualität
Stephan Kleuker
73
Parameter aus Datei testen (1/4) - Erinnerung
• Parameter-Methode muss Collection<Object[]> liefern
• Einfaches Speichern in XML über Serializable
• ergänzen in Mitarbeiter:
@Parameters
public static Collection<Object[]> data() {...
• enthaltene Object[] müssen gleich groß sein
• Typen der Array-Elemente müssen zum Konstruktor des
Tests passen
import java.io.Serializable;
public class Mitarbeiter implements Serializable{
private static final long serialVersionUID =
458076069326042941L;
• Man kann in data() auf Dateien zugreifen
• Es gibt kreative Tricks, z. B. dynamische Arraygrößen mit
null-Werten zu ermöglichen
public Mitarbeiter(){ // nur für Serialisierung
fachgebiete = new HashSet<Fachgebiet>();
// man bedenke Nachnamenproblem
}
• Anmerkung: Java kann auch mit anderen Dateien (z. B. .csv)
arbeiten
Software-Qualität
Stephan Kleuker
74
Software-Qualität
Stephan Kleuker
75
Parameter aus Datei testen (2/4) – Daten erzeugen
Parameter aus Datei testen (3/4) – Daten lesen
public class Datenerzeugung {
private final String DATEI="daten.xml";
public Datenerzeugung() throws FileNotFoundException{
XMLEncoder out = new XMLEncoder(new BufferedOutputStream(
new FileOutputStream(DATEI)));
out.writeObject(new Mitarbeiter("Hai","Wo"));
out.writeObject(Fachgebiet.TEST);
out.writeObject(true);
out.writeObject(Fachgebiet.TEST);
out.writeObject(new Mitarbeiter("Su","Se"));
out.writeObject(Fachgebiet.TEST);
out.writeObject(false);
out.writeObject(Fachgebiet.C);
out.close();
}
public static void main(String[] args) throws
FileNotFoundException {
new Datenerzeugung();
}
}
Software-Qualität
Stephan Kleuker
76
Parameter aus Datei testen (4/4) – Testen
@Parameters public static Collection<Object[]> daten()
throws FileNotFoundException {
List<Object[]> ergebnis = new ArrayList<Object[]>();
XMLDecoder in = new XMLDecoder(new BufferedInputStream(
new FileInputStream(DATEI)));
boolean neuerWert = true;
while (neuerWert) {
Object[] tmp = new Object[3];
try {
Mitarbeiter m = (Mitarbeiter) in.readObject();
m.addFachgebiet((Fachgebiet) in.readObject());
tmp[0] = m;
tmp[1] = (Boolean) in.readObject();
tmp[2] = (Fachgebiet) in.readObject();
ergebnis.add(tmp);
} catch (ArrayIndexOutOfBoundsException e) {
neuerWert = false;
}
}
in.close(); return ergebnis;
} Software-Qualität
Stephan Kleuker
77
JUnit - Erweiterungen
public class Mitarbeiter4Test {
static private final String DATEI = "daten.xml";
@Parameters ... // letzte Folie
• Beispiel: Klasse Runner zur Teststeuerung
• Aus: http://junit.sourceforge.net/javadoc/org/junit/runner/Runner.html
„A Runner runs tests and notifies a RunNotifier of significant events as it
does so. You will need to subclass Runner when using RunWith to
invoke a custom runner. When creating a custom runner, in addition to
implementing the abstract methods here you must also provide a
constructor that takes as an argument the Class containing the tests.
The default runner implementation guarantees that the instances of the
test case class will be constructed immediately before running the test
and that the runner will retain no reference to the test case instances,
generally making them available for garbage collection.“
private Mitarbeiter m;
private boolean erwartet;
private Fachgebiet pruef;
public Mitarbeiter4Test(Mitarbeiter m, Boolean b,
Fachgebiet f) {
System.out.println(m + " : " + b + " : " + f);
this.m = m;
this.erwartet = b;
Hai Wo (100)[ TEST ] : true : TEST
this.pruef = f;
Su Se (101)[ TEST ] : false : C
}
• Fehlt noch: Möglichkeit, Tests nur durchzuführen, wenn
andere Tests vorher erfolgreich waren (erst Login testen,
dann Funktionalität) Variante TestNG
@Test
public void testHat() {
Assert.assertTrue(m.hatFachgebiet(pruef)==erwartet);
}
}
Software-Qualität
Stephan Kleuker
78
Software-Qualität
Stephan Kleuker
79
Herunterladen