Annotated slides from my "Behavior Driven Development" course. Released under Creative Commons share-alike, commercial and derivatives allowed: http://creativecommons.org/licenses/by-sa/3.0/
Annotated slides from my "Behavior Driven Development" course. Released under Creative Commons share-alike, commercial and derivatives allowed: http://creativecommons.org/licenses/by-sa/3.0/
Bei uns testen lauter Affen - Das Ende der BanensoftwareSAP SE
Wer hat den Teufelskreis aus Testing und Debugging noch nicht erlebt:
In zwei Wochen ist Release-Date und die Tester finden täglich neue Fehler.
Jeder Fehler führt zu einer Änderung im Programm.
Und jede Änderung kann selbst wieder Fehler verursachen und muss deshalb getestet werden...
Software-Fehler kosten die deutsche Wirtschaft bis zu 10 Mrd Euro im Jahr. Deshalb macht Testen derzeit ca. 20% der Kosten einer neuen Software aus, Tendenz steigen. Alleine für Java-Software sind das in Deutschland ca. 3,4 Mrd. Euro im Jahr. Diese Kosten entstehen hauptsächlich durch manuelles Testen bzw. manuelle Testfallerstellung. Der Automatisierungsgrad beim Testen liegt derzeit bei ca. 15%. Was wenn man automatisch Testen könnte? Und d.h. nicht manuell erstellte Tests (die will sowieso keiner erstellen und erst recht keiner pflegen) automatisch ablaufen lassen, sondern wirklich vollautomatisch Testen?
Monkey-Testing bezeichnet zufallsbasiertes Testen von Software über die Benutzeroberfläche, und findet vollautomatisch und kostengünstig Fehler. In diesem Vortrag zeige ich, wie jeder Anwesende mit ein paar Zeilen Code einen eigenen primitiven Affen zum automatischen Testen programmieren kann. Davon ausgehend zeige ich Ansätze und Konzepte, wie man diesen Affen (u.a. mit genetischen Algorithmen) immer weiter verbessern kann, bis er teilweise bessere Ergebnisse als menschliche Tester bringt. Dazu gibt es Demos und Erfahrungsberichte aus großen Projekten.
In PostgreSQL kann man sich mit "explain" ansehen, welchen Execution Plan PostgreSQL für eine Query verwendet. Das hilft beim Suchen von Performance Problemen und hilft, den Durchsatz der Database zu steigern.
Die Folien zu meinem Vortrag "Clean Test Code" auf den Clean Code Days 2014 in München: http://www.cleancode-days.de/vortraege/articles/clean-test-code.html
A power workshop during JAX 2007 on advanced techniques of test-driven development. It deals with acceptance tests using FIT as well as with mock objects, GUI testing and Groovy as a testing language for Java.
Vortrag der OOP 2014
Überblick über die Vorteile der Programmiersprache Go für skalierbare Anwendungen sowie ein Einblick in hierbei zu beachtende Probleme und ihre Lösung.
Funktionale Programmierung und mehr mit Scalathoherr
Anhand von Beispielen werden einige Konzepte der funktionalen Programmierung im Allgemeinen und die objekt-funktionale Sprache Scala im Besonderen vorgestellt.
Vortrag von 42ways im Rahmen der IT-Weiterbildungsveranstaltungen bei der SwissLife AG, Niederlassung für Deutschland, München.
Einige ausgewählte Oracle PL/SQL Packages aus Version 11g und 12c werden kurz beschrieben und illustriert an Beispielen. In Teil 3 handelt es sich dabei um:
DBMS_XPLAN
DBMS_ASSERT
DBMS_RESUMABLE
DBMS_UTILITY
Die Programmiersprache C++ gehört immer noch zu den wichtigsten Programmiersprachen überhaupt. Gerade im Embedded Bereich vollzieht sich langsam die Abkehr von C zu C++ und ist dort alternativlos. Es hatte jedoch jahrelang den Anschein, als würde diese Sprache seit Jahren nicht weiterentwickelt und von den Features und Ausdrucksmöglichkeiten hinter neueren Sprachen zurückzufallen. In diesem Vortrag zeige ich an Codebeispielen, welche Revolution tatsächlich seit C++11 stattgefunden hat und dass die Sprache keinesfalls mehr mit der zu vergleichen ist, die man vielleicht vor Jahren kennen (und vielleicht hassen) gelernt hat. Die Umgestaltung der Sprache ist dabei keineswegs abgeschlossen sondern zeigt weitere, vielversprechende Konzepte am Horizont.
Um agile Entwicklung sinnvoll in einem Projekt zu ermöglichen, spielt die Architektur des Systems eine entscheidende Rolle. In einem agilen Projekt sind Architektureigenschaften wie Installierbarkeit und Prüfbarkeit entscheidend, da die Software in kurzen Abständen regelmäßig geliefert und im besten Fall dem Endnutzer zur Verfügung gestellt wird. Diese kurzen Releasezyklen gelingen nur durch ein hohes Maß an Automatisierung. Agile Projekte benötigen bereits passende Lösungsansätze in der Architektur, die es erlauben eine Continous Delivery Pipeline möglichst einfach zu realisieren; das Architekturmuster „Microservices“ versucht u.A. diesen Anforderungen gerecht zu werden.
Weitere Vorteile des Architekturmusters ergeben sich bei der Skalierung von Projekten. Durch den Einsatz von „Microservices“ können Projekte einfach aufgeteilt und parallel von mehreren Cross-Functional Teams mit agilen Methoden umgesetzt werden.
Die Idee eines Microservice ist nicht neu: das System wird in kleine, losgelöste Anwendungen (sog. Microservices) aufgeteilt. Diese Bausteine stellen Ihre Funktionalität als Service zur Verfügung. Der Vortrag gibt einen Praxiseinblick, auf welche Weise man vom Einsatz des Architekturmusters „Microservice“ in einem agilen Projektumfeld profitieren kann. Es wird aufgezeigt, wo sich in der Praxis Schwierigkeiten ergeben und wie man diesen vorbeugen kann. Der gesamte Vortrag gibt einen grundlegenden Einblick in die agile Entwicklung auf Basis einer Microservice-Architektur.
Bei uns testen lauter Affen - Das Ende der BanensoftwareSAP SE
Wer hat den Teufelskreis aus Testing und Debugging noch nicht erlebt:
In zwei Wochen ist Release-Date und die Tester finden täglich neue Fehler.
Jeder Fehler führt zu einer Änderung im Programm.
Und jede Änderung kann selbst wieder Fehler verursachen und muss deshalb getestet werden...
Software-Fehler kosten die deutsche Wirtschaft bis zu 10 Mrd Euro im Jahr. Deshalb macht Testen derzeit ca. 20% der Kosten einer neuen Software aus, Tendenz steigen. Alleine für Java-Software sind das in Deutschland ca. 3,4 Mrd. Euro im Jahr. Diese Kosten entstehen hauptsächlich durch manuelles Testen bzw. manuelle Testfallerstellung. Der Automatisierungsgrad beim Testen liegt derzeit bei ca. 15%. Was wenn man automatisch Testen könnte? Und d.h. nicht manuell erstellte Tests (die will sowieso keiner erstellen und erst recht keiner pflegen) automatisch ablaufen lassen, sondern wirklich vollautomatisch Testen?
Monkey-Testing bezeichnet zufallsbasiertes Testen von Software über die Benutzeroberfläche, und findet vollautomatisch und kostengünstig Fehler. In diesem Vortrag zeige ich, wie jeder Anwesende mit ein paar Zeilen Code einen eigenen primitiven Affen zum automatischen Testen programmieren kann. Davon ausgehend zeige ich Ansätze und Konzepte, wie man diesen Affen (u.a. mit genetischen Algorithmen) immer weiter verbessern kann, bis er teilweise bessere Ergebnisse als menschliche Tester bringt. Dazu gibt es Demos und Erfahrungsberichte aus großen Projekten.
In PostgreSQL kann man sich mit "explain" ansehen, welchen Execution Plan PostgreSQL für eine Query verwendet. Das hilft beim Suchen von Performance Problemen und hilft, den Durchsatz der Database zu steigern.
Die Folien zu meinem Vortrag "Clean Test Code" auf den Clean Code Days 2014 in München: http://www.cleancode-days.de/vortraege/articles/clean-test-code.html
A power workshop during JAX 2007 on advanced techniques of test-driven development. It deals with acceptance tests using FIT as well as with mock objects, GUI testing and Groovy as a testing language for Java.
Vortrag der OOP 2014
Überblick über die Vorteile der Programmiersprache Go für skalierbare Anwendungen sowie ein Einblick in hierbei zu beachtende Probleme und ihre Lösung.
Funktionale Programmierung und mehr mit Scalathoherr
Anhand von Beispielen werden einige Konzepte der funktionalen Programmierung im Allgemeinen und die objekt-funktionale Sprache Scala im Besonderen vorgestellt.
Vortrag von 42ways im Rahmen der IT-Weiterbildungsveranstaltungen bei der SwissLife AG, Niederlassung für Deutschland, München.
Einige ausgewählte Oracle PL/SQL Packages aus Version 11g und 12c werden kurz beschrieben und illustriert an Beispielen. In Teil 3 handelt es sich dabei um:
DBMS_XPLAN
DBMS_ASSERT
DBMS_RESUMABLE
DBMS_UTILITY
Die Programmiersprache C++ gehört immer noch zu den wichtigsten Programmiersprachen überhaupt. Gerade im Embedded Bereich vollzieht sich langsam die Abkehr von C zu C++ und ist dort alternativlos. Es hatte jedoch jahrelang den Anschein, als würde diese Sprache seit Jahren nicht weiterentwickelt und von den Features und Ausdrucksmöglichkeiten hinter neueren Sprachen zurückzufallen. In diesem Vortrag zeige ich an Codebeispielen, welche Revolution tatsächlich seit C++11 stattgefunden hat und dass die Sprache keinesfalls mehr mit der zu vergleichen ist, die man vielleicht vor Jahren kennen (und vielleicht hassen) gelernt hat. Die Umgestaltung der Sprache ist dabei keineswegs abgeschlossen sondern zeigt weitere, vielversprechende Konzepte am Horizont.
Um agile Entwicklung sinnvoll in einem Projekt zu ermöglichen, spielt die Architektur des Systems eine entscheidende Rolle. In einem agilen Projekt sind Architektureigenschaften wie Installierbarkeit und Prüfbarkeit entscheidend, da die Software in kurzen Abständen regelmäßig geliefert und im besten Fall dem Endnutzer zur Verfügung gestellt wird. Diese kurzen Releasezyklen gelingen nur durch ein hohes Maß an Automatisierung. Agile Projekte benötigen bereits passende Lösungsansätze in der Architektur, die es erlauben eine Continous Delivery Pipeline möglichst einfach zu realisieren; das Architekturmuster „Microservices“ versucht u.A. diesen Anforderungen gerecht zu werden.
Weitere Vorteile des Architekturmusters ergeben sich bei der Skalierung von Projekten. Durch den Einsatz von „Microservices“ können Projekte einfach aufgeteilt und parallel von mehreren Cross-Functional Teams mit agilen Methoden umgesetzt werden.
Die Idee eines Microservice ist nicht neu: das System wird in kleine, losgelöste Anwendungen (sog. Microservices) aufgeteilt. Diese Bausteine stellen Ihre Funktionalität als Service zur Verfügung. Der Vortrag gibt einen Praxiseinblick, auf welche Weise man vom Einsatz des Architekturmusters „Microservice“ in einem agilen Projektumfeld profitieren kann. Es wird aufgezeigt, wo sich in der Praxis Schwierigkeiten ergeben und wie man diesen vorbeugen kann. Der gesamte Vortrag gibt einen grundlegenden Einblick in die agile Entwicklung auf Basis einer Microservice-Architektur.
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
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
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
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
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
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