SlideShare uma empresa Scribd logo
1 de 49
Baixar para ler offline
Komponententests und
Testabdeckung
Christian Baranowski1
Komponenten Test
• Testbasis (Was ist die Grundlage für die Testfälle)	

• Anforderungen an die Komponente 	

• detaillierter Entwurf 	

• Code	

• Testobjekte (SUT = System Under Test):
• Komponenten	

• Programme	

• Datenumwandlung/Migrationsprogramme 	

• Datenbankmodule 	

2
Vier Phasen Test 	

(Four-Phase Test)
Setup
Verify
Teardown
Exercise
SUT
Fixture
1
2
3
4
3
Quelle: XUnit Test Patterns - Gerard Meszaros
JUnit 3.X Design
+ run(TestResult)
«interface»
Test
+ run(TestResult)
+ runTest()
+ setUp()
+ tearDown()
TestCase
+ run(TestResult)
+ addTest(Test)
TestSuite
+ setUp()
+ testMyTest()
+ tearDown()
MyTest
TestResult
Assert
4
JUnit 3 Example
public class CalcTest extends TestCase {
!
Calc calc;
protected void setUp() throws Exception {
calc = new Calc();
}
!
protected void tearDown() throws Exception {
calc = null;
}
!
public void testSum() {
int sum = calc.sum();
assertEquals(0, sum);
}
!
}
5
JUnit 4.X Design
+ getDescription()
«interface»
Describable
Description
+ getDescription()
+ run(RunNotifier)
Runner
+ getDescription()
+ run(RunNotifier)
ParentRunner
+ filter(Filter)
«interface»
Filterable
+ sort(Sorter)
«interface»
Sortable
TestClass
BlockJUnit4ClassRunner
+ setup()
+ myTest()
+ teardown()
MyTest
Assert
«interface»
@Before
«interface»
@Test
«interface»
@After
«run»
«static import» «use»
6
JUnit 4 Example
import static org.junit.Assert.*;
import org.junit.*;
!
public class CalcTest {
Calc calc;
@Before public void setup() {
calc = new Calc();
}
@Test public void sum() {
assertEquals(0, calc.sum());
}
@After public void teardown() {
calc = null;
}
}
7
JUnit3 Test Exceptions
try {
sut.sort(null);
fail(NPE was expected!);
} catch(NullPointerException exp){
assertTrue(true);
}
8
JUnit4 Test Exceptions
@Test(expected = NullPointerException.class)
public void sort_NullPointerException() {
sut.sort(null);
}
9
JUnit4 Test Exceptions
@Rule
public ExpectedException thrown= ExpectedException.none();
@Test
public void testSort_NullPointerException() {
thrown.expect(NullPointerException.class);
thrown.expectMessage(The values should not be null.);
sut.sort(null);
}
10
JUnit4 Rules
public class IgnoreRule implements MethodRule {	
!
	 @Retention(RetentionPolicy.RUNTIME)	
	 public static @interface IgnoreTest {}	
!
	 @Override	
	 public Statement apply(final Statement base, 	
final FrameworkMethod method, Object target) {	
	 	 return new Statement() {	
	 	 	 @Override	
	 	 	 public void evaluate() throws Throwable {	
	 	 	 	 if (method.getAnnotation(IgnoreTest.class) == null) {	
	 	 	 	 	 base.evaluate();	
	 	 	 	 }	
	 	 	 }	
	 	 };	
	 }	
}
11
JUnit4 Ignore Rule Test
@Rule	
public IgnoreRule ignoreRule = new IgnoreRule();	
	 	
@Test	
@IgnoreTest	
public void failingTest() {	
	 	 throw new RuntimeException(Not Implement);	
}
12
JUnit4 Runner 

