Wo fange ich an?
Typische TDD-Fragen
Wo höre ich auf?
Wo fange ich an?
Wie nenne ich die
Testklasse?
Typische TDD-Fragen
Wo höre ich auf?
Wo fange ich an?
Wie nenne ich die
Testklasse?
Typische TDD-Fragen
Wie nenne ich die
Testmethode?
Wo höre ich auf?
Wo fange ich an?
Wie nenne ich die
Testklasse? Wie viele Assertions
pro Testfall?
Typische TDD-Fragen
Wie nenne ich die
Testmethode?
Wo höre ich auf?
Wo fange ich an? Welche Objekte
erzeuge ich im Setup?
Wie nenne ich die
Testklasse? Wie viele Assertions
pro Testfall?
Typische TDD-Fragen
Wie nenne ich die
Testmethode?
Wo höre ich auf?
Wo fange ich an? Welche Objekte
erzeuge ich im Setup?
Wie nenne ich die
Testklasse? Wie viele Assertions
pro Testfall?
Typische TDD-Fragen
Wie nenne ich die Benötigt jede Klasse/
Testmethode? Methode eine eigene
Test-Klasse/-Methode?
Wo höre ich auf?
Wo fange ich an? Welche Objekte
erzeuge ich im Setup?
Wie nenne ich die
Testklasse? Wie viele Assertions
pro Testfall?
Typische TDD-Fragen
Wie nenne ich die Benötigt jede Klasse/
Testmethode? Methode eine eigene
Test-Klasse/-Methode?
Wie gruppiere und
organisiere ich meine
Wo höre ich auf?
Testfälle?
public class KontoTest {
@Test
public void neuesKonto() {
Konto konto = new Konto(quot;Johannesquot;);
assertEquals(quot;Johannesquot;, konto.getInhaber());
assertEquals(0, konto.getSaldo());
}
}
public class KontoTest...
private Konto konto;
@Before
public void init() {
konto = new Konto(quot;Johannesquot;);
}
@Test
public void neuesKonto() {
...
}
@Test
public void einzahlung() {
konto.zahleEin(100);
assertEquals(100, konto.getSaldo());
konto.zahleEin(99);
assertEquals(199, konto.getSaldo());
}
public class KontoTest...
@Test
public void einzahlung() {
konto.zahleEin(100);
assertEquals(100, konto.getSaldo());
konto.zahleEin(99);
assertEquals(199, konto.getSaldo());
}
@Test(expected = IllegalArgumentException.class)
public void negativeEinzahlungNichtErlaubt() {
konto.zahleEin(-1);
}
public class KontoTest...
@Test
public void einzahlung() {
konto.zahleEin(100);
assertEquals(100, konto.getSaldo());
konto.zahleEin(99);
assertEquals(199, konto.getSaldo());
}
@Test(expected = IllegalArgumentException.class)
public void negativeEinzahlungNichtErlaubt() {
konto.zahleEin(100);
konto.zahleEin(-1);
}
public class KontoTest...
@Test
public void einzahlung() {
konto.zahleEin(100);
assertEquals(100, konto.getSaldo());
konto.zahleEin(99);
assertEquals(199, konto.getSaldo());
}
@Test(expected = IllegalArgumentException.class)
public void negativeEinzahlungNichtErlaubt() {
konto.zahleEin(100);
konto.zahleEin(-1);
}
public class NeuesKontoTest...
@Test public void inhaber()...
@Test public void anfangssaldo()...
@Test public void ersteEinzahlung()...
public class KontoMitPositivemSaldoTest...
private static final int ANFANGSSALDO = 100;
@Test public void einzahlung() {
konto.zahleEin(99);
assertEquals(99 + ANFANGSSALDO, konto.getSaldo());
}
@Test(expected = IllegalArgumentException.class)
public void negativeEinzahlungNichtErlaubt() {
konto.zahleEin(-1);
}
Gewünschtes
Kontoverhalten
• Ein neues Konto
• soll den Namen seines Inhabers mitteilen
können
• soll einen Saldo von 0 EUR haben
• soll einen positiven Anfangssaldo eingezahlt
bekommen können
• Ein Konto mit positivem Saldo
• soll den Saldo bei Einzahlungen
entsprechenden vergrößern
• soll bei negativen Einzahlungen eine
IllegalArgumentException auslösen
public class EinNeuesKonto...
@Test public void sollInhaberLiefern()...
@Test public void sollAnfangssaldoNullHaben()...
@Test public void sollErsteEinzahlungErlauben()...
public class EinKontoMitPositivemSaldo...
@Test public void sollBeiPositiverEinzahlungSaldoErhöhen() {
konto.zahleEin(99);
assertThat(konto.getSaldo(), is(ANFANGSSALDO + 99));
//assertEquals(99 + ANFANGSSALDO, konto.getSaldo());
}
@Test public void sollBeiNegativerEinzahlung-
IllegalArgument-ExceptionWerfen()...
public class EinNeuesKonto...
@Test public void sollInhaberLiefern()...
@Test public void sollAnfangssaldoNullHaben()...
@Test public void sollErsteEinzahlungErlauben()...
public class EinKontoMitPositivemSaldo...
@Test public void sollBeiPositiverEinzahlungSaldoErhöhen() {
konto.zahleEin(99);
assertThat(konto.getSaldo(), is(ANFANGSSALDO + 99));
//assertEquals(99 + ANFANGSSALDO, konto.getSaldo());
}
@Test public void sollBeiNegativerEinzahlung-
IllegalArgument-ExceptionWerfen()...
Die Sprache des Testen
Testfälle, Testen, Beweisen,
Sicherstellen, Programmeinheit,
Korrektheit, Vorbedingungen
Die Sprache des Testen
Testfälle, Testen, Beweisen,
Sicherstellen, Programmeinheit,
Korrektheit, Vorbedingungen
Wir versuchen mit Testfällen zu
beweisen, dass eine Programmeinheit
unter bestimmten Vorbedingungen
korrekt arbeitet
Die Sprache des Testen
Testfälle, Testen, Beweisen,
Sicherstellen, Programmeinheit,
Korrektheit, Vorbedingungen
Wir versuchen mit Testfällen zu
beweisen, dass eine Programmeinheit
unter bestimmten Vorbedingungen
korrekt arbeitet
Set Up - Stimulate - Assert
Die Sprache des BDD
User Stories, Szenario,
Spezifikation,Verhalten, Kontext
Die Sprache des BDD
User Stories, Szenario,
Spezifikation,Verhalten, Kontext
Wir spezifizieren in Szenarien, wie sich
Dinge in einem bestimmten Kontext
verhalten sollen, um eine User Story zu
erfüllen
Die Sprache des BDD
User Stories, Szenario,
Spezifikation,Verhalten, Kontext
Wir spezifizieren in Szenarien, wie sich
Dinge in einem bestimmten Kontext
verhalten sollen, um eine User Story zu
erfüllen
Given - When - Then
def ein = new GSpecBuilderRunner()
ein.context('Ein neues Konto') {
def INHABER = quot;Johannesquot;
initially {
ein.neuesKonto = new Konto(INHABER)
}
specify('soll den Inhaber als Property liefern') {
ein.neuesKonto.inhaber.should_equal INHABER
}
specify('soll 0 EUR Anfangssaldo haben') {..}
specify('soll positive Einzahlungen bekommen können') {..}
}
ein.context('Ein Konto mit positivem Saldo') {
specify('soll bei positiver Einzahlungen den Saldo erhöhen') {..}
specify('''soll bei negativer Einzahlungen
IllegalArgumentException werfen''') {..}
}
def ein = new GSpecBuilderRunner()
ein.context('Ein neues Konto') {
def INHABER = quot;Johannesquot;
initially {
ein.neuesKonto = new Konto(INHABER)
}
specify('soll den Inhaber als Property liefern') {
ein.neuesKonto.inhaber.should_equal INHABER
}
specify('soll 0 EUR Anfangssaldo haben') {..}
Ein neues Konto
soll den Inhaber als Property liefern
specify('soll positive Einzahlungen bekommen können') {..}
} Ein neues Konto
soll 0 EUR Anfangssaldo haben
ein.context('Ein Konto mit positivem Saldo') {
Ein neues Konto
specify('soll bei positiver Einzahlungen den Saldo erhöhen') {..}
soll positive Einzahlungen bekommen können
Ein Konto mit positivem Saldo
specify('''soll bei negativer Einzahlungen
soll bei positiver Einzahlungen den Saldo erhöhen
IllegalArgumentException werfen''') {..}
Ein Konto mit positivem Saldo
} soll bei negativer Einzahlungen
IllegalArgumentException werfen
scenario quot;Konto mit ANFANGSSALDOquot;, {
def ANFANGSSALDO = 42
def BETRAG = 101
given quot;ein Konto mit SALDOquot;, {
konto = new Konto(quot;irgendwerquot;)
konto.zahleEin(ANFANGSSALDO)
}
when quot;ein BETRAG eingezahlt wirdquot;, {
konto.zahleEin(BETRAG)
}
then quot;der Saldo entspricht ANFANGSSALDO + BETRAGquot;, {
konto.getSaldo().shouldBe ANFANGSSALDO + BETRAG
}
}
scenario quot;Negative Einzahlungquot;, {
given quot;ein Kontoquot;, {...}
when quot;ein negativer Betrag eingezahlt wirdquot;, {
negativeEinzahlung = { konto.zahleEin(-1) }
}
then quot;eine IllegalArgumentException soll geworfen werdenquot;, {
ensureThrows(IllegalArgumentException) { negativeEinzahlung() }
}
}
scenario quot;Konto mit ANFANGSSALDOquot;, {
def ANFANGSSALDO = 42
def BETRAG = 101
given quot;ein Konto mit SALDOquot;, {einzelnes konto
Story:
konto = new Konto(quot;irgendwerquot;)
scenario Neues Konto
konto.zahleEin(ANFANGSSALDO)
given ein neues Konto
}
then der Inhaber ist als Property verfŸgbar
when quot;ein BETRAG eingezahltthen der {
wirdquot;, Anfangssaldo ist 0
konto.zahleEin(BETRAG)
} scenario Einfache Einzahlung
then quot;der Saldo entspricht given ein leeres BETRAGquot;, {
ANFANGSSALDO + Konto
konto.getSaldo().shouldBe ANFANGSSALDOeingezahlt wird
when ein BETRAG + BETRAG
} then der Saldo entspricht dem BETRAG
}
scenario Konto mit ANFANGSSALDO
scenario quot;Negative Einzahlungquot;, { ein Konto mit SALDO
given
given quot;ein Kontoquot;, {...} when ein BETRAG eingezahlt wird
when quot;ein negativer Betrag then der Saldo entspricht ANFANGSSALDO + BETRAG
eingezahlt wirdquot;, {
negativeEinzahlung = { konto.zahleEin(-1) }
} scenario Negative Einzahlung
given ein Konto
then quot;eine IllegalArgumentException soll geworfen werdenquot;, {
ensureThrows(IllegalArgumentException) { Betrag eingezahlt wird }
when ein negativer
negativeEinzahlung()
then eine IllegalArgumentException
}
soll geworfen werden
}
Veränderter Fokus
• Weg vom Wie - hin zum Was
• User Stories -> Szenarios
• Anfangszustand pro Szenario
• Einzelne Zusicherungen
Veränderter Fokus
• Weg vom Wie - hin zum Was
• User Stories -> Szenarios
• Anfangszustand pro Szenario
• Einzelne Zusicherungen
• Weg von der Unit - hin zum Verhalten
• Geringere Kopplung zwischen Code und
Spezifikation
• Refactoring vereinfacht
Veränderter Fokus
• Weg vom Wie - hin zum Was
• User Stories -> Szenarios
• Anfangszustand pro Szenario
• Einzelne Zusicherungen
• Weg von der Unit - hin zum Verhalten
• Geringere Kopplung zwischen Code und
Spezifikation
• Refactoring vereinfacht
• Aber: Aussagekräftiges Reporting erfordert
Investition in gute Texte
Story: konten gui
scenario Leere Kontenliste anzeigen
given eine Bank ohne Konten
when die Konten-Applikation gestartet wird
then dann ist das Konten-Fenster offen
then ist die Liste der angezeigten Konten leer
Story: konten gui
scenario Leere Kontenliste anzeigen
given eine Bank ohne Konten
when die Konten-Applikation gestartet wird
then dann ist das Konten-Fenster offen
then ist die Liste der angezeigten Konten leer
scenario Gefüllte Kontenliste anzeigen
given eine Bank mit drei Konten
when die Konten-Applikation gestartet wird
then werden im Konten-Fenster drei Konten
mit Inhaber und Saldo angezeigt
Story: konten gui
scenario Leere Kontenliste anzeigen
given eine Bank ohne Konten
when die Konten-Applikation gestartet wird
then dann ist das Konten-Fenster offen
then ist die Liste der angezeigten Konten leer
scenario Gefüllte Kontenliste anzeigen
given eine Bank mit drei Konten
when die Konten-Applikation gestartet wird
then werden im Konten-Fenster drei Konten
mit Inhaber und Saldo angezeigt
scenario Löschen eines Kontos aus Kontenliste
given ein offenes Konten-Fenster mit drei Konten
when das erste Konto angewählt wird
when der Löschen-Button gedrückt wird
then verschwindet das Konto aus der Liste
then wird an der Bank das Konto gelöscht
scenario quot;Leere Kontenliste anzeigenquot;, {
given quot;eine Bank ohne Kontenquot;
when quot;die Konten-Applikation gestartet wirdquot;
then quot;dann ist das Konten-Fenster offen quot;
and quot;ist die Liste der angezeigten Konten leerquot;
}
scenario quot;Leere Kontenliste anzeigenquot;, {
given quot;eine Bank ohne Kontenquot;, {
bank = new Bank()
}
when quot;die Konten-Applikation gestartet wirdquot;
then quot;dann ist das Konten-Fenster offen quot;
and quot;ist die Liste der angezeigten Konten leerquot;
}
import static org.mockito.Mockito.*
scenario quot;Leere Kontenliste anzeigenquot;, {
given quot;eine Bank ohne Kontenquot;, {
bank = new Bank()
mock(IBank)
}
when quot;die Konten-Applikation gestartet wirdquot;
then quot;dann ist das Konten-Fenster offen quot;
and quot;ist die Liste der angezeigten Konten leerquot;
}
import static org.mockito.Mockito.*
scenario quot;Leere Kontenliste anzeigenquot;, {
given quot;eine Bank ohne Kontenquot;, {
bank = new Bank()
mock(IBank)
}
when quot;die Konten-Applikation gestartet wirdquot;
then quot;dann ist das Konten-Fenster offen quot;
and quot;ist die Liste der angezeigten Konten leerquot;
}
public interface IBank {
}
import static org.mockito.Mockito.*
scenario quot;Leere Kontenliste anzeigenquot;, {
given quot;eine Bank ohne Kontenquot;, {
bank = mock(IBank)
stub(bank.getKonten()).toReturn([])
}
when quot;die Konten-Applikation gestartet wirdquot;
then quot;dann ist das Konten-Fenster offen quot;
and quot;ist die Liste der angezeigten Konten leerquot;
}
import static org.mockito.Mockito.*
scenario quot;Leere Kontenliste anzeigenquot;, {
given quot;eine Bank ohne Kontenquot;, {
bank = mock(IBank)
stub(bank.getKonten()).toReturn([])
}
when quot;die Konten-Applikation gestartet wirdquot;
then quot;dann ist das Konten-Fenster offen quot;
and quot;ist die Liste der angezeigten Konten leerquot;
}
public interface IBank {
List<Konto> getKonten();
}
import static org.mockito.Mockito.*
scenario quot;Leere Kontenliste anzeigenquot;, {
given quot;eine Bank ohne Kontenquot;, {
bank = mock(IBank)
stub(bank.getKonten()).toReturn([])
}
when quot;die Konten-Applikation gestartet wirdquot;, {
gui = new KontenApp(bank)
gui.setVisible(true)
}
then quot;dann ist das Konten-Fenster offen quot;
and quot;ist die Liste der angezeigten Konten leerquot;
}
import static org.mockito.Mockito.*
scenario quot;Leere Kontenliste anzeigenquot;, {
given quot;eine Bank ohne Kontenquot;, {
bank = mock(IBank)
stub(bank.getKonten()).toReturn([])
}
when quot;die Konten-Applikation gestartet wirdquot;, {
gui = new KontenApp(bank)
gui.setVisible(true)
}
then quot;dann ist das Konten-Fenster offen quot;
public class KontenApp extends JFrame {
and quot;ist die Liste der angezeigten Konten leerquot;
public KontenApp(IBank bank) {
}
}
}
import static org.mockito.Mockito.*
scenario quot;Leere Kontenliste anzeigenquot;, {
given quot;eine Bank ohne Kontenquot;, {
bank = mock(IBank)
stub(bank.getKonten()).toReturn([])
}
when quot;die Konten-Applikation gestartet wirdquot;, {
gui = new KontenApp(bank)
gui.setVisible(true)
}
then quot;dann ist das Konten-Fenster offen quot;, {
frame = new JFrameOperator(quot;Meine Kontenquot;)
}
and quot;ist die Liste der angezeigten Konten leerquot;
}
import static org.mockito.Mockito.*
scenario quot;Leere Kontenliste anzeigenquot;, {
given quot;eine Bank ohne Kontenquot;, {
bank = mock(IBank)
stub(bank.getKonten()).toReturn([])
}
when quot;die Konten-Applikation gestartet wirdquot;, {
gui = new KontenApp(bank)
gui.setVisible(true)
}
then quot;dann ist das Konten-Fenster offen quot;, {
frame = new JFrameOperator(quot;Meine Kontenquot;)
}
public quot;ist die Liste der angezeigten Konten leerquot;
and class KontenApp extends JFrame {
}
public KontenApp(IBank bank) {
super(quot;Meine Kontenquot;);
}
}
import static org.mockito.Mockito.*
scenario quot;Leere Kontenliste anzeigenquot;, {
given quot;eine Bank ohne Kontenquot;, {
bank = mock(IBank)
stub(bank.getKonten()).toReturn([])
}
when quot;die Konten-Applikation gestartet wirdquot;, {
gui = new KontenApp(bank)
gui.setVisible(true)
}
then quot;dann ist das Konten-Fenster offen quot;, {
frame = new JFrameOperator(quot;Meine Kontenquot;)
}
and quot;ist die Liste der angezeigten Konten leerquot;, {
table = new JTableOperator(frame);
table.model.rowCount.shouldBe 0
}
}
public class KontenApp extends JFrame {
private JTable kontenTable;
private final IBank bank;
import static org.mockito.Mockito.*
public KontenApp(IBank bank) {
super(quot;Meine Kontenquot;);
scenario quot;Leere Kontenliste anzeigenquot;, {
this.bank = bank;
given quot;eine Bank ohne Kontenquot;, {
createLayout();
bank = mock(IBank)}
stub(bank.getKonten()).toReturn([])
private void createLayout() {
} ...
createKontenTable();
when quot;die Konten-Applikation gestartet wirdquot;, {
fillKontenTable();
gui = new KontenApp(bank)
pack();
gui.setVisible(true)
}
} private void fillKontenTable() {
then quot;dann ist das Konten-Fenster offen quot;, {
((KontenTableModel) kontenTable.getModel()).
setKonten(bank.getKonten());
frame = new JFrameOperator(quot;Meine Kontenquot;)
}
} }
and quot;ist die Liste der angezeigten Konten leerquot;, {
table = new JTableOperator(frame);
table.model.rowCount.shouldBe 0
}
}
public class KontenApp extends JFrame {
private JTable kontenTable;
private final IBank bank;
import static org.mockito.Mockito.*
public KontenApp(IBank bank) {
super(quot;Meine Kontenquot;);
scenario quot;Leere Kontenliste anzeigenquot;, {
this.bank = bank;
given quot;eine Bank ohne Kontenquot;, {
createLayout();
bank = mock(IBank)}
stub(bank.getKonten()).toReturn([])
private void createLayout() {
} ...
createKontenTable();
when quot;die Konten-Applikation gestartet wirdquot;, {
fillKontenTable();
gui = new KontenApp(bank)
pack();
gui.setVisible(true)
}
} private void fillKontenTable() {
then quot;dann ist das Konten-Fenster offen quot;, {
((KontenTableModel) kontenTable.getModel()).
setKonten(bank.getKonten());
frame = new JFrameOperator(quot;Meine Kontenquot;)
}
} }
and quot;ist die Liste der angezeigten Konten leerquot;, {
table = new JTableOperator(frame);
table.model.rowCount.shouldBe 0
}
gui.dispose()
}
Dummies und Mocks
werden wichtiger
import static org.mockito.Mockito.*
scenario quot;Leere Kontenliste anzeigenquot;, {
given quot;eine Bank ohne Kontenquot;, {
bank = mock(IBank)
stub(bank.getKonten()).toReturn([])
}
...
}
scenario quot;Löschen eines Kontos aus Kontenlistequot;, {
given quot;ein offenes Konten-Fenster mit drei Kontenquot;, {...}
when quot;das erste Konto angewählt wirdquot;, {...}
and quot;der Löschen-Button gedrückt wirdquot;, {
deleteButton = new JButtonOperator(frame, quot;Lösche Kontoquot;)
deleteButton.push()
}
then quot;verschwindet das Konto aus der Listequot;, {
checkKontenliste(table.model, [[quot;in1quot;, 10], [quot;in2quot;, 20]])
}
and quot;wird an der Bank das Konto gelöschtquot;, {
???
}
}
import static org.easymock.EasyMock.*
scenario quot;Löschen eines Kontos aus Kontenlistequot;, {
given quot;ein offenes Konten-Fenster mit drei Kontenquot;, {...}
when quot;das erste Konto angewählt wirdquot;, {...}
and quot;der Löschen-Button gedrückt wirdquot;, {
expect(bank.loescheKonto(dreiKonten[0]))
deleteButton = new JButtonOperator(frame, quot;Lösche Kontoquot;)
deleteButton.push()
}
then quot;verschwindet das Konto aus der Listequot;, {
checkKontenliste(table.model, [[quot;in1quot;, 10], [quot;in2quot;, 20]])
}
and quot;wird an der Bank das Konto gelöschtquot;, {
verify(bank)
}
}
import static org.mockito.Mockito.*
scenario quot;Löschen eines Kontos aus Kontenlistequot;, {
given quot;ein offenes Konten-Fenster mit drei Kontenquot;, {...}
when quot;das erste Konto angewählt wirdquot;, {...}
and quot;der Löschen-Button gedrückt wirdquot;, {
deleteButton = new JButtonOperator(frame, quot;Lösche Kontoquot;)
deleteButton.push()
}
then quot;verschwindet das Konto aus der Listequot;, {
checkKontenliste(table.model, [[quot;in1quot;, 10], [quot;in2quot;, 20]])
}
and quot;wird an der Bank das Konto gelöschtquot;, {
verify(bank).loescheKonto(dreiKonten[0])
}
}
Ziele von Akzeptanztests
• Funktionale Tests aus Kundensicht
• Sprechen die Sprache des Kunden
• Konkrete Beispiele der Verwendung
Ziele von Akzeptanztests
• Funktionale Tests aus Kundensicht
• Sprechen die Sprache des Kunden
• Konkrete Beispiele der Verwendung
• Können vom Kunden geschrieben und
geändert werden
Ziele von Akzeptanztests
• Funktionale Tests aus Kundensicht
• Sprechen die Sprache des Kunden
• Konkrete Beispiele der Verwendung
• Können vom Kunden geschrieben und
geändert werden
• Testen (überwiegend) das System als
Ganzes
scenario Gefüllte Kontenliste
anzeigen
given eine Bank mit drei Konten
when die Konten-Applikation
gestartet wird
then werden im Konten-Fenster
drei Konten mit Inhaber und
Saldo angezeigt
scenario Löschen eines Kontos aus
Kontenliste
given ein offenes Konten-Fenster
mit drei Konten
when das erste Konto angewählt
wird
when der Löschen-Button gedrückt
wird
then verschwindet das Konto aus
der Liste
then wird an der Bank das Konto
gelöscht
Funktionale Tests aus Kundensicht
Sprechen die Sprache des Kunden
Konkrete Beispiele der Verwendung
Können vom Kunden geschrieben und
geändert werden
Testen (überwiegend) das System als
Ganzes
Funktionale Tests aus Kundensicht
Sprechen die Sprache des Kunden
Konkrete Beispiele der Verwendung
Können vom Kunden geschrieben und
geändert werden
Testen (überwiegend) das System als
Ganzes
Funktionale Tests aus Kundensicht
Sprechen die Sprache des Kunden
Konkrete Beispiele der Verwendung
Können vom Kunden geschrieben und
geändert werden
Testen (überwiegend) das System als
Ganzes
Funktionale Tests aus Kundensicht
Sprechen die Sprache des Kunden
Konkrete Beispiele der Verwendung
Können vom Kunden geschrieben und
geändert werden
Testen (überwiegend) das System als
Ganzes
Funktionale Tests aus Kundensicht
Sprechen die Sprache des Kunden
Konkrete Beispiele der Verwendung
Können vom Kunden geschrieben und
geändert werden
Testen (überwiegend) das System als
Ganzes
Funktionale Tests aus Kundensicht
Sprechen die Sprache des Kunden
Konkrete Beispiele der Verwendung
Können vom Kunden geschrieben und
geändert werden
Testen (überwiegend) das System als
Ganzes
BDD ist...
• „Richtiges TDD“ leicht(er) gemacht
• Veränderung der Sprache
• Anpassung der Tools
• Fokus auf Spezifikation und Verhalten
BDD ist...
• „Richtiges TDD“ leicht(er) gemacht
• Veränderung der Sprache
• Anpassung der Tools
• Fokus auf Spezifikation und Verhalten
• Vom Bekannten zum Unbekannten
• Dummies und Mocks werden wichtiger
BDD ist...
• „Richtiges TDD“ leicht(er) gemacht
• Veränderung der Sprache
• Anpassung der Tools
• Fokus auf Spezifikation und Verhalten
• Vom Bekannten zum Unbekannten
• Dummies und Mocks werden wichtiger
• Das Domänenmodell im Mittelpunkt