(Parametrisierter Test)
@RunWith(Parameterized.class)
public class SorterTest {
!
@Parameters
public static IterableObject[] data() {
return Arrays.asList(new Object[][] {{
new Integer[] { 5, 4, 3 },
new Integer[] { 3, 4, 5 }
}});
}
!
public SorterTest(Integer[] values, Integer[] expected) {
this.values = values;
this.expectedValues = expected;
}
13
Strukturorientierter Test
14
Strukturorientierter Test 

(White-BoxVerfahren)
Komponentenebene
• Struktur der Softwarekomponente	

• Anweisungen	

• Entscheidungen	

• Zweige oder einzelne Pfade	

Integrationsebene
• Aufrufgraph oder Sequenzdiagramm	

15
„Als Testabdeckung bezeichnet man das Verhältnis an
tatsächlich getroffenen Aussagen eines Tests gegenüber
den theoretisch möglich treffbaren Aussagen bzw. der
Menge der gewünschten treffbaren Aussagen.“	

- Wikipedia
Testabdeckung
16
Testabdeckung
boolean	
  aAndbOrC(boolean	
  a,	
  boolean	
  b,	
  boolean	
  c)	
  {	
  	
  	
  
	
  	
  	
  return(a	
  	
  b)	
  ||	
  c;

}
Erwartet a b c
false false false false
true false false true
false false true false
true false true true
false true false false
true true false true
true true true false
true true true true
17
Vollständige Testabdeckung
„Eine vollständige Testabdeckung stellt eine Ausnahme
dar, weil die Anzahl möglicher Testfälle sehr schnell
ungeheuer groß wird (durch kombinatorische Explosion).
Ein vollständiger Funktionstest für eine einfache Funktion,
die zwei 16-Bit-Werte als Argument erhält, würde schon
2^(16+16), also ca. 4 Milliarden Testfälle bedeuten, um
die Spezifikation vollständig zu testen.“	

- Wikipedia
18
Flussdiagramm (flowchart)
	
  	
  
	
  boolean	
  aAndbOrC(	
  
	
  	
  boolean	
  a,	
  boolean	
  b,	
  	
  
	
  	
  boolean	
  c)	
  {	
  
	
  	
  	
  boolean	
  result	
  =	
  false;	
  	
  	
  
	
  	
  	
  if(A	
  	
  B)	
  {	
  
	
  	
  	
  	
  	
  result	
  =	
  true;	
  
	
  	
  	
  }	
  
	
  	
  	
  else	
  if(C)	
  {	
  
	
  	
  	
  	
  	
  result	
  =	
  true;	
  
	
  	
  	
  }

	
  	
  	
  else	
  {	
  
	
  	
  	
  	
  	
  result	
  =	
  false;	
  
	
  	
  	
  }	
  
	
  	
  	
  return	
  result;

	
  }	
  
result = false
Start
return result
A  B result = true
C result = true
result = false
19
Vereinfachtes Flussdiagramm
boolean	
  aAndbOrC(	
  
	
  	
  boolean	
  a,	
  boolean	
  b,	
  	
  
	
  	
  boolean	
  c)	
  {	
  
	
  	
  	
  boolean	
  result	
  =	
  false;	
  	
  	
  
	
  	
  	
  if(a	
  	
  b)	
  {	
  
	
  	
  	
  	
  	
  result	
  =	
  true;	
  
	
  	
  	
  }	
  
	
  	
  	
  else	
  if(c)	
  {	
  
	
  	
  	
  	
  	
  result	
  =	
  true;	
  
	
  	
  	
  }

	
  	
  	
  else	
  {	
  
	
  	
  	
  	
  	
  result	
  =	
  false;	
  
	
  	
  	
  }	
  
	
  	
  	
  return	
  result;

}
a  b
c
false
true
true
20
Anweisungsüberdeckung	

(Statement Coverage)
a  b
c
false
true
true
Erwartet a b c
true true true false
21
Anweisungsüberdeckung	

(Statement Coverage)
a  b
c
false
true
true
Erwartet a b c
true true true false
true false false true
22
Anweisungsüberdeckung	

(Statement Coverage)
a  b
c
false
true
true
Erwartet a b c
true true true false
true false false true
false false true false
100%
Anweisungsüberdeckung
23
Testabdeckung
int	
  sum(int	
  values[],	
  int	
  offset){	
  
	
  	
  	
  	
  	
  int	
  result	
  =	
  0;	
  
	
  	
  	
  	
  	
  for	
  (int	
  value	
  :	
  values)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  if(offset	
  	
  0){	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  if(offset	
  	
  value)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  result	
  +=	
  offset;	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  	
  	
  	
  	
  result	
  +=	
  value;	
  
	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  	
  return	
  result;	
  
}
24
Testabdeckung
result = 0
for(value
: values)
offset  0
offset 
value
result +=
offset
result +=
value
return
result
Erwartet values offset
3 [2] 1
100%
Anweisungs- 	

überdeckung
25
Zweigabdeckung	

(Branch Coverage)
result = 0
for(value
: values)
offset  0
offset 
value
result +=
offset
result +=
value
return
result
Erwartet values offset
3 [2] 1
26
Zweigabdeckung	

(Branch Coverage)
result = 0
for(value
: values)
offset  0
offset 
value
result +=
offset
result +=
value
return
result
Erwartet values offset
3 [2] 1
2 [2] 0
27
Zweigabdeckung 

(Branch Coverage)
result = 0
for(value
: values)
offset  0
offset 
value
result +=
offset
result +=
value
return
result
Erwartet values offset
3 [2] 1
2 [2] 0
2 [2] 2
Merke: 100% Zweigabdeckung schließt 

100% Anweisungsüberdeckung ein!!!
28
Entscheidungsüberdeckung 	

(Term Coverage)
boolean	
  aAndbOrC(	
  
	
  	
  boolean	
  a,	
  	
  
	
  	
  boolean	
  b,	
  	
  
	
  	
  boolean	
  c)	
  {	
  	
  	
  
	
  	
  	
  if((a	
  	
  b)	
  ||	
  c)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  return	
  true;	
  
	
  	
  	
  }	
  else	
  {	
  
	
  	
  	
  	
  	
  	
  	
  return	
  false;	
  
	
  	
  	
  }

}
Erwartet a b c
true true true false
true false false true
false false true false
Merke: 100% Entscheidungsüberdeckung schließt
100% Zweigabdeckung ein!!!
29
Überblick kontrollflussorientierten
Testverfahren (Überdeckungstests)
30
Anweisungsüberdeckung
int result = 0
return result
each(values)
result += offset
offset  0
result += value
offset  value
31
Zweigabdeckung
int result = 0
return result
each(values)
result += offset
offset  0
result += value
offset  value
32
Entscheidungsüberdeckung
int result = 0
return result
each(values)
result += offset
offset  0
result += value
offset  value
33
Schleifenüberdeckung 

(Loop Coverage)
int result = 0
return result
each(values)
result += offset
offset  0
result += value
offset  value
Schleife wird:
- keinmal
- genau einmal
- mehr als einmal
durchlaufen
34
Pfadüberdeckungstest 

(Path Coverage)
Pfadüberdeckungstest werden alle
möglichen Pfade betrachtet. 	

!
Pfade in Schleifen: 	

n = Anzahl Schleifendurchläufe	

m = Anzahl der Pfade in der Schleife 	

P = m(n)+ m(n-1)+ m(n-2) + … + m0	

!
Beispiel:
max(values) = 5	

P = 35	

 + 34 + 33	

+ 32	

+ 31	

+ 1 	

 = 364 	

243 	

 + 81	

+ 27	

+ 9 	

+ 3 	

+ 1	

 = 364	

!
Bei Schleifen ergeben sich sehr viele Pfade
kombinatorische Explosion.
A
for(values)
B D
EC
F
35
Pfadüberdeckungstest
A
for(values)
B
C
F
A
for(values)
B D
C
F
A
for(values)
B D
EC
F
max(values) = 5	

 max(values) = 4	

 max(values) = 6	

P = 15+14+13+12+11+10	

P = 6
m = 1
P = 24+23+22+21+20	

P = 31
m = 2
P = 36+35+34+33+32+31+30	

P =1093
m = 3
Pfadüberdeckungstest
def n = 5
def loopPaths = ['BC', 'BDC', ‚BDEC']
!
def pathCount = 1
def continuous = []
def pathTestCases = []
(1..n).each {
continuous.add(Collections.nCopies( it, loopPaths ))
}
continuous.each {
def combinations = it.combinations()
def paths = combinations.size()
pathCount += paths
pathTestCases.addAll(combinations)
}
pathTestCases.eachWithIndex { test, nr -
println ${nr + 1} t ${test}
}
Algorithmus Loop Paths (Groovy):
37
Komponententests 	

für echte Klassen
38
Testen ohne Abhängigkeiten
«component»
SUT
«component»
DOC
depended-on
component
*
Test
*
39
Testen ohne Abhängigkeiten
public class Calc {
!
private int result = 0;
!
private Cache cache = new Cache();
!
public void add(int a) {
if (a  0)
throw new IllegalStateException();
String stmt = String.format(%d + %d, result, a);
Integer cachedResult = cache.get(stmt);
if (cachedResult != null)
result = cachedResult;
else
cache.put(stmt, result += a);
}
!
public int sum() { return result; }
}
40
Testability (Prüfbarkeit)
public class Calc {
!
private int result = 0;
!
// DOC
Cache cache = new Cache();
…
// DOC
private Cache cache = new Cache();
public void setCache(Cache cache) {
this.cache = cache;
}
PackageVisible Dependencies
Setters for Dependencies
41
Test Doubles
42
Test Doubles
Test
Double
Fake
Object
Test
Stub
Mock
Object
Test
Spy
Dummy
Object
43
Quelle: XUnit Test Patterns - Gerard Meszaros
Test Stub
Setup
Verify
Teardown
Exercise
Stub	

!
!
Create
Install
Return	

Values
Indirect 	

Inputs
SUT
44
Quelle: XUnit Test Patterns - Gerard Meszaros
Stubbing with Mockito
class Calc {	
	 Cache cache;	
	 int plus(int a, int b) {	
	 	 Object cachedValue = cache.get(a + + + b);	
	 	 if(cachedValue != null)	
	 	 return (Integer) cachedValue; 	
	 	 return a + b;	
	 }	 	
}	
!
@Test	
public void plus() {	
when(stubCache.get(1+1)).thenReturn(3);	
int result = calc.plus(1, 1);	
assertEquals(3, result);	
}
45
Setup
Verify
Teardown
Exercise
Mock
Object	

!
!
!
Create
Install
Expections
Indirect 	

Inputs
SUT
Record
Verify
Mock Object
46
Quelle: XUnit Test Patterns - Gerard Meszaros
Mocking with Mockito
class EventAdmin {	
ListEventListener listeners = new ArrayList();	
	 public void subscribe(EventListener listener) {	
	 	 listeners.add(listener);	
	 }	
	 public void send(String event, Map?, ? properties) {	
	 	 for (EventListener listener : listeners)	
	 	 	 listener.onEvent(event, properties);	
	 }	
}	
!
@Test public void send() {	
	 EventListener mockListener = mock(EventListener.class);	
	 eventAdmin.subscribe(mockListener);	
	 eventAdmin.send(ups, null);	
	 verify(mockListener).onEvent(ups, null);	
}
47
Test Spy
Setup
Verify
Teardown
Exercise
Test Spy	

!
!
!
Create
Install
Indirect 	

Inputs
SUT
Record
Verify
48
Quelle: XUnit Test Patterns - Gerard Meszaros
Spy Objects with Mockito
@Test	
	 public void send() {	
	 	 EventListener listener = new EventListener() {	
	 	 	 @Override	
	 	 	 public void onEvent(String e, Map?, ? p) {}	
	 	 };	
	 	 EventListener mockListener = spy(listener);	
	 	 eventAdmin.subscribe(mockListener);	
	 	 eventAdmin.send(ups, null);	
	 	 verify(mockListener).onEvent(ups, null);	
	 }
49

Mais conteúdo relacionado

Semelhante a Komponententests und Testabdeckung

Bei uns testen lauter Affen - Das Ende der Banensoftware
Bei uns testen lauter Affen - Das Ende der BanensoftwareBei uns testen lauter Affen - Das Ende der Banensoftware
Bei uns testen lauter Affen - Das Ende der BanensoftwareSAP SE
 
Einführung Software Testing und Qualitätssicherung
Einführung Software Testing und QualitätssicherungEinführung Software Testing und Qualitätssicherung
Einführung Software Testing und QualitätssicherungChristian Baranowski
 
SQL-Updates mit der JDBC-API
SQL-Updates mit der JDBC-APISQL-Updates mit der JDBC-API
SQL-Updates mit der JDBC-APItutego
 
Go - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeGo - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeFrank Müller
 
Battle of the Languages: Java und Python im Wettstreit beim Lösen von Program...
Battle of the Languages: Java und Python im Wettstreit beim Lösen von Program...Battle of the Languages: Java und Python im Wettstreit beim Lösen von Program...
Battle of the Languages: Java und Python im Wettstreit beim Lösen von Program...gedoplan
 
Die nächste Generation des Unit Testing
Die nächste Generation des Unit TestingDie nächste Generation des Unit Testing
Die nächste Generation des Unit TestingDaniel Lehner
 
Clean Test Code (Clean Code Days)
Clean Test Code (Clean Code Days)Clean Test Code (Clean Code Days)
Clean Test Code (Clean Code Days)David Völkel
 
96% macoun 2013
96% macoun 201396% macoun 2013
96% macoun 2013Maxim Zaks
 
Datenbindung und Performance in Angular 2
Datenbindung und Performance in Angular 2Datenbindung und Performance in Angular 2
Datenbindung und Performance in Angular 2Manfred Steyer
 
AdvancedTdd
AdvancedTddAdvancedTdd
AdvancedTddjlink
 
Differenzial Analyse in der Praxis (Florian Walther)
Differenzial Analyse in der Praxis (Florian Walther)Differenzial Analyse in der Praxis (Florian Walther)
Differenzial Analyse in der Praxis (Florian Walther)GEEKcon
 
Skalierbare Anwendungen mit Google Go
Skalierbare Anwendungen mit Google GoSkalierbare Anwendungen mit Google Go
Skalierbare Anwendungen mit Google GoFrank Müller
 
Übungsaufgaben SS2010
Übungsaufgaben SS2010Übungsaufgaben SS2010
Übungsaufgaben SS2010maikinger
 
Funktionale Programmierung und mehr mit Scala
Funktionale Programmierung und mehr mit ScalaFunktionale Programmierung und mehr mit Scala
Funktionale Programmierung und mehr mit Scalathoherr
 
Ausgewählte PL/SQL Packages (3)
Ausgewählte PL/SQL Packages (3)Ausgewählte PL/SQL Packages (3)
Ausgewählte PL/SQL Packages (3)Ulrike Schwinn
 
SEROM 2018 - 11/14/17/20 - C++ gestern heute und morgen
SEROM 2018 - 11/14/17/20 - C++ gestern heute und morgenSEROM 2018 - 11/14/17/20 - C++ gestern heute und morgen
SEROM 2018 - 11/14/17/20 - C++ gestern heute und morgenDr. Herwig Henseler
 
Praesentation TYPO3Camp Berlin Speed mit Extbase
Praesentation TYPO3Camp Berlin Speed mit ExtbasePraesentation TYPO3Camp Berlin Speed mit Extbase
Praesentation TYPO3Camp Berlin Speed mit ExtbaseStefan Frömken
 
Übungsaufgaben
ÜbungsaufgabenÜbungsaufgaben
Übungsaufgabenmaikinger
 

Semelhante a Komponententests und Testabdeckung (20)

Bei uns testen lauter Affen - Das Ende der Banensoftware
Bei uns testen lauter Affen - Das Ende der BanensoftwareBei uns testen lauter Affen - Das Ende der Banensoftware
Bei uns testen lauter Affen - Das Ende der Banensoftware
 
Microbenchmarks - Wer nicht weiß, was er misst misst Mist
Microbenchmarks - Wer nicht weiß, was er misst misst MistMicrobenchmarks - Wer nicht weiß, was er misst misst Mist
Microbenchmarks - Wer nicht weiß, was er misst misst Mist
 
Einführung Software Testing und Qualitätssicherung
Einführung Software Testing und QualitätssicherungEinführung Software Testing und Qualitätssicherung
Einführung Software Testing und Qualitätssicherung
 
Explain explain
Explain explainExplain explain
Explain explain
 
SQL-Updates mit der JDBC-API
SQL-Updates mit der JDBC-APISQL-Updates mit der JDBC-API
SQL-Updates mit der JDBC-API
 
Go - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeGo - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare Systeme
 
Battle of the Languages: Java und Python im Wettstreit beim Lösen von Program...
Battle of the Languages: Java und Python im Wettstreit beim Lösen von Program...Battle of the Languages: Java und Python im Wettstreit beim Lösen von Program...
Battle of the Languages: Java und Python im Wettstreit beim Lösen von Program...
 
Die nächste Generation des Unit Testing
Die nächste Generation des Unit TestingDie nächste Generation des Unit Testing
Die nächste Generation des Unit Testing
 
Clean Test Code (Clean Code Days)
Clean Test Code (Clean Code Days)Clean Test Code (Clean Code Days)
Clean Test Code (Clean Code Days)
 
96% macoun 2013
96% macoun 201396% macoun 2013
96% macoun 2013
 
Datenbindung und Performance in Angular 2
Datenbindung und Performance in Angular 2Datenbindung und Performance in Angular 2
Datenbindung und Performance in Angular 2
 
AdvancedTdd
AdvancedTddAdvancedTdd
AdvancedTdd
 
Differenzial Analyse in der Praxis (Florian Walther)
Differenzial Analyse in der Praxis (Florian Walther)Differenzial Analyse in der Praxis (Florian Walther)
Differenzial Analyse in der Praxis (Florian Walther)
 
Skalierbare Anwendungen mit Google Go
Skalierbare Anwendungen mit Google GoSkalierbare Anwendungen mit Google Go
Skalierbare Anwendungen mit Google Go
 
Übungsaufgaben SS2010
Übungsaufgaben SS2010Übungsaufgaben SS2010
Übungsaufgaben SS2010
 
Funktionale Programmierung und mehr mit Scala
Funktionale Programmierung und mehr mit ScalaFunktionale Programmierung und mehr mit Scala
Funktionale Programmierung und mehr mit Scala
 
Ausgewählte PL/SQL Packages (3)
Ausgewählte PL/SQL Packages (3)Ausgewählte PL/SQL Packages (3)
Ausgewählte PL/SQL Packages (3)
 
SEROM 2018 - 11/14/17/20 - C++ gestern heute und morgen
SEROM 2018 - 11/14/17/20 - C++ gestern heute und morgenSEROM 2018 - 11/14/17/20 - C++ gestern heute und morgen
SEROM 2018 - 11/14/17/20 - C++ gestern heute und morgen
 
Praesentation TYPO3Camp Berlin Speed mit Extbase
Praesentation TYPO3Camp Berlin Speed mit ExtbasePraesentation TYPO3Camp Berlin Speed mit Extbase
Praesentation TYPO3Camp Berlin Speed mit Extbase
 
Übungsaufgaben
ÜbungsaufgabenÜbungsaufgaben
Übungsaufgaben
 

Mais de Christian Baranowski

Microservices – die Architektur für Agile-Entwicklung?
Microservices – die Architektur für Agile-Entwicklung?Microservices – die Architektur für Agile-Entwicklung?
Microservices – die Architektur für Agile-Entwicklung?Christian Baranowski
 
OSGi and Spring Data for simple (Web) Application Development
OSGi and Spring Data  for simple (Web) Application DevelopmentOSGi and Spring Data  for simple (Web) Application Development
OSGi and Spring Data for simple (Web) Application DevelopmentChristian Baranowski
 
Einführung in die Software-Qualitätssicherung
Einführung in die Software-QualitätssicherungEinführung in die Software-Qualitätssicherung
Einführung in die Software-QualitätssicherungChristian Baranowski
 
Einführung Vorgehensmodelle und Agile Software Entwicklung
Einführung Vorgehensmodelle und Agile Software EntwicklungEinführung Vorgehensmodelle und Agile Software Entwicklung
Einführung Vorgehensmodelle und Agile Software EntwicklungChristian Baranowski
 
Software Testing und Qualitätssicherung
Software Testing und QualitätssicherungSoftware Testing und Qualitätssicherung
Software Testing und QualitätssicherungChristian Baranowski
 
Datenbankzugriff mit der Java Persistence Api
Datenbankzugriff mit der Java Persistence ApiDatenbankzugriff mit der Java Persistence Api
Datenbankzugriff mit der Java Persistence ApiChristian Baranowski
 
HTTP und Java Servlets Programmierung
HTTP und Java Servlets ProgrammierungHTTP und Java Servlets Programmierung
HTTP und Java Servlets ProgrammierungChristian Baranowski
 

Mais de Christian Baranowski (20)

Microservices – die Architektur für Agile-Entwicklung?
Microservices – die Architektur für Agile-Entwicklung?Microservices – die Architektur für Agile-Entwicklung?
Microservices – die Architektur für Agile-Entwicklung?
 
OSGi and Spring Data for simple (Web) Application Development
OSGi and Spring Data  for simple (Web) Application DevelopmentOSGi and Spring Data  for simple (Web) Application Development
OSGi and Spring Data for simple (Web) Application Development
 
Einführung in die Software-Qualitätssicherung
Einführung in die Software-QualitätssicherungEinführung in die Software-Qualitätssicherung
Einführung in die Software-Qualitätssicherung
 
OSGi Web Development in Action
OSGi Web Development in ActionOSGi Web Development in Action
OSGi Web Development in Action
 
Spock and Geb in Action
Spock and Geb in ActionSpock and Geb in Action
Spock and Geb in Action
 
Continuous Delivery in Action
Continuous Delivery in ActionContinuous Delivery in Action
Continuous Delivery in Action
 
Gradle and Continuous Delivery
Gradle and Continuous DeliveryGradle and Continuous Delivery
Gradle and Continuous Delivery
 
Spock and Geb
Spock and GebSpock and Geb
Spock and Geb
 
Semantic Versioning
Semantic VersioningSemantic Versioning
Semantic Versioning
 
OSGi Community Updates 2012
OSGi Community Updates 2012OSGi Community Updates 2012
OSGi Community Updates 2012
 
OSGi Mars World in Action
OSGi Mars World in ActionOSGi Mars World in Action
OSGi Mars World in Action
 
Warum OSGi?
Warum OSGi?Warum OSGi?
Warum OSGi?
 
Top10- Software Engineering Books
Top10- Software Engineering BooksTop10- Software Engineering Books
Top10- Software Engineering Books
 
Domain Driven Design - 10min
Domain Driven Design - 10minDomain Driven Design - 10min
Domain Driven Design - 10min
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
Einführung Vorgehensmodelle und Agile Software Entwicklung
Einführung Vorgehensmodelle und Agile Software EntwicklungEinführung Vorgehensmodelle und Agile Software Entwicklung
Einführung Vorgehensmodelle und Agile Software Entwicklung
 
Software Testing und Qualitätssicherung
Software Testing und QualitätssicherungSoftware Testing und Qualitätssicherung
Software Testing und Qualitätssicherung
 
Datenbankzugriff mit der Java Persistence Api
Datenbankzugriff mit der Java Persistence ApiDatenbankzugriff mit der Java Persistence Api
Datenbankzugriff mit der Java Persistence Api
 
Java Servlets und AJAX
Java Servlets und AJAX Java Servlets und AJAX
Java Servlets und AJAX
 
HTTP und Java Servlets Programmierung
HTTP und Java Servlets ProgrammierungHTTP und Java Servlets Programmierung
HTTP und Java Servlets Programmierung
 

Komponententests und Testabdeckung

  • 2. Komponenten Test • Testbasis (Was ist die Grundlage für die Testfälle) • Anforderungen an die Komponente • detaillierter Entwurf • Code • Testobjekte (SUT = System Under Test): • Komponenten • Programme • Datenumwandlung/Migrationsprogramme • Datenbankmodule 2
  • 3. Vier Phasen Test (Four-Phase Test) Setup Verify Teardown Exercise SUT Fixture 1 2 3 4 3 Quelle: XUnit Test Patterns - Gerard Meszaros
  • 4. JUnit 3.X Design + run(TestResult) «interface» Test + run(TestResult) + runTest() + setUp() + tearDown() TestCase + run(TestResult) + addTest(Test) TestSuite + setUp() + testMyTest() + tearDown() MyTest TestResult Assert 4
  • 5. JUnit 3 Example public class CalcTest extends TestCase { ! Calc calc; protected void setUp() throws Exception { calc = new Calc(); } ! protected void tearDown() throws Exception { calc = null; } ! public void testSum() { int sum = calc.sum(); assertEquals(0, sum); } ! } 5
  • 6. JUnit 4.X Design + getDescription() «interface» Describable Description + getDescription() + run(RunNotifier) Runner + getDescription() + run(RunNotifier) ParentRunner + filter(Filter) «interface» Filterable + sort(Sorter) «interface» Sortable TestClass BlockJUnit4ClassRunner + setup() + myTest() + teardown() MyTest Assert «interface» @Before «interface» @Test «interface» @After «run» «static import» «use» 6
  • 7. JUnit 4 Example import static org.junit.Assert.*; import org.junit.*; ! public class CalcTest { Calc calc; @Before public void setup() { calc = new Calc(); } @Test public void sum() { assertEquals(0, calc.sum()); } @After public void teardown() { calc = null; } } 7
  • 8. JUnit3 Test Exceptions try { sut.sort(null); fail(NPE was expected!); } catch(NullPointerException exp){ assertTrue(true); } 8
  • 9. JUnit4 Test Exceptions @Test(expected = NullPointerException.class) public void sort_NullPointerException() { sut.sort(null); } 9
  • 10. JUnit4 Test Exceptions @Rule public ExpectedException thrown= ExpectedException.none(); @Test public void testSort_NullPointerException() { thrown.expect(NullPointerException.class); thrown.expectMessage(The values should not be null.); sut.sort(null); } 10
  • 11. JUnit4 Rules public class IgnoreRule implements MethodRule { ! @Retention(RetentionPolicy.RUNTIME) public static @interface IgnoreTest {} ! @Override public Statement apply(final Statement base, final FrameworkMethod method, Object target) { return new Statement() { @Override public void evaluate() throws Throwable { if (method.getAnnotation(IgnoreTest.class) == null) { base.evaluate(); } } }; } } 11
  • 12. JUnit4 Ignore Rule Test @Rule public IgnoreRule ignoreRule = new IgnoreRule(); @Test @IgnoreTest public void failingTest() { throw new RuntimeException(Not Implement); } 12
  • 13. JUnit4 Runner 
 (Parametrisierter Test) @RunWith(Parameterized.class) public class SorterTest { ! @Parameters public static IterableObject[] data() { return Arrays.asList(new Object[][] {{ new Integer[] { 5, 4, 3 }, new Integer[] { 3, 4, 5 } }}); } ! public SorterTest(Integer[] values, Integer[] expected) { this.values = values; this.expectedValues = expected; } 13
  • 15. Strukturorientierter Test 
 (White-BoxVerfahren) Komponentenebene • Struktur der Softwarekomponente • Anweisungen • Entscheidungen • Zweige oder einzelne Pfade Integrationsebene • Aufrufgraph oder Sequenzdiagramm 15
  • 16. „Als Testabdeckung bezeichnet man das Verhältnis an tatsächlich getroffenen Aussagen eines Tests gegenüber den theoretisch möglich treffbaren Aussagen bzw. der Menge der gewünschten treffbaren Aussagen.“ - Wikipedia Testabdeckung 16
  • 17. Testabdeckung boolean  aAndbOrC(boolean  a,  boolean  b,  boolean  c)  {            return(a    b)  ||  c;
 } Erwartet a b c false false false false true false false true false false true false true false true true false true false false true true false true true true true false true true true true 17
  • 18. Vollständige Testabdeckung „Eine vollständige Testabdeckung stellt eine Ausnahme dar, weil die Anzahl möglicher Testfälle sehr schnell ungeheuer groß wird (durch kombinatorische Explosion). Ein vollständiger Funktionstest für eine einfache Funktion, die zwei 16-Bit-Werte als Argument erhält, würde schon 2^(16+16), also ca. 4 Milliarden Testfälle bedeuten, um die Spezifikation vollständig zu testen.“ - Wikipedia 18
  • 19. Flussdiagramm (flowchart)      boolean  aAndbOrC(      boolean  a,  boolean  b,        boolean  c)  {        boolean  result  =  false;            if(A    B)  {            result  =  true;        }        else  if(C)  {            result  =  true;        }
      else  {            result  =  false;        }        return  result;
  }   result = false Start return result A B result = true C result = true result = false 19
  • 20. Vereinfachtes Flussdiagramm boolean  aAndbOrC(      boolean  a,  boolean  b,        boolean  c)  {        boolean  result  =  false;            if(a    b)  {            result  =  true;        }        else  if(c)  {            result  =  true;        }
      else  {            result  =  false;        }        return  result;
 } a b c false true true 20
  • 21. Anweisungsüberdeckung (Statement Coverage) a b c false true true Erwartet a b c true true true false 21
  • 22. Anweisungsüberdeckung (Statement Coverage) a b c false true true Erwartet a b c true true true false true false false true 22
  • 23. Anweisungsüberdeckung (Statement Coverage) a b c false true true Erwartet a b c true true true false true false false true false false true false 100% Anweisungsüberdeckung 23
  • 24. Testabdeckung int  sum(int  values[],  int  offset){            int  result  =  0;            for  (int  value  :  values)  {                  if(offset    0){                      if(offset    value)                            result  +=  offset;                  }                  result  +=  value;            }            return  result;   } 24
  • 25. Testabdeckung result = 0 for(value : values) offset 0 offset value result += offset result += value return result Erwartet values offset 3 [2] 1 100% Anweisungs- überdeckung 25
  • 26. Zweigabdeckung (Branch Coverage) result = 0 for(value : values) offset 0 offset value result += offset result += value return result Erwartet values offset 3 [2] 1 26
  • 27. Zweigabdeckung (Branch Coverage) result = 0 for(value : values) offset 0 offset value result += offset result += value return result Erwartet values offset 3 [2] 1 2 [2] 0 27
  • 28. Zweigabdeckung 
 (Branch Coverage) result = 0 for(value : values) offset 0 offset value result += offset result += value return result Erwartet values offset 3 [2] 1 2 [2] 0 2 [2] 2 Merke: 100% Zweigabdeckung schließt 
 100% Anweisungsüberdeckung ein!!! 28
  • 29. Entscheidungsüberdeckung (Term Coverage) boolean  aAndbOrC(      boolean  a,        boolean  b,        boolean  c)  {            if((a    b)  ||  c)  {                return  true;        }  else  {                return  false;        }
 } Erwartet a b c true true true false true false false true false false true false Merke: 100% Entscheidungsüberdeckung schließt 100% Zweigabdeckung ein!!! 29
  • 31. Anweisungsüberdeckung int result = 0 return result each(values) result += offset offset 0 result += value offset value 31
  • 32. Zweigabdeckung int result = 0 return result each(values) result += offset offset 0 result += value offset value 32
  • 33. Entscheidungsüberdeckung int result = 0 return result each(values) result += offset offset 0 result += value offset value 33
  • 34. Schleifenüberdeckung 
 (Loop Coverage) int result = 0 return result each(values) result += offset offset 0 result += value offset value Schleife wird: - keinmal - genau einmal - mehr als einmal durchlaufen 34
  • 35. Pfadüberdeckungstest 
 (Path Coverage) Pfadüberdeckungstest werden alle möglichen Pfade betrachtet. ! Pfade in Schleifen: n = Anzahl Schleifendurchläufe m = Anzahl der Pfade in der Schleife P = m(n)+ m(n-1)+ m(n-2) + … + m0 ! Beispiel: max(values) = 5 P = 35 + 34 + 33 + 32 + 31 + 1 = 364 243 + 81 + 27 + 9 + 3 + 1 = 364 ! Bei Schleifen ergeben sich sehr viele Pfade kombinatorische Explosion. A for(values) B D EC F 35
  • 36. Pfadüberdeckungstest A for(values) B C F A for(values) B D C F A for(values) B D EC F max(values) = 5 max(values) = 4 max(values) = 6 P = 15+14+13+12+11+10 P = 6 m = 1 P = 24+23+22+21+20 P = 31 m = 2 P = 36+35+34+33+32+31+30 P =1093 m = 3
  • 37. Pfadüberdeckungstest def n = 5 def loopPaths = ['BC', 'BDC', ‚BDEC'] ! def pathCount = 1 def continuous = [] def pathTestCases = [] (1..n).each { continuous.add(Collections.nCopies( it, loopPaths )) } continuous.each { def combinations = it.combinations() def paths = combinations.size() pathCount += paths pathTestCases.addAll(combinations) } pathTestCases.eachWithIndex { test, nr - println ${nr + 1} t ${test} } Algorithmus Loop Paths (Groovy): 37
  • 40. Testen ohne Abhängigkeiten public class Calc { ! private int result = 0; ! private Cache cache = new Cache(); ! public void add(int a) { if (a 0) throw new IllegalStateException(); String stmt = String.format(%d + %d, result, a); Integer cachedResult = cache.get(stmt); if (cachedResult != null) result = cachedResult; else cache.put(stmt, result += a); } ! public int sum() { return result; } } 40
  • 41. Testability (Prüfbarkeit) public class Calc { ! private int result = 0; ! // DOC Cache cache = new Cache(); … // DOC private Cache cache = new Cache(); public void setCache(Cache cache) { this.cache = cache; } PackageVisible Dependencies Setters for Dependencies 41
  • 45. Stubbing with Mockito class Calc { Cache cache; int plus(int a, int b) { Object cachedValue = cache.get(a + + + b); if(cachedValue != null) return (Integer) cachedValue; return a + b; } } ! @Test public void plus() { when(stubCache.get(1+1)).thenReturn(3); int result = calc.plus(1, 1); assertEquals(3, result); } 45
  • 47. Mocking with Mockito class EventAdmin { ListEventListener listeners = new ArrayList(); public void subscribe(EventListener listener) { listeners.add(listener); } public void send(String event, Map?, ? properties) { for (EventListener listener : listeners) listener.onEvent(event, properties); } } ! @Test public void send() { EventListener mockListener = mock(EventListener.class); eventAdmin.subscribe(mockListener); eventAdmin.send(ups, null); verify(mockListener).onEvent(ups, null); } 47
  • 48. Test Spy Setup Verify Teardown Exercise Test Spy ! ! ! Create Install Indirect Inputs SUT Record Verify 48 Quelle: XUnit Test Patterns - Gerard Meszaros
  • 49. Spy Objects with Mockito @Test public void send() { EventListener listener = new EventListener() { @Override public void onEvent(String e, Map?, ? p) {} }; EventListener mockListener = spy(listener); eventAdmin.subscribe(mockListener); eventAdmin.send(ups, null); verify(mockListener).onEvent(ups, null); } 49